You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓开发:使用ArrayAdapter实现带行列ListView及自定义布局适配问题

解决Android任务应用的两个ListView相关问题

嘿,我来帮你搞定这两个关于ListView和ArrayAdapter的问题!咱一步步来拆解:

一、创建带行列的ListView并使用ArrayAdapter填充数据

要实现带行列的ListView,核心是自定义行布局+自定义ArrayAdapter,因为默认的ArrayAdapter只能适配单个TextView的行。具体步骤如下:

1. 编写行布局(表格样式的列表项)

在layout文件夹下新建list_item_task.xml,用水平LinearLayout来模拟“列”,每个列对应一个数据字段(比如任务标题、状态、创建时间):

<?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"
    android:padding="8dp"
    android:divider="@android:color/darker_gray"
    android:dividerHeight="1dp">

    <!-- 第一列:任务标题 -->
    <TextView
        android:id="@+id/tv_task_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="16sp"
        android:textStyle="bold"/>

    <!-- 第二列:任务状态 -->
    <TextView
        android:id="@+id/tv_task_status"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="14sp"
        android:gravity="center"/>

    <!-- 第三列:创建时间 -->
    <TextView
        android:id="@+id/tv_task_time"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="14sp"
        android:gravity="end"/>
</LinearLayout>

这里用layout_weight让三个TextView平分宽度,模拟表格的三列效果,还加了分割线让行列更清晰。

2. 准备数据源(自定义Task类)

先定义你的Task实体类,包含任务的各个属性,记得加getter方法:

public class Task {
    private int id;
    private String title;
    private String status;
    private String createTime;

    public Task(int id, String title, String status, String createTime) {
        this.id = id;
        this.title = title;
        this.status = status;
        this.createTime = createTime;
    }

    // Getter方法
    public String getTitle() { return title; }
    public String getStatus() { return status; }
    public String getCreateTime() { return createTime; }
}

3. 自定义ArrayAdapter适配Task类

默认的ArrayAdapter无法处理多控件的行,所以要自定义一个继承自ArrayAdapter<Task>的类,重写getView方法来绑定数据:

public class TaskAdapter extends ArrayAdapter<Task> {
    private LayoutInflater inflater;

    public TaskAdapter(Context context, List<Task> taskList) {
        super(context, 0, taskList);
        inflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 复用convertView优化性能
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_item_task, parent, false);
        }

        // 获取当前任务对象
        Task currentTask = getItem(position);

        // 绑定数据到控件
        TextView tvTitle = convertView.findViewById(R.id.tv_task_title);
        TextView tvStatus = convertView.findViewById(R.id.tv_task_status);
        TextView tvTime = convertView.findViewById(R.id.tv_task_time);

        tvTitle.setText(currentTask.getTitle());
        tvStatus.setText(currentTask.getStatus());
        tvTime.setText(currentTask.getCreateTime());

        return convertView;
    }
}

4. 在MainActivity中绑定ListView和Adapter

在activity_main.xml里添加ListView(你的代码开头已经是RelativeLayout,直接加进去就行):

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listView_tasks"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

然后在MainActivity里初始化数据、Adapter并设置给ListView:

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private TaskAdapter taskAdapter;
    private List<Task> taskList;

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

        listView = findViewById(R.id.listView_tasks);

        // 模拟测试数据
        taskList = new ArrayList<>();
        taskList.add(new Task(1, "学习ArrayAdapter", "进行中", "2024-05-20"));
        taskList.add(new Task(2, "设计SQL数据库", "未开始", "2024-05-21"));
        taskList.add(new Task(3, "测试任务应用", "已完成", "2024-05-19"));

        // 初始化Adapter并设置给ListView
        taskAdapter = new TaskAdapter(this, taskList);
        listView.setAdapter(taskAdapter);
    }
}

二、解决自定义Task类与ArrayAdapter结合、表格布局的难点

刚才的步骤其实已经覆盖了这部分需求,这里再重点强调几个容易踩坑的点:

  • 为什么要自定义ArrayAdapter?:默认的ArrayAdapter只能将数据绑定到单个TextView(比如android.R.layout.simple_list_item_1),而我们的行布局有多个控件,必须重写getView来手动绑定每个控件的数据。
  • 表格样式的关键:用layout_weight让每个列的控件平分宽度,或者固定宽度,同时给ListView或行布局加分割线,让行列更像表格。
  • 性能优化:复用convertView避免重复加载布局,还可以用ViewHolder模式进一步优化(如果数据量很大的话),比如:
    static class ViewHolder {
        TextView tvTitle;
        TextView tvStatus;
        TextView tvTime;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_item_task, parent, false);
            holder = new ViewHolder();
            holder.tvTitle = convertView.findViewById(R.id.tv_task_title);
            holder.tvStatus = convertView.findViewById(R.id.tv_task_status);
            holder.tvTime = convertView.findViewById(R.id.tv_task_time);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
    
        Task currentTask = getItem(position);
        holder.tvTitle.setText(currentTask.getTitle());
        holder.tvStatus.setText(currentTask.getStatus());
        holder.tvTime.setText(currentTask.getCreateTime());
    
        return convertView;
    }
    
    这样不用每次都调用findViewById,提升ListView滚动的流畅度。

如果后续要结合SQL数据库,只需要把模拟的taskList换成从数据库查询出来的数据即可,Adapter的逻辑不用改,非常灵活。

内容的提问来源于stack exchange,提问作者dongerpep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:31:10