如何为RecyclerView的日历模块添加内部分隔线?
解决RecyclerView日历模块添加分隔线的问题
看起来你现在把分隔线放在了RecyclerView外面的LinearLayout里,没法和内部的日历模块联动对吧?别担心,我们可以通过几个方法把分隔线整合到RecyclerView内部,适配日历部分的进度判断需求:
方法一:利用RecyclerView的ItemDecoration(推荐)
这是最灵活的方式,能精准控制分隔线只在日历模块的item之间显示:
- 先把布局里外面的那些ImageView分隔线删掉,只保留RecyclerView:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gray_bg" android:orientation="vertical"> <android.support.v7.widget.RecyclerView android:id="@+id/recycleView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
- 自定义一个
CalendarDividerDecoration类,继承RecyclerView.ItemDecoration,在里面判断当前item是否属于日历模块,并且只在符合条件的位置绘制分隔线:
public class CalendarDividerDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; private int mTopViewType; // 顶部视图的itemType public CalendarDividerDecoration(Context context, int topViewType) { mDivider = ContextCompat.getDrawable(context, R.drawable.history_norm_delimiter); mTopViewType = topViewType; } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); for (int i = 0; i < parent.getChildCount(); i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); // 只给日历模块的item添加分隔线(跳过顶部视图,以及最后一个日历item) int itemType = parent.getAdapter().getItemViewType(parent.getChildAdapterPosition(child)); if (itemType != mTopViewType && i < parent.getChildCount() - 1) { int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } }
- 在你的Activity里给RecyclerView添加这个Decoration:
// 假设你的顶部视图itemType是0,日历模块是1 recycleView.addItemDecoration(new CalendarDividerDecoration(this, 0));
方法二:在日历item布局中内置分隔线
如果你的分隔线位置固定,也可以直接在日历item的布局文件底部添加ImageView:
<!-- 日历item的布局 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 日历内容部分 --> <TextView android:id="@+id/tv_calendar_date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2024-05-20"/> <!-- 分隔线ImageView,根据进度判断是否显示 --> <ImageView android:id="@+id/iv_divider" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/history_norm_delimiter" android:visibility="gone"/> </LinearLayout>
然后在Adapter的onBindViewHolder里,根据进度目标判断是否显示这个分隔线:
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof CalendarViewHolder) { CalendarViewHolder calendarHolder = (CalendarViewHolder) holder; // 假设hasReachTarget是判断是否达成进度目标的方法 boolean hasReachTarget = checkIfReachTarget(position); calendarHolder.ivDivider.setVisibility(hasReachTarget ? View.VISIBLE : View.GONE); } }
方法三:添加专门的分隔线Item
如果需要在特定的日历项之间插入分隔线,可以在Adapter里新增一个分隔线的itemType,然后在数据列表中合适的位置插入分隔线数据:
- 定义itemType:
private static final int TYPE_TOP = 0; private static final int TYPE_CALENDAR = 1; private static final int TYPE_DIVIDER = 2;
- 在
getItemViewType中返回对应的类型:
@Override public int getItemViewType(int position) { Object item = mDataList.get(position); if (item instanceof TopViewData) { return TYPE_TOP; } else if (item instanceof CalendarData) { return TYPE_CALENDAR; } else if (item instanceof DividerData) { return TYPE_DIVIDER; } return super.getItemViewType(position); }
- 在
onCreateViewHolder中创建分隔线的ViewHolder:
@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == TYPE_DIVIDER) { View view = inflater.inflate(R.layout.item_divider, parent, false); return new DividerViewHolder(view); } // 其他类型的ViewHolder创建... }
这样就能把分隔线完全整合到RecyclerView内部,和日历模块的进度状态联动啦。
内容的提问来源于stack exchange,提问作者ManLok Wong
相关产品推荐
相关产品推荐

