RecyclerView自定義分割線
前言
RecyclerView已經推出很久了,由于其高度的可定制性現在被廣泛應用,我們常用的功能,如:單條目更新,LayoutManager實現各種炫酷的排列效果,定義個性分割線等
今天學習如何定制一個自己的分割線,讓你的列表看起來更好看
內容部分
首先:常規(guī)的用法三步走設置布局方式,設置分割線,設置adapter。
本身系統(tǒng)是自帶了一個默認的分割線類DividerItemDecoration可以實現和ListView一樣的效果。但是我們可能有其他的需求,如我們希望分割線有不同的顏色,這時我們可以通過DividerItemDecoration的setDrawable(Drawable drawable)方法設置一個Drawable進入,如下:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); Drawable drawable = getResources().getDrawable(R.drawable.mycoler); dividerItemDecoration.setDrawable(drawable); recyclerView.addItemDecoration(dividerItemDecoration);
通過編寫不同的shape可以設置成不同的顏色的線。如圖:

特殊情況問題記錄
當我在繪制橫向滾動的RecyclerView的分割線的時候,出了一個小問題,因為使用shape畫的線,獲取Drawable的寬度一直為1px導致,無法顯示分割線,如果你傳入的是一個圖片就沒問題,我還沒找到原因。
描述:RecyclerView高度為100dp,item的高度為50dp,當繪制出豎直方向分割線的時候,item部分分割線未能顯示,經過排查發(fā)現,分割線是繪制在RecyclerView的view上,item作為子view存在于RecyclerView的容器中,所以導致分割線繪制的一部分被遮擋,此處我使用系統(tǒng)提供的DividerItemDecoration也是效果一致的。如下圖:

所繪制的分割線上繪制在RecyclerView的布局上的,這也就解釋了,為什么繪制完分割線需要調用getItemOffsets()方法進行位置重新排列了
如何解決這個情況呢?(其實就是自己根據出傳入的Drawable寬度處理)
1.給item設置一個padding值就可以了,這樣就可以把分割線顯示出來了。
2.通過getItemOffsets()方法設置偏移量,讓item順位后移,顯示出來分割線即可。
處理后的圖片如下:

不過這個問題我會在嘗試,找出為什么拿到的寬度數值不正確,如有知道的大佬,望告知,謝謝
定制過程分析
步驟一
初始化一些參數內容,如偏移量,默認的分割線等
public MyItemDecoration(Context context, int orientation, int inset, Drawable drawable) {
if (orientation != VERTICAL && orientation != HORIZONTAL) {
throw new IllegalArgumentException("請輸入正確的參數!");
}
this.inset = inset;
mOrientation = orientation;
mDivider = drawable;
if (drawable == null) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
}
步驟二
繪制部分,通過標識位來區(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);
}
}
}
步驟三
繪制垂直或水平的分割線,這里主要是設置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ōu)镽ecyclerView添加了分割線,所以整體位置要做調整。主要調整的部分就是,在條目中間添加一個分割線,需要對原來的所有條目后移動一個分割線的寬度(高度)。
@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);
}
}
}
以上就是基本的步驟的,其實就是參考系統(tǒng)提供的DividerItemDecoration來寫就行。其實系統(tǒng)的代碼,是最好的實例,所以多讀源碼對能力的提升很有幫助。
另外一種實現分割線的方式
其實這種方式很簡單,就是將分割線放到item布局中。感覺也是不錯的方案,畢竟在做條目布局的時候就把這個分割線完成了。
finish以上完畢,有問題謝謝指出。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android模擬器"Failed To Allocate memory 8"錯誤如何解決
這篇文章主要介紹了Android模擬器"Failed To Allocate memory 8"錯誤如何解決的相關資料,需要的朋友可以參考下2017-03-03
Android開發(fā)實現撥打電話與發(fā)送信息的方法分析
這篇文章主要介紹了Android開發(fā)實現撥打電話與發(fā)送信息的方法,結合實例形式分析了Android撥打電話及發(fā)送信息相關布局、功能實現及權限控制操作技巧,需要的朋友可以參考下2017-12-12
Android14原生PackageInstaller安裝某些apk報錯問題
本文主要介紹了在Android 14上安裝大型應用時遇到的java.lang.RuntimeException: Could not copy bitmap to parcel blob錯誤,下面就一起來介紹一下解決方法,感興趣的可以了解一下2025-03-03

