最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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 添加具體的圖畫(huà)或者 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的畫(huà)布上繪制任何適當(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的畫(huà)布上繪制任何適當(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畫(huà)分割線

自定義ItemDecoration。

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

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

RecyclerView.addItemDecoration(new fruitDecoration(this))

在getItemOffsets畫(huà)分割線,當(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、畫(huà)出每個(gè)分組的組名

當(dāng)是組名時(shí),在較大分割線哪里畫(huà)出組名。在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畫(huà)了之后才畫(huà),所以組名的吸頂是寫(xiě)在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 返回可見(jiàn)區(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 Studio設(shè)置主題與字體大小圖文教程

    Android Studio設(shè)置主題與字體大小圖文教程

    這篇文章通過(guò)圖文詳細(xì)的給大家介紹了Android Studio中如何設(shè)置主題與字體大小,文章介紹的非常詳細(xì),相信對(duì)大家學(xué)習(xí)使用Android Studio具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起看看吧。
    2016-10-10
  • Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    本文主要介紹了Android中Fragment的加載方式與數(shù)據(jù)通信的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Android?WebView預(yù)渲染介紹

    Android?WebView預(yù)渲染介紹

    這篇文章主要介紹了Android?WebView預(yù)渲染介紹,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 從源碼剖析Android中的Intent組件

    從源碼剖析Android中的Intent組件

    這篇文章主要介紹了Android中的Intent組件,作者從源碼剖析了Intent如何實(shí)現(xiàn)組件間的切換,需要的朋友可以參考下
    2016-03-03
  • Android實(shí)現(xiàn)歡迎滑動(dòng)頁(yè)面

    Android實(shí)現(xiàn)歡迎滑動(dòng)頁(yè)面

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)歡迎滑動(dòng)頁(yè)面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android編程判斷橫屏、豎屏及設(shè)置橫豎屏的方法

    Android編程判斷橫屏、豎屏及設(shè)置橫豎屏的方法

    這篇文章主要介紹了Android編程判斷橫屏、豎屏及設(shè)置橫豎屏的方法,結(jié)合實(shí)例形式分析了Android針對(duì)橫豎屏的判斷、計(jì)算、設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • android系統(tǒng)按鍵音framework流程源碼詳細(xì)解析

    android系統(tǒng)按鍵音framework流程源碼詳細(xì)解析

    這篇文章主要為大家詳細(xì)介紹了android系統(tǒng)按鍵音framework流程源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Android利用RecyclerView實(shí)現(xiàn)全選、置頂和拖拽功能示例

    Android利用RecyclerView實(shí)現(xiàn)全選、置頂和拖拽功能示例

    列表控件可以說(shuō)是我們絕大部分App中都會(huì)使用的,為了提升交互樂(lè)趣,我們經(jīng)常需要在列表中加入置頂、拖拽等操作,下面這篇文章主要介紹了Android利用RecyclerView如何實(shí)現(xiàn)全選、置頂和拖拽功能的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-04-04
  • Android串口操作方法實(shí)例

    Android串口操作方法實(shí)例

    這篇文章主要介紹了Android串口操作方法實(shí)例,本文共分5個(gè)步驟講解了Android串口操作方法,并給出代碼實(shí)例,需要的朋友可以參考下
    2015-04-04
  • Android系統(tǒng)設(shè)置中的清除數(shù)據(jù)會(huì)清除哪些數(shù)據(jù)?

    Android系統(tǒng)設(shè)置中的清除數(shù)據(jù)會(huì)清除哪些數(shù)據(jù)?

    這篇文章主要介紹了Android系統(tǒng)設(shè)置中的清除數(shù)據(jù)會(huì)清除哪些數(shù)據(jù)?本文對(duì)比了清除前和清除后的數(shù)據(jù)情況,從而得出到底清除了哪些數(shù)據(jù),需要的朋友可以參考下
    2015-01-01

最新評(píng)論

和田县| 射洪县| 卢氏县| 古交市| 鹤庆县| 响水县| 乌拉特中旗| 凤山市| 丰台区| 哈尔滨市| 浦北县| 屯留县| 朔州市| 库车县| 长治县| 旬邑县| 梧州市| 张家界市| 巢湖市| 响水县| 稷山县| 大庆市| 政和县| 富蕴县| 临湘市| 商都县| 松桃| 永川市| 大宁县| 华坪县| 石渠县| 丽水市| 惠来县| 九台市| 镇康县| 安福县| 朝阳市| 泰安市| 绥芬河市| 张家界市| 饶阳县|