前言
在项目中基本上都会用到的 多种item(条目)的加载 比如大家常见的app( <网易新闻>app的新闻的列表,<新闻头条>app的新闻列表) 都是采用了加载多种item的布局。例如下图:
但是我们要如何实现这种功能呢?很多人说用recycleview嵌套recycleview,但是事实上,种方法并不理想,理由是一方面recycleview嵌套会产生冲突;另一方面作为前端有时候后端的接口传值并不能满足我们两个recycleview嵌套。因此我们需要采用recycleview的多布局实现这类功能。
看了很多例子,说其实最关键的是要复写RecyclerView的Adapter中的getItemViewType()方法 这个方法就根据条件返回条目的类型,然后onCreateViewHolder里根据viewtype来判断 所引用的item布局类型 这样每一条item就会不一样了,但是种方法不好维护。我就用了另一种方法,使用自定义View实现。
第一层:显示页面
1. Bean存储类型(AdapterBean)
public class AdapterBean implements MultiItemEntity {
//第一个布局
public static final int LEARNRECORD_ONE = 1;
//第二个布局
public static final int LEARNRECORD_TWO = 2;
//第三个布局
public static final int LEARNRECORD_Three = 3;
//第四个布局
public static final int LEARNRECORD_FLOUR = 4;
public int itemType;
public LearnRecordAdapterBean(int type) {
itemType = type;
}
@Override
public int getItemType() {
return itemType;
}
}
2. 显示页面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFFF"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srlEnableLoadMore="false">
<android.support.v7.widget.RecyclerView
android:id="@+id/rl_learnrecord"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</RelativeLayout>
</LinearLayout>
3. recyclerview的adapter
public class LearnRecordAdapter extends BaseMultiItemQuickAdapter<LearnRecordAdapterBean, BaseViewHolder> {
private LearnOneView OneView;
private LearnTwoView TwoView;
private LearnThreeView ThreeView;
private LearnFourView FourView;
public LearnRecordAdapter(List<AdapterBean> data) {
super(data);
addItemType(AdapterBean.LEARNRECORD_ONE, R.layout.openhome_learnrecord_item_head);
addItemType(AdapterBean.LEARNRECORD_TWO, R.layout.openhome_learnrecord_item_learnweek);
addItemType(AdapterBean.LEARNRECORD_THREE,
R.layout.openhome_learnrecord_item_errorstop);
addItemType(AdapterBean.LEARNRECORD_FOUR,
R.layout.openhome_learnrecord_item_errorstop)
}
@Override
protected void convert(BaseViewHolder helper, AdapterBean item) {
switch (helper.getItemViewType()){
case AdapterBean.LEARNRECORD_ONE:
OneView = helper.getView(R.id.headview);
OneView.setData();
break;
case AdapterBean.LEARNRECORD_TWO:
TwoView = helper.getView(R.id.learnweekview);
TwoView.setData();
break;
case AdapterBean.LEARNRECORD_THREE:
ThreeView = helper.getView(R.id.errorstopview) ;
ThreeView.setData();
break;
case AdapterBean.LEARNRECORD_FOUR:
FourView = helper.getView(R.id.errorstopview) ;
FourView.setData();
break;
default:
break;
}
}
}
4. 显示页面activity
public class LearnRecordActivity extends BaseActivity {
public LearnRecordAdapter learnRecordAdapter;
private RecyclerView recyclerView;
private List<AdapterBean> learnRecorddata = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
initData();
initAdapter();
}
/**
* 初始化数据
*/
private void initData(){
if (learnRecorddata!=null&&learnRecorddata.size()>0){
learnRecorddata.clear();
}
// 绑定数据
learnRecorddata.add(new AdapterBean(AdapterBean.LEARNRECORD_ONE));
learnRecorddata.add(new AdapterBean(AdapterBean.LEARNRECORD_TWO));
learnRecorddata.add(new AdapterBean(AdapterBean.LEARNRECORD_THREE));
learnRecorddata.add(new AdapterBean(AdapterBean.LEARNRECORD_FOUR));
if (learnRecordAdapter != null) {
learnRecordAdapter.notifyDataSetChanged();
}
}
/**
* 初始化适配器
*/
private void initAdapter() {
// recyclerview绑定adapter
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
learnRecordAdapter = new LearnRecordAdapter(learnRecorddata);
recyclerView.setAdapter(learnRecordAdapter);
}
}
第二层:各个item的布局(自定义view)
由于四个item的应用大同小意,那么这里就仅仅介绍第一个item的实现。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.xes.cloudlearning.openhome.view.LearnRecordHeadView
android:id="@+id/headview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
在这里可以看到,这里是一个自定义view,点击LearnRecordHeadView可以进去看到这个自定义view的布局。
public class LearnRecordHeadView extends RelativeLayout {
@BindView(R2.id.tv_practice)
TextView tvPractice;
@BindView(R2.id.tv_areadykeep)
TextView tvAreadykeep;
@BindView(R2.id.tv_countnum)
TextView tvCountnum;
@BindView(R2.id.tv_count)
TextView tvCount;
@BindView(R2.id.tv_test)
TextView tvTest;
@BindView(R2.id.tv_practicenum)
TextView tvPracticenum;
@BindView(R2.id.tv_pk)
TextView tvPk;
@BindView(R2.id.tv_pknum)
TextView tvPknum;
private Context mContext;
public LearnRecordHeadView(Context context) {
super(context);
mContext = context;
initView();
}
public LearnRecordHeadView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
}
public LearnRecordHeadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView();
}
private void initView() {
View.inflate(mContext, R.layout.openhome_title_item_layout, this);
ButterKnife.bind(this);
}
@SuppressLint("SetTextI18n")
public void setData() {
tvPractice.setText("80");
tvAreadykeep.setText("XXX");
tvCountnum.setText("800");
tvCount.setText("XXX");
tvTest.setText("XXXX");
tvPracticenum.setText("XX");
tvPk.setText("XX");
tvPknum.setText("XXX");
}
}
在这里看到这里还有一个布局,也就是这个自定义view的布局openhome_title_item_layout。点击进去看。我们在这个view中处理这里的数据和逻辑。
<?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="wrap_content“>
<LinearLayout
android:id="@+id/ll_headView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content
android:layout_marginTop="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
</RelativeLayout>
<View
android:id="@+id/tv_right_line"
android:layout_width="1dp"
android:layout_height="33dp"
android:layout_alignParentRight="true"
android:layout_marginTop="40dp"
android:background="#E6E6E6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
这就是完整的流程,以后一个非常复杂的页面,完全可以用一个recycleview实现。