直播軟體原始碼,自定義RecyclerView支援快速滾動

zhibo系統開發發表於2023-04-20

直播軟體原始碼,自定義RecyclerView支援快速滾動

問題描述:


RecyclerView自帶快速滾動無法控制捲軸的長度,也就是說隨著item的增多,捲軸的長度會越變越小。


解決問題:


透過自定義RecyclerView來實現捲軸的長度不會因為item的增多而發生長度變化。

package com.emsm.app.widget;
 
import android.view.MotionEvent;
 
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
 
import com.emsm.app.util.LogHelps;
 
/**
 * @Author chentao 0000668668
 * @Time 2023/2/10
 */
public class ScrollerEvent {
    private RecyclerView mRecyclerView;
 
    private float mInitialBarHeight;
    private float mLastPressedYAdjustedToInitial;
    private int mLastAppBarLayoutOffset;
 
    public void attachRecyclerView(RecyclerView recyclerView, CallBack call) {
        this.mRecyclerView = recyclerView;
        this.mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                LogHelps.i("");
            }
 
            @Override
            public void onScrolled(@NonNull RecyclerView parent, int dx, int dy) {
                super.onScrolled(parent, dx, dy);
                if (call == null) {
                    return;
                }
 
                // 捲軸拇指的垂直範圍
                float extent = parent.computeVerticalScrollExtent();
                //  可滾動的區域大小
                float range = parent.computeVerticalScrollRange();
                // 當前偏移量(當前滾動的距離)
                float offset = parent.computeVerticalScrollOffset();
                // 最大偏移量(最大可滾動的距離)
                float maxOffset = range - extent;
                // 可以滑動時,在繪製
                if (maxOffset > 0) {
                    // float offsetY = ratio * mMeasureHeight;
                    float ratio = offset / maxOffset;
                    LogHelps.i("dx:" + dx +
                            " dy:" + dy +
                            " extent:" + extent +
                            " range:" + range +
                            " offset:" + offset +
                            " maxOffset:" + maxOffset +
                            " ratio:" + ratio);
 
                    call.onScrolled(ratio);
                }
            }
        });
    }
 
    public boolean onTouchEvent(MotionEvent event, int viewHeight) {
        if (mRecyclerView == null || event == null) {
            return true;
        }
 
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            mRecyclerView.stopScroll();
 
            int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE;
            nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL;
 
            mRecyclerView.startNestedScroll(nestedScrollAxis);
 
            mInitialBarHeight = viewHeight;
            mLastPressedYAdjustedToInitial = event.getY() + 0;
        } else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
            float newHandlePressedY = event.getY() + 0;
            int barHeight = viewHeight;
            float newHandlePressedYAdjustedToInitial = newHandlePressedY + (mInitialBarHeight - barHeight);
            float deltaPressedYFromLastAdjustedToInitial = newHandlePressedYAdjustedToInitial - mLastPressedYAdjustedToInitial;
 
            int dY = (int) ((deltaPressedYFromLastAdjustedToInitial / mInitialBarHeight) * (mRecyclerView.computeVerticalScrollRange() + 0));
            updateRvScroll(dY + mLastAppBarLayoutOffset);
 
            mLastPressedYAdjustedToInitial = newHandlePressedYAdjustedToInitial;
        } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
            mLastPressedYAdjustedToInitial = -1;
            mRecyclerView.stopNestedScroll();
        }
        return true;
    }
 
    public void updateRvScroll(int dY) {
        if (mRecyclerView == null) {
            return;
        }
        try {
            mRecyclerView.scrollBy(0, dY);
        } catch (Exception t) {
            t.printStackTrace();
        }
    }
 
    interface CallBack {
        // 滾動的比例值 0-1
        void onScrolled(float ratio);
    }
 
    /**
     * 判斷是否可以滾動
     * @param recyclerView
     * @return
     */
    public static boolean isRecyclerScrollable(RecyclerView recyclerView) {
        if (recyclerView == null) {
            return false;
        }
 
        float range = recyclerView.computeVerticalScrollRange();
        float height = recyclerView.getHeight();
        // LogHelps.i("recyclerView的滾動範圍 " + range + " | RecyclerView的高度 " + height);
        // 滾動範圍大於RecyclerView的高度 說明是可以滾動的
        if (true) {
            return range > height;
        }
 
        boolean h = false;
        if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            RecyclerView.Adapter adapter = recyclerView.getAdapter();
            if (layoutManager == null || adapter == null) {
                h = false;
            } else {
                h = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
            }
        } else if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
            GridLayoutManager layoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
            RecyclerView.Adapter adapter = recyclerView.getAdapter();
            if (layoutManager == null || adapter == null) {
                h = false;
            } else {
                h = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
            }
        } else if (recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
            StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) recyclerView.getLayoutManager();
            RecyclerView.Adapter adapter = recyclerView.getAdapter();
            if (layoutManager == null || adapter == null) {
                h = false;
            } else {
                h = layoutManager.findLastCompletelyVisibleItemPositions(null)[(layoutManager.getSpanCount() - 1)] < adapter.getItemCount() - 1;
            }
        }
 
        return h;
    }
 
}


以上就是 直播軟體原始碼,自定義RecyclerView支援快速滾動,更多內容歡迎關注之後的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2947136/,如需轉載,請註明出處,否則將追究法律責任。

相關文章