Android ListView 显示的项目与 Adapter 获取的项目不同

Android ListView show different items than Adapter get

我正在尝试使用我自己的自定义适配器来填充我的 ListView。我试图显示列表中的 24 个不同元素,但我得到的只是从 0 到 6 的七个元素,它们一遍又一遍地显示 24(ListView 中显示的所有项目的数量)。所以它从 0 开始显示元素,在 6 结束并重新开始,直到 ListView 有 24 个元素。我哪里弄错了?

来自Activity的一段代码:

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_day_plan);

    tasksListView = (ListView) findViewById(R.id.tasks_list_view);
    tasksList = new ArrayList<Task>();

    for (int h = 0; h < 24; h++) {

        Task task = new Task(h, 0, h + 1, 0, String.valueOf(h), null);
        tasksList.add(task);
    }
    customAdapter = new ListAdapter(this, R.layout.task, tasksList);
    tasksListView.setAdapter(customAdapter);

}

我的自定义适配器:

public class ListAdapter extends ArrayAdapter<Task>{

private ArrayList<Task> tasks;

public ListAdapter(Context context, int resource, ArrayList<Task> tasks) {

    super(context, resource, tasks);
    this.tasks = tasks;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View v = convertView;

    if (v == null) {

        LayoutInflater vi;
        vi = LayoutInflater.from(getContext());
        v = vi.inflate(R.layout.task, null);

        Task task = tasks.get(position);

        if (task != null) {

            TextView time_header = (TextView) v.findViewById(R.id.time_header);
            TextView task_header = (TextView) v.findViewById(R.id.task_header);

            if (time_header != null) {

                time_header.setText(task.timeToString());
            }

            if (task_header != null) {

                task_header.setText(task.getHeader());
            }
        }
    }

    return v;
}


public ArrayList<Task> getItems() {

    return tasks;
}
}

任务class:

public class Task {

private int startHour;
private int startMinute;
private int endHour;
private int endMinute;
private String header;
private String description;

public Task(int sH, int sM, int eH, int eM, String head, String desc) {

    this.startHour = sH;
    this.startMinute = sM;
    this.endHour = eH;
    this.endMinute = eM;
    if (head == null) {

        this.header = "[wolne]";
    } else {

        this.header = head;
    }

    if (desc == null) {

        this.description = "";
    } else {

        this.description = desc;
    }

}

public String getHeader() {

    return header;
}

public String timeToString() {

    String time = startHour + ":" + 
            startMinute + 
            " - " + 
            endHour + 
            ":" + 
            endMinute;
    return time;
}
}

和随机行布局:

<?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="match_parent"
    android:padding="5dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/time_header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp"
        android:textSize="12sp" 
        android:text="@string/exampe_time"/>

    <TextView android:id="@+id/task_header"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:singleLine="true"
        android:textSize="15sp"
        android:text="@string/lorem_ipsum"/>

</LinearLayout>

我尝试调试应用程序,我检查过,项目在 ArrayList 和适配器中是正确的,所以我猜问题一定是在适配器中的某个地方...

您再次使用,已创建convertView,但您没有为当前位置设置数据。

最简单的解决方案

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View v = convertView;

    if (v == null) {

        LayoutInflater vi;
        vi = LayoutInflater.from(getContext());
        v = vi.inflate(R.layout.task, null);
    }
    Task task = tasks.get(position);

    if (task != null) {

        TextView time_header = (TextView) v.findViewById(R.id.time_header);
        TextView task_header = (TextView) v.findViewById(R.id.task_header);

        if (time_header != null) {

            time_header.setText(task.timeToString());
        }

        if (task_header != null) {

            task_header.setText(task.getHeader());
        }
    }


    return v;
}

最佳方案

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder viewHolder;

    if (convertView == null) {
        //Initialize yout layoutInflater in your adapter constructor
        convertView = vi.inflate(R.layout.task, null);
        viewHolder = new ViewHolder();
        viewHolder.task_header = (TextView) v.findViewById(R.id.time_header);
        viewHolder.time_header = (TextView) v.findViewById(R.id.task_header);
        convertView.setTag(viewHolder);
    } else
        viewHolder = (ViewHolder) convertView.getTag();

    Task task = tasks.get(position);

    if (task != null) {

        viewHolder.time_header.setText(task.timeToString());
        viewHolder.task_header.setText(task.getHeader());
    }
    return convertView;
}

static class ViewHolder {
    TextView time_header;
    TextView task_header;
}