自定义 ListView 不显示任何内容

Custom ListView doesn't show anything

我正在尝试在 ListView 的左侧填充字符串(食品名称),在右侧填充项目计数。在学习了一些教程之后,我制作了一个 CustomAdapter class (见下文)扩展了 BaseAdapter ,在那里我可以看到(通过打印语句)至少 getCount() 方法被调用,但我的 getView() 方法没有被调用,我的 ListView 也没有出现在我的应用程序中。我究竟做错了什么?我认为这是因为我不知道如何在正确的位置制作 getView() 运行 。当我使用带有字符串数组的普通 ArrayAdapter 时,它工作正常。

这是我尝试在 MainActivity 中填充 ListView 的方式 class:

CustomAdapter customAdapter = new CustomAdapter();
ListView lv1 = (ListView) findViewById(R.id.listView);
lv1.setAdapter(customAdapter);
customAdapter.notifyDataSetChanged();

现在,这是我的 CustomAdapter class:

import java.util.ArrayList;
import java.util.List;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class CustomAdapter extends BaseAdapter {

    List<foodItem> mItemList = getDataForListView();

    public CustomAdapter(List<foodItem> list){
        this.mItemList = list;
        // tried this as an alternative
    }

    @Override
    public int getCount() {
        return mItemList.size();
    }

    @Override
    public foodItem getItem(int arg0) {
        return mItemList.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int arg0, View arg1, ViewGroup parent) {
        System.out.println("Item list size: " + mItemList.size()); // doesn't show anything in console

        if(arg1==null) {
            LayoutInflater inflater = (LayoutInflater) LayoutInflater.from(parent.getContext());
            arg1 = inflater.inflate(R.layout.listrow, parent ,false);
// R.layout.listrow is an XML file defined and formatted at 60sp tall
// as that is how tall I want each item in the ListView to be
        }

        TextView foodItem = (TextView)arg1.findViewById(R.id.foodTitle);
        TextView likeCount = (TextView)arg1.findViewById(R.id.likeCount);
        foodItem i = mItemList.get(arg0);
        foodItem.setText(i.getItem());
        likeCount.setText(i.getLikes());

        return arg1;
    }

    public List<foodItem> getDataForListView() {

        List<foodItem> itemList = new ArrayList<foodItem>();
// Test method populating with some data
        for(int i=0; i<50; i++) {
            itemList.add(new foodItem(i, "Item " + i));
        }
        return itemList;
    }
}

我也尝试添加自己的构造函数,但结果是一样的。任何帮助将不胜感激!

编辑:我的主要布局 activity:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.inventoryList.MainActivity" >

    <ListView
        android:id="@+id/foodOptions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp" />

</RelativeLayout>

最后,这是我的 listrow.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="60sp"
    android:orientation="horizontal"
    android:padding="5sp" >

    <TextView
        android:id="@+id/foodTitle"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:textSize="12sp"
        android:text="123"
        android:gravity="center" />

    <TextView
        android:id="@+id/likeCount"
        android:layout_width="12sp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:text="@+string/likeCount"
        android:textSize="10sp"
        tools:ignore="SmallSp" />

</RelativeLayout>

您将在 getDataForListView 中重新声明 List<foodItem> itemList。这会覆盖成员变量。改为

itemList = new ArrayList<>();

您还应该在构造函数中执行此操作,而不是在成员方法中执行此操作,并且在成员变量前加上 m(因此 mItemList)是一种很好的风格,有助于防止出现此问题。所以一起:

private class CustomAdapter extends BaseAdapter {
    private List<foodItem>  mItemList; //camel case isn't usually applied to classes os this should be FoodItem

    public CustomAdapter() {
        mItemList = new ArrayList<>();
        for (...) {
            ...
        }
    }

    ...
}

更好的是,将 List 传递给构造函数:

private class CustomAdapter extends BaseAdapter {
    private List<FoodItem> mItemList;

    public CustomAdapter(List<FoodItem> itemList) {
        mItemList = itemList;
    }
    ...
}

为您的适配器实现一个构造函数,以便您可以将项目列表传递给它:

public CustomAdapter(List<foodItem> itemList) {
    this.itemList = itemList;
}

预先创建您的列表并将其传递给适配器构造函数:

ArrayList<foodItem> items = buildItemsList();
CustomAdapter customAdapter = new CustomAdapter(items);
ListView lv1 = (ListView) findViewById(R.id.listView);
lv1.setAdapter(customAdapter);

如果您需要可变适配器,请实现一个方法(在适配器中)以添加项并在之后通知数据集更改:

public void add(foodItem item) {
    itemList.add(item);
    notifyDataSetChanged();
}

您可以执行相同的操作来删除和更新项目,只需记住通知更改以便刷新列表视图。

我修好了。我的 Main Activity 有三个选项卡,我为每个选项卡设置了一个选项卡侦听器来更改适配器中的内容。我原以为这些选项卡侦听器不会在启动应用程序时被调用,但显然事实并非如此。因此,根据我在测试中注释掉的内容,我被调用了 setAdapter() 并传入了一个空适配器。

感谢大家的帮助,抱歉,原来是我没有提供的代码错误。

我遇到了类似的问题,我把

解决了
adapter.notifyDataSetChanged();

在我的 try-catch 块之外