欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、ItemDecoration

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

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

RecyclerView.addItemDecoration()

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

public abstract static class ItemDecoration

public class DividerItemDecoration extends RecyclerView.ItemDecoration

里面有3個(gè)方法:

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

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

繪制效果

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

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

繪制效果

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

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

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

1、實(shí)現(xiàn)一個(gè)簡(jiǎn)單的RecyclerView

下面這個(gè)RecyclerView的實(shí)現(xiàn)細(xì)節(jié)略。

2、通過(guò)ItemDecoration畫分割線

自定義ItemDecoration。

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

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

RecyclerView.addItemDecoration(new fruitDecoration(this))

在getItemOffsets畫分割線,當(dāng)是組名時(shí),預(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);
            }
        }

實(shí)現(xiàn)效果

3、畫出每個(gè)分組的組名

當(dāng)是組名時(shí),在較大分割線哪里畫出組名。在onDraw()方法里實(shí)現(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的個(gè)數(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++) {
                //獲取對(duì)應(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);
                }
            }
       }
    }

實(shí)現(xiàn)效果

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

因?yàn)閛nDrawOver方法是在itemView畫了之后才畫,所以組名的吸頂是寫在onDrawOver方法里。需要注意的時(shí),當(dāng)我們的第二個(gè)組名到頂部的時(shí)候,要把當(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)的第一個(gè)item的position
            int position =((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
            // 獲取第一個(gè)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ù)诙€(gè)是頭部時(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);
            }
        }
    }

實(shí)現(xiàn)效果

完整demo

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

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

相關(guān)文章

  • Android實(shí)現(xiàn)APP在線下載更新

    Android實(shí)現(xiàn)APP在線下載更新

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)APP在線下載更新的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Kotlin注解實(shí)現(xiàn)Parcelable序列化流程詳解

    Kotlin注解實(shí)現(xiàn)Parcelable序列化流程詳解

    有時(shí)我們會(huì)在界面跳轉(zhuǎn)的過(guò)程中,做對(duì)象傳值,這時(shí)就需要對(duì)該對(duì)象做序列化處理了。Android中對(duì)對(duì)象的序列化處理有兩種方式,這篇文章主要介紹了Kotlin注解實(shí)現(xiàn)Parcelable序列化
    2022-12-12
  • Android實(shí)現(xiàn)手勢(shì)滑動(dòng)多點(diǎn)觸摸縮放平移圖片效果(二)

    Android實(shí)現(xiàn)手勢(shì)滑動(dòng)多點(diǎn)觸摸縮放平移圖片效果(二)

    這篇文章主要介紹了Android實(shí)現(xiàn)手勢(shì)滑動(dòng)多點(diǎn)觸摸縮放平移圖片效果,實(shí)現(xiàn)圖片支持多點(diǎn)觸控,自由的進(jìn)行縮放、平移的注意事項(xiàng),感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android App開發(fā)中ViewPager組件的入門使用教程

    Android App開發(fā)中ViewPager組件的入門使用教程

    這篇文章主要介紹了Android App開發(fā)中ViewPager組件的入門使用教程,ViewPager主要用來(lái)實(shí)現(xiàn)通過(guò)滑動(dòng)來(lái)切換頁(yè)面的效果,需要的朋友可以參考下
    2016-03-03
  • Android開發(fā)-之五大布局詳解

    Android開發(fā)-之五大布局詳解

    這篇文章主要介紹了Android開發(fā)-之五大布局詳解,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • Android實(shí)現(xiàn)刮刮樂(lè)示例分析

    Android實(shí)現(xiàn)刮刮樂(lè)示例分析

    本文實(shí)現(xiàn)了Android刮刮樂(lè)示例分析,刮獎(jiǎng)在生活中常常見到,網(wǎng)上現(xiàn)在也有各種各樣的抽獎(jiǎng)活動(dòng),下面我們就要實(shí)現(xiàn)一個(gè)刮刮樂(lè)程序。
    2016-10-10
  • 詳解Flutter網(wǎng)絡(luò)圖片本地緩存的實(shí)現(xiàn)

    詳解Flutter網(wǎng)絡(luò)圖片本地緩存的實(shí)現(xiàn)

    這篇文章主要為大家介紹了詳解Flutter網(wǎng)絡(luò)圖片本地緩存的實(shí)現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Android使用Notification在狀態(tài)欄上顯示通知

    Android使用Notification在狀態(tài)欄上顯示通知

    這篇文章主要為大家詳細(xì)介紹了Android使用Notification在狀態(tài)欄上顯示通知,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 阿里路由框架ARouter 源碼解析之Compiler

    阿里路由框架ARouter 源碼解析之Compiler

    這篇文章主要介紹了阿里路由框架ARouter 源碼解析之Compiler,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Android自定義View實(shí)現(xiàn)標(biāo)簽流效果

    Android自定義View實(shí)現(xiàn)標(biāo)簽流效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)標(biāo)簽流效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評(píng)論