滚动视图内的两个列表视图的平滑滚动

时间:2016-06-24 18:35:21

标签: android listview android-recyclerview

通过产品设计,我需要在scrollview中有两个listview。我使用reyclerviews代替listviews。您可以想象,滚动体验非常滞后。通过为我的两个recyclerviews设置NestedScrollingEnabled(false),我能够解决滞后问题。

rv1.setNestedScrollingEnabled(false);
rv2.setNestedScrollingEnabled(false);

我遇到的冲突是NestedScrolling是API 21+的一个功能。早期API版本的等效代码是什么?

我尝试过以下操作,但列表项不可点击。滚动非常流畅。

rv1.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      return true;
   }
});

rv2.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      return true;
   }
});

我尝试调整代码以便我的项目可以点击,因此我将代码更新为以下内容,但是,现在平滑滚动已经消失,但我的项目是可点击的。

rv1.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      int action = event.getAction();
      switch (action) {
         case MotionEvent.ACTION_DOWN:
            // disallow scrollview to intercept touch events
            v.getParent().requestDisallowInterceptTouchEvent(false);
            break;
         case MotionEvent.ACTION_UP:
            // allow scrollview to intercept touch events
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;

      v.onTouchEvent(event);
      return true;
   }
});


rv2.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      int action = event.getAction();
      switch (action) {
         case MotionEvent.ACTION_DOWN:
            // disallow scrollview to intercept touch events
            v.getParent().requestDisallowInterceptTouchEvent(false);
            break;
         case MotionEvent.ACTION_UP:
            // allow scrollview to intercept touch events
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;

      v.onTouchEvent(event);
      return true;
   }
});

我认为它可能是我的xml结构的方式,父实际上是LinearLayout包装而不是scrollView,虽然这只是我的理论。我已经在下面发布了xml的结构。

<ScrollView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.v7.widget.CardView
            ....
            ....

            <android.support.v7.widget.RecyclerView
                android:id="@+id/rv1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@null"
                android:overScrollMode="never"
                android:scrollingCache="false"/>

            </android.support.v7.widget.CardView>
    </LinearLayout>
  </ScrollView>

如果有任何帮助,请提前感谢!

1 个答案:

答案 0 :(得分:0)

我能够解决这个问题。滚动视图中的列表视图如此缓慢且滞后的原因主要是由于在每个相应视图中启用了多个滚动。如果您可以消除列表视图或滚动视图的滚动,一切都会更顺畅(不要与最流畅的混淆。它没有优化)。所以这就是我所做的。

我添加了一个使用API​​ 21的嵌套滚动属性的条件,而在else条件下,我在CustomRecyclerView类中显式设置了滚动禁用。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // disable nested scrolling
        rvAirportNearest.setNestedScrollingEnabled(false);
        rvAirportServiced.setNestedScrollingEnabled(false);
    } else {
        // disable scrolling
        rvAirportNearest.setScrollingEnabled(false);
        rvAirportServiced.setScrollingEnabled(false);
    }

这是我的自定义回收站视图类

public class CustomScrollableRecyclerView extends RecyclerView {

    private boolean isScrollable = true; // by default recycler view is scrollable

    /**
     * Constructor
     * @param context
     */
    public CustomScrollableRecyclerView(Context context) {
        super(context);
    }

    /**
     * Constructor
     * @param context
     * @param attrs
     */
    public CustomScrollableRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Constructor
     * @param context
     * @param attrs
     * @param defStyle
     */
    public CustomScrollableRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public int computeVerticalScrollRange() {
        if (isScrollable()) {
            return super.computeVerticalScrollRange();
        }
        return 0;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        if(isScrollable()) {
            return super.onInterceptTouchEvent(e);
        }
        return false;
    }

    /**
     * Method is used to set scrolling enabled
     * @param enabled
     */
    public void setScrollingEnabled(boolean enabled) {
        isScrollable = enabled;
    }

    /**
     * Method is used to check if scrolling is enabled
     * @return true if scrolling is possible, otherwise false
     */
    public boolean isScrollable() {
        return isScrollable;
    }

}

希望这有助于其他人面对同样的问题。