教你实现 Android 左右联动列表

在 Android 开发中,实现左右联动的列表是一种常见的需求,通常用于展示两个相互依赖的数据集合,比如分类和对应的子分类。本文将带你一步一步实现这一功能,帮助你掌握基本的 Android 开发技巧。

整体流程

我们将整个实现过程分为几个关键步骤,具体如下表所示:

步骤 描述
1 创建 Android 项目
2 设计布局文件
3 创建数据模型
4 创建适配器
5 设置联动逻辑

步骤详解

第一步:创建 Android 项目

首先使用 Android Studio 创建一个新的项目。选择 Empty Activity 模板,命名为 LinkedListActivity

第二步:设计布局文件

res/layout/activity_linked_list.xml 文件中,设计两个联动的列表。这里我们使用 RecyclerView 来显示数据。代码如下:

<LinearLayout
    xmlns:android="
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/leftRecyclerView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rightRecyclerView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
</LinearLayout>

这里设计了一个水平线性布局,包含两个 RecyclerView,左边的用于显示分类,右边的用于显示对应的子分类。

第三步:创建数据模型

接下来,我们需要创建数据模型。创建一个名为 Category 的类:

public class Category {
    private String name; // 类别名称
    private List<String> subCategories; // 子类别列表

    public Category(String name, List<String> subCategories) {
        this.name = name;
        this.subCategories = subCategories;
    }

    public String getName() {
        return name; // 获取类别名称
    }

    public List<String> getSubCategories() {
        return subCategories; // 获取子类别列表
    }
}

第四步:创建适配器

接下来,我们需要为左右两个 RecyclerView 创建适配器。左侧适配器 CategoryAdapter 用于显示类别,右侧适配器 SubCategoryAdapter 用于显示子类别。

// CategoryAdapter.java
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder> {
    private List<Category> categories; // 存储类别对象
    private OnCategoryClickListener listener; // 点击事件接口

    public interface OnCategoryClickListener {
        void onCategoryClick(int position);
    }

    public CategoryAdapter(List<Category> categories, OnCategoryClickListener listener) {
        this.categories = categories;
        this.listener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(android.R.layout.simple_list_item_1, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.bind(categories.get(position), listener, position); // 绑定数据
    }

    @Override
    public int getItemCount() {
        return categories.size(); // 获取项目数量
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1); // 获取文本视图
        }

        void bind(final Category category, final OnCategoryClickListener listener, final int position) {
            textView.setText(category.getName()); // 设置类别名称
            itemView.setOnClickListener(v -> listener.onCategoryClick(position)); // 设置点击事件
        }
    }
}
// SubCategoryAdapter.java
public class SubCategoryAdapter extends RecyclerView.Adapter<SubCategoryAdapter.ViewHolder> {
    private List<String> subCategories; // 存储子类别对象

    public SubCategoryAdapter(List<String> subCategories) {
        this.subCategories = subCategories;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(android.R.layout.simple_list_item_1, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(subCategories.get(position)); // 绑定数据
    }

    @Override
    public int getItemCount() {
        return subCategories.size(); // 获取项目数量
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1); // 获取文本视图
        }
    }
}

第五步:设置联动逻辑

接下来需要在主活动中连接两个适配器,并实现联动逻辑。

// LinkedListActivity.java
public class LinkedListActivity extends AppCompatActivity {
    private RecyclerView leftRecyclerView;
    private RecyclerView rightRecyclerView;
    private CategoryAdapter categoryAdapter;
    private SubCategoryAdapter subCategoryAdapter;
    private List<Category> categories; // 存储类别列表

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linked_list);

        leftRecyclerView = findViewById(R.id.leftRecyclerView);
        rightRecyclerView = findViewById(R.id.rightRecyclerView);

        // 初始化数据
        categories = new ArrayList<>();
        categories.add(new Category("食物", Arrays.asList("水", "面包", "水果")));
        categories.add(new Category("饮料", Arrays.asList("牛奶", "果汁", "可乐")));

        categoryAdapter = new CategoryAdapter(categories, position -> {
            // 响应类别点击事件,更新子类别
            updateSubCategoryList(position);
        });

        leftRecyclerView.setAdapter(categoryAdapter);
        leftRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        subCategoryAdapter = new SubCategoryAdapter(new ArrayList<>());
        rightRecyclerView.setAdapter(subCategoryAdapter);
        rightRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    private void updateSubCategoryList(int position) {
        // 更新右侧子类别列表
        List<String> subCategories = categories.get(position).getSubCategories();
        subCategoryAdapter = new SubCategoryAdapter(subCategories);
        rightRecyclerView.setAdapter(subCategoryAdapter);
    }
}

类图

下面是实现过程中使用的类图,展示了类别及其子类别的结构。

classDiagram
    class Category {
        +String name
        +List<String> subCategories
        +String getName()
        +List<String> getSubCategories()
    }
    
    class CategoryAdapter {
        +List<Category> categories
        +void onBindViewHolder(ViewHolder holder, int position)
    }

    class SubCategoryAdapter {
        +List<String> subCategories
        +void onBindViewHolder(ViewHolder holder, int position)
    }

流程图

以下是整个联动流程的图示:

journey
    title 联动列表操作流程
    section 用户选择类别
      用户点击左侧类别: 5: 用户
    section 更新子类别
      更新右侧子类别列表: 5: 系统

结语

通过以上步骤,我们成功实现了一个简单的 Android 左右联动列表。这个案例展示了如何将两个 RecyclerView 联动,使用户在选择一侧的类别时,另一侧能够动态更新对应的子类别。你可以在此基础上扩展功能,比如为类别增加图片、为子类别增加点击事件处理等。希望这篇文章能帮助你更好地理解 Android 开发的基本概念,也期待你在技术道路上不断学习与成长!