RecyclerView - 新增不同的分割線
如何給RecyclerView 新增不同的分割線:
UI出的效果圖:
關鍵點:
自定義
ItemDecoration
-
關鍵的方法:
RecyclerView
的getChildAdapterPosition(View child)
方法:
返回這個itemView 對應的 adapter position
這個adapter position 是介面卡裡的資料position 拿到了這個position,就能知道viewType 了
/**
* Return the adapter position that the given child view corresponds to.
*
* @param child Child View to query
* @return Adapter position corresponding to the given view or {@link #NO_POSITION}
*/
public int getChildAdapterPosition(View child) {
final ViewHolder holder = getChildViewHolderInt(child);
return holder != null ? holder.getAdapterPosition() : NO_POSITION;
}
code
public class DifWidthDecoration extends RecyclerView.ItemDecoration {
private Context mContext;
private Drawable mDividerWidth;
private Drawable mDividerNarrow;
private int mOrientation;
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
public DifWidthDecoration(Context context, int oritation) {
this.mContext = context;
this.mOrientation = oritation;
this.mDividerWidth = context.getResources().getDrawable(R.drawable.divider_wider);
this.mDividerNarrow = context.getResources().getDrawable(R.drawable.divider_narrow);
setOrientation(oritation);
}
//設定螢幕方向
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
this.mOrientation = orientation;
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == HORIZONTAL_LIST) {
//橫向 list 畫豎線
drawVerticalLine(c, parent, state);
} else if (mOrientation == VERTICAL_LIST) {
//豎向list 畫橫線
drawHorizontalLine(c, parent, state);
}
}
private static final String TAG = "DifWidthDecoration";
private void drawHorizontalLine(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
int blankWidth = DisplayUtil.getScreenWidth(mContext) / 10;
Log.d(TAG, String.format("childCount -> %d", childCount));
//由於RecyclerViwe 複用ItemView 這裡的childCount 是使用者可見的 count
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
//接上面:所以要拿到itemView 對應的adapter position,但是方法的引數裡不像getItemOffsets()裡回撥了View view
//所以 自己取到child 通過RecyclerView 的 getChildAdapterPosition(child) 來取到adapterPosition
//舊的寫法 parent.getAdapter().getItemType(i) -> 會造成 分割線的錯亂
int adapterPosition = parent.getChildAdapterPosition(child);
int type = parent.getAdapter().getItemViewType(adapterPosition);
if (type == DifferentDividerAdapter.item_type_group) {
//拿到child 的佈局資訊
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDividerWidth.getIntrinsicHeight();
mDividerWidth.setBounds(left, top, right, bottom);
mDividerWidth.draw(c);
} else if (type == DifferentDividerAdapter.item_type_child) {
//拿到child 的佈局資訊
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDividerNarrow.getIntrinsicHeight();
mDividerNarrow.setBounds(left + blankWidth, top, right, bottom);
mDividerNarrow.draw(c);
}
}
}
private void drawVerticalLine(Canvas c, RecyclerView parent, RecyclerView.State state) {
int top = parent.getPaddingTop();
int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
int blankWidth = DisplayUtil.getScreenWidth(mContext) / 10;
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
int adapterPosition = parent.getChildAdapterPosition(child);
int type = parent.getAdapter().getItemViewType(adapterPosition);
if (type == DifferentDividerAdapter.item_type_group) {
//拿到child 的佈局資訊
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDividerWidth.getIntrinsicWidth();
mDividerWidth.setBounds(left, top, right, bottom);
mDividerWidth.draw(c);
} else if (type == DifferentDividerAdapter.item_type_child) {
//拿到child 的佈局資訊
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDividerNarrow.getIntrinsicWidth();
mDividerNarrow.setBounds(left, top + blankWidth, right, bottom);
mDividerNarrow.draw(c);
}
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int adapterPosition = parent.getChildAdapterPosition(view);
int type = parent.getAdapter().getItemViewType(adapterPosition);
if (mOrientation == HORIZONTAL_LIST) {
if (type == DifferentDividerAdapter.item_type_group) {
//畫豎線 向右偏移divider 的寬度
outRect.set(0, 0, mDividerWidth.getIntrinsicWidth(), 0);
} else if (type == DifferentDividerAdapter.item_type_child) {
outRect.set(0, 0, mDividerWidth.getIntrinsicWidth(), 0);
}
} else if (mOrientation == VERTICAL_LIST) {
if (type == DifferentDividerAdapter.item_type_group) {
//畫橫線 向下偏移divider 的高度
outRect.set(0, 0, 0, mDividerWidth.getIntrinsicHeight());
} else if (type == DifferentDividerAdapter.item_type_child) {
outRect.set(0, 0, 0, mDividerNarrow.getIntrinsicHeight());
}
}
}
}
效果:
注意:
onDrawOver()
-> drawHorizontalLine(Canvas c, RecyclerView parent, RecyclerView.State state)
這裡:
final int childCount = parent.getChildCount();
由於RecyclerViwe 複用ItemView 這裡的childCount 是使用者可見的 count
所以最開始我這樣取得itemType :
int type = parent.getAdapter().getItemVieType(i);
直接用遍歷時的 i 作為了view 對應的adapter position,
是錯誤的,隨著RecyclerView 的滑動,會造成Divider的錯亂(具體表現為:向下移動,好奇的可以自試一下)
因為這個 i 是關於 childCount 的,而childCount 最多就是 螢幕上能展示出的itemView的個數
相關文章
- RecyclerView使用指南(三)—— 新增分割線和點選事件View事件
- RecyclerVieW自定義華麗的分割線View
- 地表最強 RecyclerView 分割線 Y_DividerItemDecoration 2.0ViewIDE
- RecyclerView新增動態水印View
- RecyclerView 梳理:點選&長按事件、分割線、拖曳排序、滑動刪除View事件排序
- RecyclerView點選新增波紋效果View
- 為RecyclerView新增FootView和HeadViewView
- Android 給RecyclerView新增頭部和尾部AndroidView
- unbuntu新增交換分割槽
- html 分割線HTML
- 線條分割,
- 封裝RecyclerView,實現新增頭部和底部封裝View
- 分割槽表的不同操作對索引的影響索引
- linux新增swap分割槽Linux
- linux 新增硬碟分割槽Linux硬碟
- swap分割槽新增刪除
- (轉) Android 優雅的為RecyclerView新增HeaderView和FooterViewAndroidViewHeader
- Android中的分割線Android
- Oracle帶區域性分割槽索引的分割槽表刪除舊分割槽新增新分割槽Oracle索引
- linux使用fdisk新增分割槽的例子Linux
- 介面無小事(二): 讓RecyclerView展示更多不同檢視View
- MySql資料分割槽操作之新增分割槽操作MySql
- Oracle11g INTERVAL分割槽新增分割槽策略Oracle
- RecyclerView零點突破(動畫+邊線篇)View動畫
- 給RecyclerView新增showLoadng、showEmpty、showError和LoadMore功能ViewError
- 用檔案新增Swap分割槽
- Oracle12.2中新增的分割槽功能Oracle
- Laravel redis 連不同的連線LaravelRedis
- 學習筆記】分割槽表和分割槽索引——新增表分割槽(二)筆記索引
- 自定義RecyclerView新增HeaderView,新增FooterView,實現滑動到底部,載入更多ViewHeader
- ORACLE將不同表改為分割槽表Oracle
- 分割槽表與堆表執行計劃的不同
- Liunx新增新硬碟和分割槽方法硬碟
- linux 新增磁碟 分割槽掛載Linux
- 取消特定UITableViewCell、UITableHeaderFooterView的分割線UIViewHeader
- 清除UITableView底部多餘的分割線UIView
- 不同的連線方式效能對比!
- RecyclerView的使用View