2015-02-06 46 views
2

我试图用左边的字符串(食物项目名称)和右边的项目计数编号填充ListView。我做了一个CustomAdapter类(见下文),它在继续下面的一些教程之后扩展了BaseAdapter,我可以看到(通过打印语句)至少调用了getCount()方法,但我的getView()方法没有被调用,我的ListView也没有没有出现在我的应用程序中。我究竟做错了什么?我认为这是因为我不知道如何使getView()在正确的地方运行。当我使用正常的ArrayAdapter和一串字符串时,它工作正常。自定义ListView不显示任何东西

这里是我试图在我的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> 
+1

在调用setAdapter之后是否将任何项目添加到适配器? – Harry 2015-02-06 17:02:27

+0

在调用'lv1.setAdapter(customAdapter);' – 2015-02-06 17:04:00

+0

后'listrow.xml'和您的活动布局后,尝试调用'customAdapter.notifyDataSetChanged()'。 – njzk2 2015-02-06 17:31:17

回答

1

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

感谢您的帮助,遗憾的是,事实证明这是我没有提供的代码中的错误。

1

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

是的,但不是,因为该方法返回一个影响到成员变量的列表 – njzk2 2015-02-06 17:21:33

+0

是的,很好的catch – seiterm 2015-02-06 17:25:43

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

你可以做同样的删除和更新项目,只记得通知更改,以便刷新列表视图。

+0

这与OP经历的问题有什么关系? – njzk2 2015-02-06 17:32:05

+1

我很确定造成空列表的原因是因为他没有调用notifyDatasetChanged,但由于我没有足够的信誉,我不能评论要求他检查“getCount”是否返回零。所以,我只能回答,规则说必须用答案来解决问题。 根据我的经验,我发布了什么是推荐的方式来处理列表,避免像他遇到的问题。 – 2015-02-06 17:39:37

+0

@JuanjoVega getCount()每次运行时返回50。我按照你的说法加入了一个构造函数,并在设置适配器并更新了上面的代码后,将该调用添加到notifyDataSetChanged()。为什么可能getView(...)永远不会被调用?我在该方法中的打印语句永远不会被打中,但似乎这种方法必须发生,以填充listview。 – MikeM 2015-02-06 19:40:42

1

我有类似的问题,我通过把我try-catch块的

adapter.notifyDataSetChanged(); 

OUTSIDE解决。