📅  最后修改于: 2023-12-03 15:13:20.429000             🧑  作者: Mango
ListView 是 Android 开发中使用非常广泛的组件。然而,随着许多新的功能(如动画、复杂布局等)的要求,ListView 已经不足以满足我们的需求。为了应对这些问题,Google 推出了一个新的组件:RecyclerView。
RecyclerView 与 ListView 相似,但具有更好的性能和更丰富的功能。它是一种更高级别的、强大的实现,可用于实现更复杂的布局和动画。
在这篇文章中,我们将讨论如何将你的 ListView 迁移到 RecyclerView 中。
要开始使用 RecyclerView,需要在 build.gradle 文件中添加 RecyclerView 依赖项:
implementation 'androidx.recyclerview:recyclerview:{version}'
一旦库已经导入,我们就需要修改布局文件来替换 ListView。
要进行此操作,我们可以使用 RecyclerView
标签替换现有的 ListView
标签:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
现在我们已经将布局文件迁移到 RecyclerView 中,我们需要修改 Java 代码来更新 Adapter 和 ViewHolder。以下是在 ListView 和 RecyclerView 中使用的标准流程:
1. 创建 ViewHolder
在 RecyclerView 中,不再需要 ViewHolder 中的 findViewById()。相反,它是由构造函数注入的。然而,因为 RecyclerView 根据需要复用 ViewHolder,所以它可能处于多个布局中,因此我们需要在 ViewHolder 的构造函数中为它提供合适的视图类型。
ViewHolder 代码在 ListView 和 RecyclerView 中稍有不同:
ListView 的 ViewHolder:
public static class ViewHolder {
public TextView textView;
public ViewHolder(View itemView) {
textView = (TextView)itemView.findViewById(R.id.text);
}
}
RecyclerView 的 ViewHolder:
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView)itemView.findViewById(R.id.text);
}
}
可以看到,在 RecyclerView 中,我们的 ViewHolder 扩展了 RecyclerView.ViewHolder 并在构造函数中调用了 super()。这确保了它拥有与 RecyclerView 相关的功能。
2. 创建 Adapter
RecyclerView 的 Adapter 需要我们实现一个新的方法:onBindViewHolder()。此方法与 getView() 方法类似,但它将 ViewHolder 作为参数,而不是返回一个。
ListAdapter 代码:
public class ListAdapter extends ArrayAdapter<String> {
private final LayoutInflater mInflater;
private final List<String> mItems;
public ListAdapter(Context context, List<String> items) {
super(context, R.layout.list_item, items);
mInflater = LayoutInflater.from(context);
mItems = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(getItem(position));
return convertView;
}
private static class ViewHolder {
public TextView textView;
public ViewHolder(View itemView) {
textView = (TextView)itemView.findViewById(R.id.text);
}
}
}
RecyclerView 的 Adapter 代码:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<String> mItems;
private LayoutInflater mInflater;
public RecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mItems = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String item = mItems.get(position);
holder.textView.setText(item);
}
@Override
public int getItemCount() {
return mItems.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
}
}
}
与我们在 ListView 中使用的 Adapter 不同,RecyclerViewAdapter 扩展了 RecyclerView.Adapter,其中 T 表示 ViewHolder。我们指定了自己实现的 ViewHolder,这是我们在第一步中创建的类。
在 onBindViewHolder() 方法中,我们更新 ViewHolder 中的数据。它非常类似于 getView(),除了我们需要将数据直接注入ViewHolder。
3. 更新 Activity/Fragment
要在 RecyclerView 中使用 Adapter,我们需要像 ListView 一样检索 RecyclerView,并设置它的 Adapter。 RecyclerView 也需要设置一个 LayoutManager 来控制它的布局,否则会难以处理元素的位置。
以上为 ListView 代码:
public class MainActivity extends Activity {
private ListView mListView;
private ListAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.list);
mAdapter = new ListAdapter(this, generateItemsList());
mListView.setAdapter(mAdapter);
}
private List<String> generateItemsList() {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 1000; ++i) {
list.add("Item " + i);
}
return list;
}
}
以下为 RecyclerView 代码:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerViewAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new RecyclerViewAdapter(this, generateItemsList());
mRecyclerView.setAdapter(mAdapter);
}
private List<String> generateItemsList() {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 1000; ++i) {
list.add("Item " + i);
}
return list;
}
}
在以上代码中,我们使用 mRecyclerView.setLayoutManager() 方法设置了一个 LinearLayoutManager,这是官方提供的一个特定的 LayoutManager。 RecyclerView 可以使用其他类型的LayoutManager(如 GridLayoutManager 或 StaggeredGridLayoutManager),这取决于你的需求。
现在你已经可以使用 RecyclerView 了! 这不仅提高了性能,而且还提供了更多选择。希望这篇文章能帮助你迁移你的 ListView 到 RecyclerView,并成功地开始使用这个更高级别的组件。