上一篇用ListView-ViewType实现了分类列表,本篇将使用RecyclerView-ViewType来实现,由于两个实现的核心思想、布局文件和数据类都是基本一致的,部分差别下面会指出,所以本篇开门见山直接进入编码部分。
一、编码
-
由于本次实现是使用RecyclerView,所以在布局和item之间的间距问题会有一些差距;
1)在item的布局文件中,分类Title
的布局去除来文字的paddingLeft
:<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/yunfei_title" android:layout_width="match_parent" android:gravity="center_vertical" android:textSize="@dimen/sp18" android:textColor="@color/blue" android:paddingTop="@dimen/dp10" android:layout_height="wrap_content"/>
2)在item的布局文件中,
coupon
的布局文件去除了cardview
外层的RelativeLayout
:<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView 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="wrap_content" android:minHeight="@dimen/dp60" app:cardBackgroundColor="@color/main_radio_selected" app:cardCornerRadius="@dimen/dp20" app:cardElevation="0dp" app:contentPaddingLeft="@dimen/dp20" app:contentPaddingRight="@dimen/dp20" app:contentPaddingTop="@dimen/dp20" tools:ignore="HardcodedText,UnusedAttribute"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:maxEms="7" android:maxLines="1" android:text="新用户优惠券新的生活" android:textSize="@dimen/sp20" /> <TextView android:id="@+id/couponDescription" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dp5" android:contentDescription="优惠券说明" android:ellipsize="end" android:maxEms="11" android:maxLines="1" android:text="优选商城通用,团购/抢购不可用" android:textSize="@dimen/sp15" /> </LinearLayout> <TextView android:id="@+id/couponMoney" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:contentDescription="优惠券金额" android:gravity="center" android:text="50" android:textSize="@dimen/sp50" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="@dimen/px1" android:background="@color/black" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingTop="@dimen/dp10" android:paddingBottom="@dimen/dp10"> <TextView android:id="@+id/indate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="有效期" android:text="2017-12-12至2019-09-05" /> <TextView android:id="@+id/useCondition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:contentDescription="满多少才能使用,使用条件" android:text="满200可用" /> </RelativeLayout> </LinearLayout> </android.support.v7.widget.CardView>
3)由于上一篇是使用在
cardView
外嵌套一层RelativeLayout
来控制item之间的间距,在Recycler中我们将用添加ItemDecoration
来控制间距:public class MarginItemDecoration extends RecyclerView.ItemDecoration { private final int marginX; private final int marginY; public MarginItemDecoration(Context context) { super(); marginX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 15, context.getResources().getDisplayMetrics()); marginY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, context.getResources().getDisplayMetrics()); } @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { outRect.set(marginX,marginY,marginX,marginY); } }
-
创建类
ViewTypeRecyclerAdapter
继承RecyclerView.Adapter<RecyclerView.ViewHolder>
这里我们使用RecyclerView.ViewHolder
因为不确定是哪种ViewHolder,所以使用父类填充范型,统一ViewHolder -
添加属性
List<CouponBean> mCouponBeanList
和Context mContext
,生成构造方法:private List<CouponBean> mCouponBeanList; private Context mContext; public ViewTypeRecyclerAdapter(List<CouponBean> couponBeanList, Context context) { mCouponBeanList = couponBeanList; mContext = context; }
-
实现抽象方法
public int getItemCount()
方法返回数据集合的长度,重写public int getItemViewType(int position
返回对应的ViewType和上篇写法一致为:@Override public int getItemViewType(int position) { String isUse = mCouponBeanList.get(position).getIsUse(); return ("0".equals(isUse) || "1.5".equals(isUse)) ? 0 : 1; }
-
实现方法
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
输出我们的ItemView,由于我们采用的是两种ViewHolder,所以我们需要创建两种ViewHolder
且都继承类RecyclerView.ViewHolder
;
1)分类TitleViewHolder
:static class TitleViewHolder extends RecyclerView.ViewHolder { private TextView title; public TitleViewHolder(@NonNull View itemView) { super(itemView); title = itemView.findViewById(R.id.yunfei_title); } void bindData(CouponBean couponBean) { title.setText(couponBean.getCouponName()); } }
2)优惠券
CouponViewHolder
:static class CouponViewHolder extends RecyclerView.ViewHolder { private TextView couponDescription, couponMoney, indate, useCondition; public CouponViewHolder(@NonNull View itemView) { super(itemView); couponDescription = itemView.findViewById(R.id.couponDescription); couponMoney = itemView.findViewById(R.id.couponMoney); useCondition = itemView.findViewById(R.id.useCondition); indate = itemView.findViewById(R.id.indate); } void bindData(CouponBean couponBean) { couponDescription.setText(couponBean.getCouponUseExplain()); couponMoney.setText(couponBean.getDenominationShow()); useCondition.setText(couponBean.getUseConditionsDesc()); indate.setText(couponBean.getValidityDate()); } }
3)创建对应的ViewHolder:
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
:@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View itemView = LayoutInflater.from(mContext).inflate(i == 0 ? R.layout.yunfei_title2 : R.layout.yunfei_coupon_item, viewGroup, false); return i == 0 ? new TitleViewHolder(itemView) : new CouponViewHolder(itemView); }
二、测试
1.activity布局文件
<?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"
tools:context=".yunfei.ListViewActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
- 初始化RecyclerView并为其设置适配器
ViewTypeRecyclerAdapte
和布局管理器LinearLayoutManager
:List<CouponBean> couponBeans = LocalDataServer.requestDateFromServerByViewType(); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new MarginItemDecoration(this)); recyclerView.setAdapter(new ViewTypeRecyclerAdapter(couponBeans, this));
3、测试效果:
-
适配器完整代码
public class ViewTypeRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<CouponBean> mCouponBeanList; private Context mContext; public ViewTypeRecyclerAdapter(List<CouponBean> couponBeanList, Context context) { mCouponBeanList = couponBeanList; mContext = context; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View itemView = LayoutInflater.from(mContext).inflate(i == 0 ? R.layout.yunfei_title2 : R.layout.yunfei_coupon_item2, viewGroup, false); return i == 0 ? new TitleViewHolder(itemView) : new CouponViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { if (viewHolder instanceof TitleViewHolder) { ((TitleViewHolder) viewHolder).bindData(mCouponBeanList.get(i)); } else { ((CouponViewHolder) viewHolder).bindData(mCouponBeanList.get(i)); } } @Override public int getItemViewType(int position) { String isUse = mCouponBeanList.get(position).getIsUse(); return ("0".equals(isUse) || "1.5".equals(isUse)) ? 0 : 1; } @Override public int getItemCount() { if (mCouponBeanList != null) { return mCouponBeanList.size(); } return 0; } static class TitleViewHolder extends RecyclerView.ViewHolder { private TextView title; public TitleViewHolder(@NonNull View itemView) { super(itemView); title = itemView.findViewById(R.id.yunfei_title); } void bindData(CouponBean couponBean) { title.setText(couponBean.getCouponName()); } } static class CouponViewHolder extends RecyclerView.ViewHolder { private TextView couponDescription, couponMoney, indate, useCondition; public CouponViewHolder(@NonNull View itemView) { super(itemView); couponDescription = itemView.findViewById(R.id.couponDescription); couponMoney = itemView.findViewById(R.id.couponMoney); useCondition = itemView.findViewById(R.id.useCondition); indate = itemView.findViewById(R.id.indate); } void bindData(CouponBean couponBean) { couponDescription.setText(couponBean.getCouponUseExplain()); couponMoney.setText(couponBean.getDenominationShow()); useCondition.setText(couponBean.getUseConditionsDesc()); indate.setText(couponBean.getValidityDate()); } } }
至此使用RecyclerView-ViewType实现分类列表显示就完成了,下一篇我们将完全使用
RecyclerView.ItemDecoration
来实现分类列表显示,其中还涉及了一点绘制的知识,see you!