亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android RecyclerView實現(xiàn)吸頂動態(tài)效果流程分析

 更新時間:2022年12月22日 09:53:07   作者:別偷我的豬_09  
RecyclerView是Android一個更強大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法

一、ItemDecoration

ItemDecoration 允許應(yīng)用給具體的 View 添加具體的圖畫或者 layout 的偏移,對于繪制 View之間的分割線,視覺分組邊界等等是非常有用的。

當(dāng)我們調(diào)用 addItemDecoration() 方法添加 decoration 的時候,RecyclerView 就會調(diào)用該類的 onDraw 方法去繪制分割線,也就是說:分割線是繪制出來的。

RecyclerView.addItemDecoration()

RecyclerView.ItemDecoration,該類為抽象類,官方目前只提供了一個實現(xiàn)類 DividerItemDecoration。

public abstract static class ItemDecoration

public class DividerItemDecoration extends RecyclerView.ItemDecoration

里面有3個方法:

onDraw(): 在提供給RecyclerView的畫布上繪制任何適當(dāng)?shù)难b飾。通過此方法繪制的任何內(nèi)容都將在繪制項目視圖之前被繪制,因此將出現(xiàn)在視圖的下方。

public void onDraw(Canvas c, RecyclerView parent, State state) {
            onDraw(c, parent);
        }

繪制效果

onDrawOver():在提供給RecyclerView的畫布上繪制任何適當(dāng)?shù)难b飾。通過這種方法繪制的任何內(nèi)容都將在項目視圖被繪制之后被繪制,因此將出現(xiàn)在視圖上方。

public void onDrawOver(Canvas c, RecyclerView parent, State state) {
            onDrawOver(c, parent);
        }

繪制效果

getItemOffsets():檢索給定項的任何偏移量。outRect的每個字段指定項目視圖應(yīng)該插入的像素數(shù),類似于padding或margin。默認實現(xiàn)將outRect的界限設(shè)置為0,并返回。

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
            getItemOffsets(outRect, ((LayoutParams)view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }

二、實現(xiàn)RecyclerView吸頂效果

1、實現(xiàn)一個簡單的RecyclerView

下面這個RecyclerView的實現(xiàn)細節(jié)略。

2、通過ItemDecoration畫分割線

自定義ItemDecoration。

創(chuàng)建 fruitDecotion 類 繼承 ItemDecoration,并實現(xiàn)onDraw、onDrawover、getItemOffsets三個方法。

RecyclerView調(diào)用自定義的fruitDecoration

RecyclerView.addItemDecoration(new fruitDecoration(this))

在getItemOffsets畫分割線,當(dāng)是組名時,預(yù)留更大的空間(即分割線的height比普通分割線大)。

@Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (parent.getAdapter() instanceof fruitAdapter){
            // parent.getAdapter()獲取到當(dāng)前RecyclerView的Adapter
            fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
            // 獲取當(dāng)前view的位置
            int position = parent.getChildLayoutPosition(view);
            if (adapter.isGroupHeader(position)) {
                // 如果是頭部,則預(yù)留更大的地方
                outRect.set(0, groupHeaderHeight, 0, 0);
            }else {
                outRect.set(0, 4, 0, 0);
            }
        }

實現(xiàn)效果

3、畫出每個分組的組名

當(dāng)是組名時,在較大分割線哪里畫出組名。在onDraw()方法里實現(xiàn)

@Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (parent.getAdapter() instanceof fruitAdapter) {
            fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
            //當(dāng)前屏幕中item的個數(shù)
            int count = parent.getChildCount();
            // 獲取當(dāng)前RecyclerView距離屏幕左邊的padding
            int left = parent.getPaddingLeft();
            // right == RecyclerView的寬度 - RecyclerView的右padding
            int right = parent.getWidth() - parent.getPaddingRight();
            for (int i = 0; i < count; i++) {
                //獲取對應(yīng) i 的 view
                View view = parent.getChildAt(i);
                // 獲取 i 的 view 的布局位置
                int position = parent.getChildLayoutPosition(view);
                // 判斷是否是頭部
                boolean isGroupHeader = adapter.isGroupHeader(position);
                // i 的 view 是頭部并且 當(dāng)前view的top位置距離屏幕的頂部還有距離
                if(isGroupHeader && view.getTop() - groupHeaderHeight - parent.getPaddingTop() >=0) {
                    c.drawRect(left, view.getTop() - groupHeaderHeight, right, view.getTop(), headPaint);
                    String groupName = adapter.getGroupName(position);
                    textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                    c.drawText(groupName, left + 20, view.getTop() - groupHeaderHeight / 2f + textRect.height() / 2f, textPaint);
                }else if(view.getTop() - groupHeaderHeight - parent.getPaddingTop() >=0){
                    //分割線
                    c.drawRect(left, view.getTop() - 4, right, view.getTop(), headPaint);
                }
            }
       }
    }

實現(xiàn)效果

4、實現(xiàn)吸頂效果

因為onDrawOver方法是在itemView畫了之后才畫,所以組名的吸頂是寫在onDrawOver方法里。需要注意的時,當(dāng)我們的第二個組名到頂部的時候,要把當(dāng)前頂部的組名給替換掉。

 @Override
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        if (parent.getAdapter() instanceof fruitAdapter) {
            fruitAdapter adapter = (fruitAdapter) parent.getAdapter();
            //TODO 返回可見區(qū)域內(nèi)的第一個item的position
            int position =((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
            // 獲取第一個item的view
            View itemView = parent.findViewHolderForAdapterPosition(position).itemView;
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            int top = parent.getPaddingTop();
            //TODO 當(dāng)?shù)诙€是頭部時,
            boolean isGroupHeader = adapter.isGroupHeader(position + 1);
            if (isGroupHeader) {
                int bottom = Math.min(groupHeaderHeight, itemView.getBottom() - parent.getPaddingTop());
                c.drawRect(left, top, right, top + bottom, headPaint);
                String groupName = adapter.getGroupName(position);
                textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                c.drawText(groupName, left + 20, top + bottom - groupHeaderHeight / 2f
                        + textRect.height() / 2f, textPaint);
            }else { // 如果不是頭部, 即普通的itemView,則當(dāng)前的頭部一直固定在頂部
                c.drawRect(left, top, right, top + groupHeaderHeight, headPaint);;
                String groupName = adapter.getGroupName(position);
                textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                c.drawText(groupName, left + 20, top + groupHeaderHeight / 2f
                        + textRect.height() / 2f, textPaint);
            }
        }
    }

實現(xiàn)效果

完整demo

鏈接: https://pan.baidu.com/s/11I8dtWts3BZjYMgNvzanTw?pwd=bvx9

到此這篇關(guān)于Android RecyclerView實現(xiàn)吸頂動態(tài)效果流程分析的文章就介紹到這了,更多相關(guān)Android RecyclerView內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論