getView() 从不调用自定义适配器

getView() never called on custom adapter

我知道其他人已经问过这个问题,但我已经查看了其他解决方案,但仍然无法正常工作。

适配器代码:

private class CustomTextAndImageAdapter extends ArrayAdapter<String> {
    private Context context;
    private Activity activity;
    private ArrayList<String> timeArrayList;
    private ArrayList<Bitmap> weatherIconArrayList;
    private ArrayList<String> descriptionArrayList;
    private ArrayList<String> tempArrayList;
    private ArrayList<String> popArrayList;
    private ArrayList<String> windSpeedArrayList;

    public final void setTimeArrayList(ArrayList<String> timeArrayList)
    {
        this.timeArrayList = timeArrayList;
    }

    public final void setDescriptionArrayList(ArrayList<String> descriptionArrayList)
    {
        this.descriptionArrayList = descriptionArrayList;
    }

    public final void setTempArrayList(ArrayList<String> tempArrayList)
    {
        this.tempArrayList = tempArrayList;
    }

    public final void setPopArrayList(ArrayList<String> popArrayList)
    {
        this.popArrayList = popArrayList;
    }

    public final void setWindSpeedArrayList(ArrayList<String> windSpeedArrayList)
    {
        this.windSpeedArrayList = windSpeedArrayList;
    }

    public final void setWeatherIconArrayList(ArrayList<Bitmap> weatherIconArrayList)
    {
        this.weatherIconArrayList = weatherIconArrayList;
    }

    public CustomTextAndImageAdapter(Context context, Activity activity, int resource)
    {
        super(context, resource);
        this.context = context;
        this.activity = activity;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent)
    {
        Log.d(Constants.LOG_TAG, "getView() method called");
        LayoutInflater inflater = activity.getLayoutInflater();
        View rowView= inflater.inflate(R.layout.itemlistrow, null, false);

        TextView timeTextView = (TextView)rowView.findViewById(R.id.time);
        timeTextView.setText(timeArrayList.get(position));
        Log.d(Constants.LOG_TAG, "Time text view text = " + timeArrayList.get(position));

        ImageView iconImageView = (ImageView) rowView.findViewById(R.id.weatherIcon);
        iconImageView.setImageBitmap(weatherIconArrayList.get(position));

        TextView descriptionTextView = (TextView)rowView.findViewById(R.id.description);
        descriptionTextView.setText(descriptionArrayList.get(position));

        TextView tempTextView = (TextView)rowView.findViewById(R.id.temp);
        tempTextView.setText(tempArrayList.get(position));

        TextView popTextView = (TextView)rowView.findViewById(R.id.pop);
        popTextView.setText(popArrayList.get(position));

        TextView windSpeedTextView = (TextView)rowView.findViewById(R.id.windSpeed);
        windSpeedTextView.setText(windSpeedArrayList.get(position));

        return rowView;
    }
}

列表项布局(itemlistrow.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/time" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/weatherIcon"
                />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Sunny"
                android:id="@+id/description"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="11 C"
                android:id="@+id/temp"
                />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text = "Rain:"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text = "Wind:"
                />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id = "@+id/pop"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text = "@+id/windSpeed"
                />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

在其他一些解决方案中,它提到覆盖 getCount()。这是我做错了吗?如果是这样,我怎么知道要为 getCount() 输入什么,因为使用了多个不同的 ArrayList。是否选择其中一个,因为它们的长度都相同,例如timeArrayList.size()?

这不是使用从多个 ArrayList 填充数据的适配器来填充 ListView 的好方法。在 Android 中显示列表的情况下,通常我们使用单一来源的数据集传递给适配器。

所以在你的情况下,当你调用 notifyDatasetChanged 时,据我猜测,它不应该在列表中正确生效。

notifyDatasetChanged 基本上调用适配器的 getCount 函数并检查与适配器关联的 ArrayList 的大小是否已更改。如果 ArrayList 的大小发生变化,它会刷新 ListView 并调用 getView 函数。

在你的情况下,我没有看到任何 getCount 功能。 getCount 通常 returns 与适配器关联的 ArrayList 的大小。

所以我建议使用单个 ArrayList 传递给适配器。您可以合并多个 ArrayList,也可以在您的情况下使用一个连接的 HashMap。您可以决定如何将数据集的单个列表传递给适配器以将它们填充到 ListView 中。

像这样使用多个 ArrayList 对象违背了使用 ArrayAdapter 的目的,后者的想法是拥有单一的项目来源。更不用说现在的代码看起来一点也不好看。

我建议首先创建一个 Weather 对象来保存您的数据:

public class Weather {
    private String time;
    private Bitmap weatherIcon;
    private String description;
    private String temp;
    private String pop;
    private String windSpeed;

    // build object here, provide getters, etc....
    .....
}

比起你的 adapter 可以转换成更简单的东西,像这样:

private class CustomTextAndImageAdapter extends ArrayAdapter<Weather>
{
    private LayoutInflater inflater;

    public CustomTextAndImageAdapter(Context context, Activity activity, int resource, List<Weather> items)
    {
        super(context, resource, items);
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent)
    {
        View rowView= inflater.inflate(R.layout.itemlistrow, null, false);

        TextView timeTextView = (TextView)rowView.findViewById(R.id.time);
        timeTextView.setText(getItem(position).getTime());

        ImageView iconImageView = (ImageView) rowView.findViewById(R.id.weatherIcon);
        iconImageView.setImageBitmap(getItem(position).getWeatherIcon());

        ........

        return rowView;
    }
}

主要区别在于它现在是 ArrayAdapter<Weather> 并且您直接在适配器的 constructor 中传递参数。适配器的用户现在只需调用 1 个构造函数,而不是之前必须调用的所有最终方法。

另一个主要区别是您将 items 列表传递给超级 class。现在你的 adapter 知道它的大小(内部 getCount() 将是 == items.size())所以 getView() 将被适当地调用。

作为最后的想法 - adapter 仍然没有使用 ViewHolder 模式,您应该完全实现它!已经有很多关于它的帖子,所以只要搜索一下,你就会找到它。