RecyclerView的Item多种类型的选择和不同样式展示之利用框架方法实现

xiaoxiao2021-02-27  148

同样的道理,我们直接上效果图:

从这个示意图中也可以看出:其也是由三部分组成,头部+RecyclerView+尾部,只不过其头部比较复杂,所以我们采用一个第三方的框架:

compile 'com.jakewharton:butterknife:7.0.1' //recyclerView头部框架 compile 'com.bartoszlipinski.recyclerviewheader:library:1.2.1' compile 'com.android.support:recyclerview-v7:25.3.1'

直接上代码:注释很详细 第一步:窗口界面

//数据集合 private List<PrimeProduct> mDatas; private PrimeProductAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(linearLayoutManager); //封装其数据,填充假数据 initRecyclerViewData(); recyclerView.setAdapter(mAdapter); //RecyclerView的头部--使用第三方,不算一种Type类型 RecyclerViewHeader recyclerViewHeader = RecyclerViewHeader.fromXml(this, R.layout.list_item_prime_product_header); //绑定头部到RecyclerView,此时使用的时候必须注意RecyclerView的根布局必须是FrameLayout或者RelativeLayout或者LinearLayout recyclerViewHeader.attachTo(recyclerView); } //将其数据分装成二种类型,recyclerView和尾部数据 private void initRecyclerViewData() { mDatas = new ArrayList<>(); //第一种类型 PrimeProduct product = new PrimeProduct(); product.productName = "新手专享163期"; product.productDesc = "注册理财金可用-限APP"; product.annualRate = "预期年化"; product.annualRateValue = 12.00f; product.operator = "立即抢购"; product.timeLimit = 7; product.isNowBuy = true; mDatas.add(product); PrimeProduct product2 = new PrimeProduct(); product2.productName = "新手专享221期"; product2.productDesc = "1元起购"; product2.annualRate = "预期年化"; product2.annualRateValue = 18.00f; product2.operator = "立即抢购"; product2.timeLimit = 43; product2.isNowBuy = true; mDatas.add(product2); PrimeProduct product3 = new PrimeProduct(); product3.productName = "一铜金A1257期"; product3.productDesc = "仅限购宝购买"; product3.annualRate = "预期年化"; product3.annualRateValue = 6.00f; product3.operator = "立即抢购"; product3.timeLimit = 28; product3.isNowBuy = false; mDatas.add(product3); PrimeProduct product4 = new PrimeProduct(); product4.productName = "一铜天下1310期"; product4.productDesc = "抢购"; product4.annualRate = "预期年化"; product4.annualRateValue = 5.80f; product4.operator = "立即抢购"; product4.timeLimit = 20; product4.isNowBuy = false; mDatas.add(product4); //第二种类型 PrimeProduct bottom = new PrimeProduct(); mDatas.add(bottom); mAdapter = new PrimeProductAdapter(this, mDatas); }

第二步:Adapter封装数据

public class PrimeProductAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context mContext; private List<PrimeProduct> mDatas; //定义二种不同类型的变量 public static final int TYPE_ITEM_RECYCLER = 1; public static final int TYPE_FOOTER_RECYCLER = 2; private final LayoutInflater mInflater; public PrimeProductAdapter(Context context, List<PrimeProduct> datas) { this.mContext = context; this.mDatas = datas; mInflater = LayoutInflater.from(context); } //根据不同的viewType去创建不同的ViewHolder @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_ITEM_RECYCLER) { //RecyclerView的Item的布局 View view = mInflater.inflate(R.layout.list_item_prime_product, parent, false); return new ProductViewHodler(view); } else { //底部ViewHodler //尾部的布局 return new BottomViewHodler(mInflater.inflate(R.layout.list_item_prime_product_bottom, parent, false)); } } //RecyclerView中item的ViewHodler public static class ProductViewHodler extends RecyclerView.ViewHolder { @Bind(R.id.name) TextView mName; @Bind(R.id.desc) TextView mDesc; @Bind(R.id.year_epr) TextView mYearEpr; @Bind(R.id.time_limit_title) TextView mTimeLimitTitle; @Bind(R.id.time_limit) TextView mTimeLimit; @Bind(R.id.btn_buy_now) Button mBtnBuyNow; @Bind(R.id.buy_now_layout) LinearLayout mBuyNowLayout; @Bind(R.id.txt_buy_now) TextView mTxtBuyNow; @Bind(R.id.buy_now_layout2) LinearLayout mBuyNowLayout2; public ProductViewHodler(View itemView) { super(itemView); ButterKnife.bind(this,itemView); } } //底部ViewHodler public static class BottomViewHodler extends RecyclerView.ViewHolder { public BottomViewHodler(View itemView) { super(itemView); } } //根据返回的holder或者getItemViewType()返回的类型去绑定不同的数据 @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //或者通过不同的itemViewType去添加不同的数据 int itemViewType = getItemViewType(position); switch (itemViewType) { case TYPE_FOOTER_RECYCLER: //尾部填充的数据 BottomViewHodler bottomHolder = (BottomViewHodler) holder; break; case TYPE_ITEM_RECYCLER: //RecyclerView每个Item填充的数据 ProductViewHodler productViewHolder = (ProductViewHodler) holder; PrimeProduct product = mDatas.get(position); productViewHolder.mName.setText(product.productName); productViewHolder.mDesc.setText(product.productDesc); productViewHolder.mYearEpr.setText(String.valueOf(product.annualRateValue)); productViewHolder.mTimeLimit.setText(String.valueOf(product.timeLimit)); //自定义boolean属性,控制btn立即购买样式条目显示 if (product.isNowBuy) { productViewHolder.mBuyNowLayout.setVisibility(View.VISIBLE); productViewHolder.mBuyNowLayout2.setVisibility(View.GONE); } else { productViewHolder.mBuyNowLayout.setVisibility(View.GONE); productViewHolder.mBuyNowLayout2.setVisibility(View.VISIBLE); } break; } //通过不同的ViewHodler来添加不同的数据都可以解决问题 /* if (holder instanceof ProductViewHodler) { ProductViewHodler productViewHolder = (ProductViewHodler) holder; PrimeProduct product = mDatas.get(position); ProductViewHodler.mName.setText(product.productName); ProductViewHodler.mDesc.setText(product.productDesc); ProductViewHodler.mYearEpr.setText(String.valueOf(product.annualRateValue)); ProductViewHodler.mTimeLimit.setText(String.valueOf(product.timeLimit)); //自定义boolean属性,控制btn立即购买样式条目显示 if (product.isNowBuy) { ProductViewHodler.mBuyNowLayout.setVisibility(View.VISIBLE); ProductViewHodler.mBuyNowLayout2.setVisibility(View.GONE); } else { ProductViewHodler.mBuyNowLayout.setVisibility(View.GONE); ProductViewHodler.mBuyNowLayout2.setVisibility(View.VISIBLE); } } else if (holder instanceof BottomViewHodler) { BottomViewHodler bottomHolder = (BottomViewHodler) holder; }*/ } 返回的是总体的RecyclerView的Item加上Btn @Override public int getItemCount() { return mDatas == null ? 0 : mDatas.size(); } //根据索引位置去判断其显示不同类型的TYPE @Override public int getItemViewType(int position) { int itemCount = getItemCount(); if (position == itemCount - 1) { //返回尾部的对应的类型 return TYPE_FOOTER_RECYCLER; } else { return TYPE_ITEM_RECYCLER; } } }

