自定义ListView没有显示任何内容

时间:2015-02-06 16:59:06

标签: java android listview custom-adapter

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

以下是我在MainActivity类中尝试填充ListView的方法:

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

现在,这是我的CustomAdapter类:

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;
    }
}

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

编辑:我的主要活动的布局:

<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>

4 个答案:

答案 0 :(得分:1)

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

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;
    }
    ...
}

答案 1 :(得分:1)

我修好了。我的主要活动有三个选项卡,每个选项卡都设置了一个标签监听器,用于更改适配器中的内容。我曾假设在启动应用程序时不会调用这些选项卡侦听器,但显然这不是真的。因此,根据我在测试中注释掉的内容,我被称为setAdapter()并传入一个空的适配器。

感谢大家的帮助,对不起,我发现这是我未提供的代码中的错误。

答案 2 :(得分:1)

我遇到了类似的问题,我解决了

adapter.notifyDataSetChanged();
我的try-catch块的

OUTSIDE

答案 3 :(得分:0)

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

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();
}

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