使用scrollview必須知道的坑

1、問(wèn)題:Cast from null to OnScrollChangeListener requires API level 23 (current min is 16)監(jiān)聽

原因:scrollview的滑動(dòng),OnScrollChangeListener 在API23以后才有
解決:自定義監(jiān)聽接口

public class MyScrollView extends ScrollView {

    private OnScrollListener listener;

    public void setOnScrollListener(OnScrollListener listener) {
        this.listener = listener;
    }

    public MyScrollView(Context context) {
        super(context);
    }

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

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

    //設(shè)置接口
    public interface OnScrollListener {
        void onScroll(int scrollY);
    }

    /**
     * 重寫原生onScrollChanged方法,將參數(shù)傳遞給接口,由接口傳遞出去
     */
    @Override
    public void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (listener != null) {
            //垂直滑動(dòng)的距離
            listener.onScroll(t);
        }
    }
}

2、scrollview嵌套viewpage時(shí)

問(wèn)題
(1):頁(yè)面空白
(2):每個(gè)viewpage中的fragment高度一樣,導(dǎo)致頁(yè)面內(nèi)容短的fragment底部有大片空白區(qū)域
(3):viewpage中的fragment中如果包含自帶滾動(dòng)的控制,如webview,recycleview等,在滑動(dòng)切換viewpage時(shí),會(huì)出現(xiàn)卡頓。
解決:自定義viewpage,
(1)重寫onMeasure()方法計(jì)算viewpage高度,
(2)在生成fragment頁(yè)面時(shí)將view和position保存起來(lái),定義resetHeight()方法,viewpage切換時(shí)改變viewpage高度。
(3)自帶卡頓的這邊分控件會(huì)獲得焦點(diǎn),消耗touch事件,所以解決方法就是在viewpage中攔截touch事件。兩處方法重寫onTouchEvent(),onInterceptTouchEvent()。

public class CustomViewPager extends ViewPager {
    private int current;
    private int height = 0;
    /**
     * 保存position與對(duì)于的View
     */
    private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();

    private boolean scrollble = true;
    private OnTouchListener mOnTouchListener;

    public interface OnTouchListener {
        void onTouch(int state);
    }

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mChildrenViews.size() > current) {
            View child = mChildrenViews.get(current);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            height = child.getMeasuredHeight();
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void resetHeight(int current) {
        this.current = current;
        if (mChildrenViews.size() > current) {

            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
            if (layoutParams == null) {
                layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
            } else {
                layoutParams.height = height;
            }
            setLayoutParams(layoutParams);
        }
    }

    /**
     * 保存position與對(duì)于的View
     */
    public void setObjectForPosition(View view, int position) {
        mChildrenViews.put(position, view);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (!scrollble) {
            //返回true表示,表示消耗此次touch事件
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (!scrollble) {
            //返回true表示,表示消耗此次touch事件
            return true;
        }
        return super.onTouchEvent(ev);
    }


    public boolean isScrollble() {
        return scrollble;
    }

    public void setScrollble(boolean scrollble) {
        this.scrollble = scrollble;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mOnTouchListener != null) {
            mOnTouchListener.onTouch(ev.getAction());
        }
        return super.dispatchTouchEvent(ev);
    }

    public void setmOnTouchListener(OnTouchListener mOnTouchListener) {
        this.mOnTouchListener = mOnTouchListener;
    }

}

3、scrollview滑動(dòng)定位,當(dāng)scrollview處于滑動(dòng)狀態(tài)時(shí),這時(shí)通過(guò)點(diǎn)擊定位到scrollview的某一處會(huì)失效。

解決:同時(shí)使用兩個(gè)scrollview的滑動(dòng)方法 scrollTo() 和smoothScrollTo()。
smoothScrollTo()類似scroolTo(),但是滑動(dòng)的時(shí)候是平緩的,而不是立即滾動(dòng)到某處。
smoothScrollTo()方法可以打斷滑動(dòng)動(dòng)畫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容