同样的道理,我们直接上效果图:
从这个示意图中也可以看出:其也是由三部分组成,头部+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;
}
}
以上,大功告成