Android RecyclerView实际使用 - 制作一个列表¶
更新日期:2022-7-27
- 2022-7-27 修改列表
示例,用RecyclerView做出一个列表。显示测试数据。
前面我们已经知道如何用RecyclerView显示一列数据。这里我们做出一个具体的例子。尽量做好看一点。
这个示例会分为以下几个步骤:
- 1.确定数据。这里用的是模拟数据。
- 2.设计UI和表现形式。
- 3.编写layout与适配器。
模拟数据¶
巧妇难为无米之炊,模拟数据就是模拟需求。
新建一个类DataTest,设计4个属性。
public class DataTest {
private String timezone;
private int number;
private int personCount;
private int count;
public DataTest(String timezone, int number, int personCount, int count) {
this.timezone = timezone;
this.number = number;
this.personCount = personCount;
this.count = count;
}
// getter setter...
}
设计item的布局¶
设计UI,在一行里显示4个属性值。item用的是item_recy2.xml
。
<?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"
android:orientation="horizontal">
<TextView
android:id="@+id/tv1"
style="@style/RePage2Header"
android:layout_marginEnd="@dimen/re_2_half_gap" />
<TextView
android:id="@+id/tv2"
style="@style/RePage2Header"
android:layout_marginStart="@dimen/re_2_half_gap"
android:layout_marginEnd="@dimen/re_2_half_gap" />
<TextView
android:id="@+id/tv3"
style="@style/RePage2Header"
android:layout_marginStart="@dimen/re_2_half_gap"
android:layout_marginEnd="@dimen/re_2_half_gap" />
<TextView
android:id="@+id/tv4"
style="@style/RePage2Header"
android:layout_marginStart="@dimen/re_2_half_gap" />
</LinearLayout>
本例中的ui我们自由发挥。
准备颜色,尺寸等资源¶
相关的style和颜色,尺寸配置文件,在res/values
目录下。
关于资源文件,可以参考res资源目录简介
style文件style.xml
。
<style name="RePage2Header">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">40dp</item>
<item name="android:layout_weight">2</item>
<item name="android:textColor">#ffffff</item>
<item name="android:gravity">center</item>
<item name="android:background">@color/rePage2Item</item>
</style>
layout_width
为0dp。是为了使用layout_weight
属性。
让它们4个TextView按比例分割父View的宽度。
这里的分割用到了LinearLayout的分割占比特性。
颜色配置文件color.xml
,添加如下颜色设置。
尺寸配置dimens.xml
。
设计ViewHolder¶
资源文件和layout准备妥当,开始写对应的viewHolder。这里也是把VH类和Adapter类放在activity类里面。
private class VH extends RecyclerView.ViewHolder {
TextView tv1;
TextView tv2;
TextView tv3;
TextView tv4;
public VH(@NonNull View itemView) {
super(itemView);
tv1 = itemView.findViewById(R.id.tv1);
tv2 = itemView.findViewById(R.id.tv2);
tv3 = itemView.findViewById(R.id.tv3);
tv4 = itemView.findViewById(R.id.tv4);
}
}
设计Adapter类¶
适配器Adapter类。
private class Adapter extends RecyclerView.Adapter<VH> {
private List<DataTest> dataList = new ArrayList<>();
public Adapter() {
}
public void setDataList(List<DataTest> dataList) {
this.dataList = dataList; // 最好进行判空操作
notifyDataSetChanged();
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new VH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recy2, parent, false));
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
DataTest dataTest = dataList.get(position);
holder.tv1.setText(dataTest.getTimezone());
holder.tv2.setText(String.valueOf(dataTest.getNumber()));
holder.tv3.setText(String.valueOf(dataTest.getPersonCount()));
holder.tv4.setText(String.valueOf(dataTest.getCount()));
}
@Override
public int getItemCount() {
return dataList.size();
}
}
配置RecyclerView¶
设置recyclerview。
// 在activity或者fragment里
private Adapter mAdapter = new Adapter();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_recy_2);
RecyclerView recyclerView = findViewById(R.id.re_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
recyclerView.setAdapter(mAdapter);
mAdapter.setDataList(genDataTestList());
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.top = getResources().getDimensionPixelOffset(R.dimen.re_2_gap);
}
});
}
// 生成模拟数据
private List<DataTest> genDataTestList() {
List<DataTest> list = new ArrayList<>();
for (int i = 1; i <= 60; i++) {
DataTest d = new DataTest("时区" + i, i, i, i);
list.add(d);
}
return list;
}
onCreate
方法中配置recyclerView。
recyclerView.addItemDecoration
方法是给item设置间隔样式。
getItemOffsets
可以设置子项的间距。这里给子项底部一个间距值。具体数值设置在dimen中。
genDataTestList()
是生成模拟的数据。
运行效果¶
运行起来即可看到效果。
使用include修改layout¶
看到效果图,有的朋友问:表头和item的结构是一样的,可以复用吗?
其实是可以的。我们可以在layout中使用include
标签,把另一个layout文件“包含”进来。
复制act_recy_2.xml
粘贴得到act_recy_2_include.xml
,把原来的表头的LinearLayout改成include。
item_recy2
。
当我们想添加个margin-top
的时候,比如这样
as会弹出警告:
Layout parameter layout_marginTop ignored unless both layout_width and layout_height are also specified on
tag
也就是在include标签中,如果要设置其他属性,需要先设置layout_width
和layout_height
。
修改一下,再加个id,变成这样。
<include
android:id="@+id/header"
layout="@layout/item_recy2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp" />
让Activity使用这个layout。修改一下RecyclerViewDemo2Act
。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_recy_2_include);
initHeader();
// 配置RecyclerView的部分
}
private void initHeader() {
View header = findViewById(R.id.header);
TextView tv1 = header.findViewById(R.id.tv1);
tv1.setText("时区");
TextView tv2 = header.findViewById(R.id.tv2);
tv2.setText("序号");
TextView tv3 = header.findViewById(R.id.tv3);
tv3.setText("人员");
TextView tv4 = header.findViewById(R.id.tv4);
tv4.setText("数量");
}
initHeader()
。里面先把header找到,通过header找到它的子view,也就是那4个TextView。
分别设置文字即可。
运行看看效果,是不是和前面的一样。
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~