第三步:需要注意的事项:

1, 使用RecyclerView和RecyclerViewHead相互绑定的时候,其RecyclerView的父视图必须是FrameLayout或者RelativeLayout或者LinearLayout

2,通过自定义boolean变量的值isNowBuy,去控制btn不同样式的展示布局如下:

<RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:orientation="horizontal"> <LinearLayout android:id="@+id/buy_now_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="visible"> <Button android:id="@+id/btn_buy_now" android:layout_width="match_parent" android:layout_height="38dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:background="@drawable/btn_common_sel" android:gravity="center" android:text="立即抢购" android:textColor="@color/white"/> <View android:layout_width="match_parent" android:layout_height="13dp"/> </LinearLayout> <LinearLayout tools:visibility="visible" android:id="@+id/buy_now_layout2" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_txt_buy_now_sel" android:clickable="true" android:orientation="vertical" android:visibility="gone"> <View android:layout_width="match_parent" android:layout_height="1px" android:background="#eeeeee"/> <TextView android:id="@+id/txt_buy_now" android:layout_width="match_parent" android:layout_height="45dp" android:gravity="center" android:text="立即抢购" android:textColor="#ff0000"/> </LinearLayout> </RelativeLayout>

3,对象中自定义Boolean属性值:如下

public class PrimeProduct { //偷懒写法 public String productName; public String productDesc; public String annualRate; public float annualRateValue; public String operator; public int timeLimit; /** * 自己添加的控制属性,显示立即抢购 */ public boolean isNowBuy = false; }

以上,即可实现RecyclerView多种不同布局

另外介绍一种:在Bean对象中,自定义ViewType类型,去实现getItemViewType(); //Bean对象

//Bean对象 public class InvestProduct { public int resId; public String title; public String desc; public String reservation; //预约描述 public int timeLimit; //时间限制 //设置其状态为网络连接状态 public int viewType = InvestProductAdapter.ITEM_TYPE_COMMON; //自定义二个boolean字段,控制属性 public boolean isReservation; //是否预定 public boolean hasTimeLimit; //是否有时间限制 }

//activity和fragment实现类型的占位

List<InvestProduct> mDatas = new ArrayList<InvestProduct>(); InvestProduct network = new InvestProduct(); network.viewType = InvestProductAdapter.ITEM_TYPE_NETWORK_ERROR; InvestProduct none = new InvestProduct(); none.viewType = InvestProductAdapter.ITEM_TYPE_TONG_BAO; mDatas.add(network); // 数据占位 mDatas.add(none); // 数据占位

//adapter中数据的编写

public static final int ITEM_TYPE_COMMON = 0; public static final int ITEM_TYPE_TONG_BAO = 1; public static final int ITEM_TYPE_NETWORK_ERROR = 2; //创建ViewHolder @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_COMMON) { //带下标题栏的(和不带标题栏的) return new ProductViewHolder(mLayoutInflater.inflate(R.layout.list_item_invest, parent, false)); } else if (viewType == ITEM_TYPE_TONG_BAO){ //头部视图 return new HeaderHolder(mLayoutInflater.inflate(R.layout.list_item_invest_header, parent, false)); } else { //暂无数据,请先检查网络 return new NetworkHolder(mLayoutInflater.inflate(R.layout.view_network_unusual, parent, false)); } } //通过自定义字段去控制ViewType类型 @Override public int getItemViewType(int position) { //InvestProduct 为javaBean对象 InvestProduct investProduct = mDatas.get(position); if (investProduct.viewType == ITEM_TYPE_NETWORK_ERROR) { return ITEM_TYPE_NETWORK_ERROR; } else if (investProduct.viewType == ITEM_TYPE_TONG_BAO){ return ITEM_TYPE_TONG_BAO; } else { return ITEM_TYPE_COMMON; } }

以上,大功告成

转载请注明原文地址: https://www.6miu.com/read-14956.html

最新回复(0)