2015-02-06 124 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解決。