关于ScrollView嵌套RecyclerView高度,焦点,滑动,setOnScrollChangeListener问题的解决

来源:互联网 发布:c 逆波兰算法 编辑:程序博客网 时间:2024/06/07 22:41

1 RecyclerView高度设置不起作用

解决方法:
a)重写tLayoutManager 太麻烦,有兴趣可以查查
b)代码里给RecyclerView设置一个高度

 ViewGroup.LayoutParams params = rvMused.getLayoutParams();        params.height = 1080*2;//条目的高度*显示多少条 这里注意不要把条目的布局高度设为match_parent 可以是wrap_cotent或者直接写固定高度        recyclerView.setLayoutParams(params);

注:自定义的条目布局 R.layout.item 的高度也可以代码获得

int height=  LayoutInflater.from(activity).inflate(R.layout.item, new LinearLayout(getContext()), false).getLayoutParams().height;

c)神奇的相对布局

有上面问题一般是因为你用了

<ScrollView>    <LinearLayout>        <!--其他布局-->        <RecyclerView        android:layout_height="YOURHHEIGHTVALUE"/>    <LinearLayout/></ScrollView>

上述布局就会有嵌套高度设置”YOURHHEIGHTVALUE”不起作用的情况,然而只要简单的换成相对布局,一切就好了

<ScrollView>    <RelativeLayout>        <!--其他布局-->        <RecyclerView         android:layout_height="YOURHHEIGHTVALUE"/>    <RelativeLayout/></ScrollView>

这样就没问题了 ,是不是很神奇!!!

2 RecyclerView抢占焦点是的页面显示位置是RecyclerView的第一条

解决方法:
代码设置ScorllView滑动到最上面

 scorllView.smoothScrollTo(0, 0);

3 让RecyclerView不滑动

代码里添加

recyclerView.setNestedScrollingEnabled(false);

4 ScrollView的setOnScrollChangeListener()方法 requires api23 的问题

a)重写ScrollView,

对比api19和最新的 onScrollChanged源码

    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        if (AccessibilityManager.getInstance(mContext).isEnabled()) {            postSendViewScrolledAccessibilityEventCallback();        }        mBackgroundSizeChanged = true;        final AttachInfo ai = mAttachInfo;        if (ai != null) {            ai.mViewScrollChanged = true;        }    }
   protected void onScrollChanged(int l, int t, int oldl, int oldt) {        notifySubtreeAccessibilityStateChangedIfNeeded();        if (AccessibilityManager.getInstance(mContext).isEnabled()) {            postSendViewScrolledAccessibilityEventCallback();        }        mBackgroundSizeChanged = true;        if (mForegroundInfo != null) {            mForegroundInfo.mBoundsChanged = true;        }        final AttachInfo ai = mAttachInfo;        if (ai != null) {            ai.mViewScrollChanged = true;        }//以下是新增的代码        if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {            mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);        }    }

可以看出原理是父控件view里一直都有 (api1开始)protected void onScrollChanged这个方法,而api23以前没有提供 public interface OnScrollChangeListener 这个接口以及它的set方法–setOnScrollChangeListener,使得不能从外部直接获得(this, l, t, oldl, oldt)这四个参数并进行响应操作,所以我们继承ScrollView同时暴漏出他的父控件view的onScrollChanged方法就可以了

b)利用 sv.setOnTouchListener();方法,但是无法监听惯性

    @Override    public boolean onTouch(View v, MotionEvent event) {//利用v和event的getScrollY(),getX,getY,getAction等方法一样可以达到setOnTouchListener的目的//http://blog.csdn.net/sinat_29912455/article/details/51073537这个网址有介绍各个方法的区别        return false;    }

加强版的b方法: 获得 ScrollView 惯性滑动后的位置
缺点:MotionEvent.ACTION_UP后后的getScrollY的时间不好确定
参考 http://lmx227.iteye.com/blog/1007533

 @Override    public boolean onTouch(View v, MotionEvent event) {        int action = event.getAction();        switch (action) {            case MotionEvent.ACTION_MOVE:                scrollY = sv.getScrollY();                changeTextSwicher(scrollY);              break;            case MotionEvent.ACTION_UP:                scrollY = sv.getScrollY();                changeTextSwicher(scrollY);                detectScrollY();                break;        }        return false;    }    public void detectScrollY() {        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                int tempScrollY = sv.getScrollY();                if (tempScrollY != scrollY) {                    scrollY = tempScrollY;                    changeTextSwicher(tempScrollY);                } else {                    Log.e("TAG", "scrollX = " + scrollY);                    return;                }            }        }, 200);    }    public void changeTextSwicher(int scroll) {    }

c ) 利用scrollView.getViewTreeObserver().addOnScrollChangedListener
但是惯性问题依然没解决

scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {      @Override      public void onScrollChanged() {      }  }); 
阅读全文
0 0