美文网首页
Android的在ScrollView中嵌套RecycleVie

Android的在ScrollView中嵌套RecycleVie

作者: 主音King | 来源:发表于2018-11-29 14:42 被阅读5次

针对ScrollView监听事件
在Android的M(包含 api23)版本之后对外开放了监听
setOnScrollChangeListener

            scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
                @Override
                public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    Log.d(TAG, "onScrollChange-scrollX:" + scrollX + " scrollY:" + scrollY + " oldScrollX:" + oldScrollX + " oldScrollY:" + oldScrollY);
                }
            });

对于在api23之前的版本其实内部有监听不过没有开放(protected),只需要重写scrollView曝漏出即可

public class MyScrollView extends ScrollView {
    /**
     * 滑动回调监听
     */
    private MyScrollViewListener listener;

    /**
     * 曝漏出
     * @param listener
     */
    public void setListener(MyScrollViewListener listener) {
        this.listener = listener;
    }
    public MyScrollView(Context context) {
        this(context,null);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    @Override
    protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
        super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
        if (listener!=null){
            listener.onScrollChanged(this,scrollX,scrollY,oldScrollX,oldScrollY);
        }
    }

    /**
     * 对外开放滑动回调类
     */
    public interface MyScrollViewListener{
        void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
    }
}

其中回调参数scrollY:滑出ScrollView的距离outH
scrollView.getHeight(): scrollView可以看到的高度seeH
则在scrollView滑动过程中在监听中时时算出滑动的view距离底部的距离:
bottomH=滑动view总高度-(outH + seeH)
如果RecycleView嵌套在ScrollView中,则RecyclerView滑动距离底部距离
itemH * itemCount -(outH + seeH)
当然这个值一般在recyclerView.addOnScrollListener回调的onScrollStateChanged方法中处理,根据RecyclerView.SCROLL_STATE_IDLE == newState状态来计算。

scrollView.setListener(new MyScrollView.MyScrollViewListener() {
            @Override
            public void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                outH = scrollY;
            }
        });
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (RecyclerView.SCROLL_STATE_IDLE == newState) {
                    int totalH = itemCount * dip2px(50);
//                    int outH = scrollView.getScrollY();// 也可以这样获取outH
                    int seeH = scrollView.getHeight();
                    int bottomH = totalH - (seeH + outH);
                    Log.d(TAG, "onScrollStateChanged-停止滑动:" + newState + " 总高:" + totalH
                            + " 当前高:" + " item:" + dip2px(50) + " curTop:" + outH + " outH:" + outH + " seeH:" + seeH+" 距离底部:"+bottomH);
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                Log.d(TAG, "onScrolled-dx:" + dx + " dy:" + dy);
            }
        });
<ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="123dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </RelativeLayout>
    </ScrollView>

因为recyclerView高度为match_parent,recyclerView会把所有数据加载进去消耗性能。所以recyclerView是无法滑动的(因为已经显示完了,超出屏幕了只是用户看不到而已)
则可以根据scrollView去滑动.根据recyclerView指定对应的item颜色

        recyclerView.smoothScrollToPosition(position);//外层没有scrollView是可以根据position滑动的
        if (scrollView != null) {
            int count = position - 2;
            if (count <= 0) {
                scrollView.smoothScrollTo(0, 0);
            } else {
                scrollView.smoothScrollTo(0, count * CommonUtils.dip2px(80));
            }

相关文章

网友评论

      本文标题:Android的在ScrollView中嵌套RecycleVie

      本文链接:https://www.haomeiwen.com/subject/azcfcqtx.html