RecyclerView自定義分割線
前言
RecyclerView已經(jīng)推出很久了,由于其高度的可定制性現(xiàn)在被廣泛應(yīng)用,我們常用的功能,如:?jiǎn)螚l目更新,LayoutManager實(shí)現(xiàn)各種炫酷的排列效果,定義個(gè)性分割線等
今天學(xué)習(xí)如何定制一個(gè)自己的分割線,讓你的列表看起來更好看
內(nèi)容部分
首先:常規(guī)的用法三步走設(shè)置布局方式,設(shè)置分割線,設(shè)置adapter。
本身系統(tǒng)是自帶了一個(gè)默認(rèn)的分割線類DividerItemDecoration可以實(shí)現(xiàn)和ListView一樣的效果。但是我們可能有其他的需求,如我們希望分割線有不同的顏色,這時(shí)我們可以通過DividerItemDecoration的setDrawable(Drawable drawable)方法設(shè)置一個(gè)Drawable進(jìn)入,如下:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); Drawable drawable = getResources().getDrawable(R.drawable.mycoler); dividerItemDecoration.setDrawable(drawable); recyclerView.addItemDecoration(dividerItemDecoration);
通過編寫不同的shape可以設(shè)置成不同的顏色的線。如圖:
特殊情況問題記錄
當(dāng)我在繪制橫向滾動(dòng)的RecyclerView的分割線的時(shí)候,出了一個(gè)小問題,因?yàn)槭褂胹hape畫的線,獲取Drawable的寬度一直為1px導(dǎo)致,無法顯示分割線,如果你傳入的是一個(gè)圖片就沒問題,我還沒找到原因。
描述:RecyclerView高度為100dp,item的高度為50dp,當(dāng)繪制出豎直方向分割線的時(shí)候,item部分分割線未能顯示,經(jīng)過排查發(fā)現(xiàn),分割線是繪制在RecyclerView的view上,item作為子view存在于RecyclerView的容器中,所以導(dǎo)致分割線繪制的一部分被遮擋,此處我使用系統(tǒng)提供的DividerItemDecoration也是效果一致的。如下圖:
所繪制的分割線上繪制在RecyclerView的布局上的,這也就解釋了,為什么繪制完分割線需要調(diào)用getItemOffsets()方法進(jìn)行位置重新排列了
如何解決這個(gè)情況呢?(其實(shí)就是自己根據(jù)出傳入的Drawable寬度處理)
1.給item設(shè)置一個(gè)padding值就可以了,這樣就可以把分割線顯示出來了。
2.通過getItemOffsets()方法設(shè)置偏移量,讓item順位后移,顯示出來分割線即可。
處理后的圖片如下:
不過這個(gè)問題我會(huì)在嘗試,找出為什么拿到的寬度數(shù)值不正確,如有知道的大佬,望告知,謝謝
定制過程分析
步驟一
初始化一些參數(shù)內(nèi)容,如偏移量,默認(rèn)的分割線等
public MyItemDecoration(Context context, int orientation, int inset, Drawable drawable) { if (orientation != VERTICAL && orientation != HORIZONTAL) { throw new IllegalArgumentException("請(qǐng)輸入正確的參數(shù)!"); } this.inset = inset; mOrientation = orientation; mDivider = drawable; if (drawable == null) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); } }
步驟二
繪制部分,通過標(biāo)識(shí)位來區(qū)分是垂直方向還是水平方向
@Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { if (parent.getLayoutManager() != null && this.mDivider != null) { if (this.mOrientation == VERTICAL) { this.drawVertical(c, parent); } else { this.drawHorizontal(c, parent); } } }
步驟三
繪制垂直或水平的分割線,這里主要是設(shè)置Drawable在RecyclerView中的位置。
private void drawHorizontal(Canvas canvas, RecyclerView parent) { int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { View childAt = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) childAt.getLayoutParams(); int left = childAt.getRight() + layoutParams.rightMargin; int right = mDivider.getIntrinsicWidth() + left; mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } } private void drawVertical(Canvas canvas, RecyclerView parent) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + layoutParams.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); if (inset > 0) { mDivider.setBounds(left + inset, top, right - inset, bottom); } else { mDivider.setBounds(left, top, right, bottom); } mDivider.draw(canvas); } }
步驟四
因?yàn)槲覀優(yōu)镽ecyclerView添加了分割線,所以整體位置要做調(diào)整。主要調(diào)整的部分就是,在條目中間添加一個(gè)分割線,需要對(duì)原來的所有條目后移動(dòng)一個(gè)分割線的寬度(高度)。
@Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { if (this.mDivider == null) { outRect.set(0, 0, 0, 0); } else { if (this.mOrientation == VERTICAL) { outRect.set(0, 0, 0, this.mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, this.mDivider.getIntrinsicWidth(), 0); } } }
以上就是基本的步驟的,其實(shí)就是參考系統(tǒng)提供的DividerItemDecoration來寫就行。其實(shí)系統(tǒng)的代碼,是最好的實(shí)例,所以多讀源碼對(duì)能力的提升很有幫助。
另外一種實(shí)現(xiàn)分割線的方式
其實(shí)這種方式很簡(jiǎn)單,就是將分割線放到item布局中。感覺也是不錯(cuò)的方案,畢竟在做條目布局的時(shí)候就把這個(gè)分割線完成了。
finish以上完畢,有問題謝謝指出。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)RecyclerView添加分割線的簡(jiǎn)便方法
- Android RecyclerView實(shí)現(xiàn)水平、垂直方向分割線
- Android 給RecyclerView添加分割線的具體步驟(分享)
- RecyclerView底部分割線去除的方法
- android中RecyclerView自定義分割線實(shí)現(xiàn)
- Android RecyclerView網(wǎng)格布局(支持多種分割線)詳解(2)
- Android中RecyclerView上拉下拉,分割線,多條目的實(shí)例代碼
- 萬能RecyclerView分割線
- RecyclerView消除底部分割線的方法
- RecyclerView的萬能分割線
相關(guān)文章
Android 實(shí)現(xiàn)滑動(dòng)方法總結(jié)
這篇文章主要介紹了Android 實(shí)現(xiàn)滑動(dòng)方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-07-07Android GSYVideoPlayer視頻播放器功能的實(shí)現(xiàn)
這篇文章主要介紹了Android GSYVideoPlayer視頻播放器功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)
這篇文章主要為大家介紹了Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01RecyclerView實(shí)現(xiàn)插入和刪除
這篇文章主要為大家詳細(xì)介紹了RecyclerView實(shí)現(xiàn)插入和刪除,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android 屬性動(dòng)畫ValueAnimator與插值器詳解
這篇文章主要介紹了Android 屬性動(dòng)畫ValueAnimator與插值器詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05View事件分發(fā)原理和ViewPager+ListView嵌套滑動(dòng)沖突
這篇文章主要介紹了View事件分發(fā)原理和ViewPager+ListView嵌套滑動(dòng)沖突,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià),需要的小伙伴可以參考一下2022-05-05Android 將view 轉(zhuǎn)換為Bitmap出現(xiàn)空指針問題解決辦法
這篇文章主要介紹了Android 將view 轉(zhuǎn)換為Bitmap出現(xiàn)空指針問題解決辦法的相關(guān)資料,這里提供實(shí)例并提供解決辦法,需要的朋友可以參考下2017-07-07