NestedScrollView's smoothScrollTo() behaves weird

后端 未结 4 1218
半阙折子戏
半阙折子戏 2020-12-04 03:09

What I am trying to achieve is to scroll to scroll_position_1 when tab1 (and so on) is clicked like this. I don\'t understand what\'s happening at

相关标签:
4条回答
  • 2020-12-04 03:56

    You can use a ListView instead of a ConstraintLayout and add the text views to the list. Then, you can simply call listView.smoothScrollToPosition(index) instead of worrying about the x and y coordinates.

    1) Edit your layout as shown below.

    2) Add items to your ListView via code.

    3) Upon tab click, call listView.smoothScrollToPosition(index_of_text_view) and your list view scrolls to that position.

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
          <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
    
              <android.support.design.widget.TabLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
    
                  <android.support.design.widget.TabItem
                      android:layout_height="wrap_content"
                      android:layout_width="wrap_content"/>
    
                  <android.support.design.widget.TabItem
                      android:layout_height="wrap_content"
                      android:layout_width="wrap_content"/>
              </android.support.design.widget.TabLayout>
    
              <ListView
               android:id="@+id/list_view"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
           </LinearLayout
    </android.support.v4.widget.NestedScrollView>
    
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|snap">
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="180dp"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"/>
    
            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    

    0 讨论(0)
  • 2020-12-04 03:57

    Looks like there is a bug when programmatically scrolling NestedScrollView within CoordinatorLayout. This solved my problem:

    private void scrollToView(final View view) {
        mScroller.scrollBy(0, 1);
        mScroller.smoothScrollTo(0, view.getTop());
    }
    

    or for better control:

    private void scrollToView(final View view) {
        mScroller.scrollBy(0, 1);
        ObjectAnimator.ofInt(mScroller, "scrollY",  view.getTop()).setDuration(700).start();
    }
    
    0 讨论(0)
  • 2020-12-04 03:59

    You can try this:

    nestedScrollView.fling(0);
    nestedScrollView.smoothScrollTo(0, 0);
    
    0 讨论(0)
  • 2020-12-04 04:00

    When tab is clicked, just get the desired view's y position relative to the root view and scroll to that position.

    public class MainActivity extends AppCompatActivity {
    
      private NestedScrollView nestedScrollView;
      private CoordinatorLayout coordinatorLayout;
      TextView textView;
    
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        nestedScrollView = findViewById(R.id.nsv);
        coordinatorLayout = findViewById(R.id.cl);
        textView = findViewById(R.id.scroll_position_1);
    
        TabLayout tabLayout = findViewById(R.id.tl);
        tabLayout.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
            if(tab.getPosition() == 1/*position of your desired tab*/){
              scrollToView(textView);
            }
          }
    
          @Override
          public void onTabUnselected(TabLayout.Tab tab) {
    
          }
    
          @Override
          public void onTabReselected(TabLayout.Tab tab) {
    
          }
        });
    
      }
    
      /*
       * Used to scroll to the given view.
       *
       * @param view View to which we need to scroll.
       */
      private void scrollToView(View view) {
        // Get deepChild Offset
        int position = getRelativeTop(view);
        final int finalPosition = position;
        nestedScrollView.fling(0);
        nestedScrollView.smoothScrollTo(0, finalPosition);
      }
    
      private int getRelativeTop(View myView) {
        Rect offsetViewBounds = new Rect();
    //returns the visible bounds
        myView.getDrawingRect(offsetViewBounds);
    // calculates the relative coordinates to the parent
        coordinatorLayout.offsetDescendantRectToMyCoords(myView, offsetViewBounds);
    
        int relativeTop = offsetViewBounds.top;
        int relativeLeft = offsetViewBounds.left;
        return relativeTop;
      }
    
    }
    
    0 讨论(0)
提交回复
热议问题