为什么要使用 RecyclerView
假如说要创建一个包含100个项的列表项,如果单独为他们创建100个View,显然非常的不好。建议使用 RecyclerView 代替,它只创建刚好充满屏幕的12个View,而不是100个。用户滑动屏幕切换视图时,上一个视图>会回收利用
如何使用
RecyclerView能够显示数据还离不开另外两个类的支持:ViewHolder
子类和Adapter
子类
ViewHolder:
ViewHolder只做一件事:容纳View视图
Adapter:
创建必要的ViewHolder
绑定ViewHolder至模型层数据
示例
1. 先编写一个activity_game.xml
视图容纳 RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
2.activity_game.xml
对应的gameActivity
public class gameActivity extends AppCompatActivity {
private gameAdapter mAdapter; // 在下面有实现
private RecyclerView mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// 1.获取到 RecyclerView
mList = findViewById(R.id.recycler_view);
/*
2.
RecyclerView视图创建完成后,就立即转交给了LayoutManager对象
这里使用LinearLayoutManager类,它支持以竖直列表的形式展示列表项
*/
mList.setLayoutManager(new LinearLayoutManager(gameActivity.this));
mAdapter = new gameAdapter();
mList.setAdapter(mAdapter);
}
}
注意,没有LayoutManager的支持,不仅RecyclerView无法工作,还会导致应用崩溃。所 以,RecyclerView视图创建完成后,就立即转交给了LayoutManager对象。 RecyclerView类不会亲自摆放屏幕上的列表项。实际上,摆放的任务被委托给了 LayoutManager。除了在屏幕上摆放列表项,LayoutManager还负责定义屏幕滚动行为。因此, 没有LayoutManager,RecyclerView也就没法正常工作。 除了一些Android操作系统内置版实现,LayoutManager还有很多第三方库实现版本。我们 使用的是LinearLayoutManager类,它支持以竖直列表的形式展示列表项。我们在本书后续章 节中还会使用GridLayoutManager类,以网格形式展示列表项。 运行应用,应该还是看不到内容;现在看到的是一个RecyclerView空视图。要显示出crime 列表项,还需要完成Adapter和ViewHolder的实现。
3. 实现 ViewHolder
这里需要实现指定每个列表项的视图 game_list_item.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="vertical">
<TextView
android:id="@+id/gameTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="标题"/>
<TextView
android:id="@+id/gameContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="内容"/>
</LinearLayout>
实现 ViewHolder
,绑定上面的game_list_item.xml
视图
private class gameHolder extends RecyclerView.ViewHolder{
// 在构造方法里先实例化game_list_item布局
public gameHolder(LayoutInflater inflater, ViewGroup parent){
super(inflater.inflate(R.layout.game_list_item, parent, false));
}
}
4. 实现 Adapter
private class gameAdapter extends RecyclerView.Adapter{
// 第一步指定 列表项个数
@Override
public int getItemCount() {
return 20;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(gameActivity.this);
// 使用上面的ViewHolder
return new gameHolder(layoutInflater, parent);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
}
}
}
完整代码
activity_game.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
3.game_list_item.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="vertical">
<TextView
android:id="@+id/gameTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="标题"/>
<TextView
android:id="@+id/gameContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="内容"/>
</LinearLayout>
4.gameActivity.java
public class gameActivity extends AppCompatActivity {
private gameAdapter mAdapter;
private RecyclerView mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
mList = findViewById(R.id.recycler_view);
mList.setLayoutManager(new LinearLayoutManager(gameActivity.this));
mAdapter = new gameAdapter();
mList.setAdapter(mAdapter);
}
private class gameHolder extends RecyclerView.ViewHolder{
private TextView mgameTitle;
private TextView mgameContent;
public gameHolder(LayoutInflater inflater, ViewGroup parent){
super(inflater.inflate(R.layout.game_list_item, parent, false));
// 可以对视图内的控件进行操作,如绑定按钮事件之类 ...
// 请在此执行操作
}
public void bind(HashMap<String,String> hashMap){
mgameTitle = findViewById(R.id.gameTitle);
mgameContent = findViewById(R.id.gameContent);
}
}
private class gameAdapter extends RecyclerView.Adapter{
/* 第一步 调用Adapter的getItemCount()方法,RecyclerView询问数组列表中包含多少个对象 */
@Override
public int getItemCount() {
return 20;
}
/* 第二步:
调用Adapter的onCreateViewHolder(ViewGroup, int)方法创建ViewHolder及其要显示的视图
RecyclerView需要新的ViewHolder来显示列表项时,会调用onCreateViewHolder方法
*/
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(gameActivity.this);
return new gameHolder(layoutInflater, parent);
}
/*
第三步:
RecyclerView会传入ViewHolder及其位置,调用onBindViewHolder(ViewHolder,int)方法
Adapter会找到目标位置的数据并将其绑定到ViewHolder的视图上。
所谓绑定,就是使用模型数据填充视图。
*/
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
}
}
}