Android:使用自定义适配器显示listview-过滤arraylist
我有一个特殊的问题。我正在分析一家餐馆的菜单卡。他们有英语和德语版本。我有一个类FoodItem为:Android:使用自定义适配器显示listview-过滤arraylist,android,android-listview,android-arrayadapter,Android,Android Listview,Android Arrayadapter,我有一个特殊的问题。我正在分析一家餐馆的菜单卡。他们有英语和德语版本。我有一个类FoodItem为: public class FoodItem { private int foodClass; private String foodType; private String foodName; private String foodCost; private String hauptBeilage; private String salat; } 现在
public class FoodItem {
private int foodClass;
private String foodType;
private String foodName;
private String foodCost;
private String hauptBeilage;
private String salat;
}
现在,我使用Jsoup下载了一个fooditems的arraylist。我使用字符串foodType
分隔德语和英语菜单
我想在开头列出德语菜单。但是,我也把英文菜单附在了清单上。我应该如何处理这个问题
我的下载线程(Jsoup)是:
在我的活动中,我有:
handler = new android.os.Handler() {
@Override
public void handleMessage(Message msg) {
foodItemAdapter.notifyDataSetChanged();
}
};
如果我在getDailyGerman()之后通过处理程序发送消息
然后我得到一个非法状态异常
,表示适配器的内容已更改,但listview未更新
我的适配器代码:
public FoodItemAdapter(Context context, int textViewResourceId, ArrayList<FoodItem> FoodItemArg) {
super(context, textViewResourceId, FoodItemArg);
FoodItemAdapter.foodItems = FoodItemArg;
this.setNotifyOnChange(false);
// if(FoodItemAdapter.foodItems == null)
// Log.i("Adapter", "Problem Inside Adapter Constructor");
}
//=========================public methods============================
public static ArrayList<FoodItem> getDailyEnglishFoodItems()
{
ArrayList<FoodItem> returnList = new ArrayList<FoodItem>();
for(FoodItem eachItem : FoodItemAdapter.foodItems)
{
if(eachItem.getFoodClass() == 1)
{
Log.i("Adapter" , "Adding English Daily Food : " + eachItem.getFoodName());
returnList.add(eachItem);
}
}
return returnList;
}
public static ArrayList<FoodItem> getDailyGermanFoodItems()
{
ArrayList<FoodItem> returnList = new ArrayList<FoodItem>();
for(FoodItem eachItem : FoodItemAdapter.foodItems)
{
if(eachItem.getFoodClass() == 2)
{
Log.i("Adapter" , "Adding German Daily Food : " + eachItem.getFoodName());
returnList.add(eachItem);
}
}
return returnList;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/*
* Describes each view in the list view.
* Get the question and find the question text, timestamp and the votes.
* Show them in the textview which is a part of the listview.
*/
View v = convertView;
FoodItem foodItem =(FoodItem) FoodItemAdapter.foodItems.get(position);
if(foodItem == null)
{
Log.i("Adapter", "Null Food Item");
}
int colorPos = 0;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.fooditem_row, null);
colorPos = position % colors.length;
}
public FoodItemAdapter(上下文、int textViewResourceId、ArrayList FoodItemArg){
super(上下文、textViewResourceId、FoodItemArg);
FoodItemAdapter.foodItems=FoodItemArg;
this.setNotifyOnChange(false);
//if(FoodItemAdapter.foodItems==null)
//Log.i(“适配器”,“适配器构造函数内部的问题”);
}
//========================================公共方法============================
公共静态数组列表getDailyEnglishFoodItems()
{
ArrayList returnList=新建ArrayList();
for(FoodItem eachItem:FoodItemAdapter.foodItems)
{
if(eachItem.getFoodClass()==1)
{
Log.i(“适配器”,“添加英语日常食品:”+eachItem.getFoodName());
返回列表。添加(每个条目);
}
}
退货清单;
}
公共静态数组列表getDailyGermanFoodItems()
{
ArrayList returnList=新建ArrayList();
for(FoodItem eachItem:FoodItemAdapter.foodItems)
{
if(eachItem.getFoodClass()==2)
{
Log.i(“适配器”,“添加德国日常食品:”+eachItem.getFoodName());
返回列表。添加(每个条目);
}
}
退货清单;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
/*
*描述列表视图中的每个视图。
*获取问题并找到问题文本、时间戳和投票。
*在作为listview一部分的textview中显示它们。
*/
视图v=转换视图;
FoodItem FoodItem=(FoodItem)FoodItemAdapter.foodItems.get(position);
if(foodItem==null)
{
Log.i(“适配器”、“空食品项目”);
}
int colorPos=0;
if(convertView==null){
LayoutFlater充气器=(LayoutFlater)this.getContext().getSystemService(Context.LAYOUT\u充气器\u服务);
v=充气机。充气(R.layout.fooditem_行,空);
colorPos=位置%colors.length;
}
请帮助我,因为我在这一点上被困了3天。谢谢。我在添加项目并拨打电话后也遇到了同样的问题 UI中的notifyDataSetChanged()
线程问题已解决根据我对您问题的理解,您希望将英语项目置于列表的顶部,然后是德语项目。您可以使用Collection.sort方法并使用特定的比较器来完成手头的任务 例如:
final List<FoodItem> combinedList = getDailyGermanFoodItems();
combinedList.addAll(getDailyEnglishFoodItems());
Collections.sort(compinedList, new FoodItemComparator());
//then you call the handler to update the adapter and the listView
handler.post(new Runnable(){
public void run(){
FoodItemAdapter adapter = new FoodItemAdapter(activity.this, layout, combinedList);
listView.setAdapter(adapter);
}});
}
假设foodType值保证仅为德语/英语。
此外,您还必须在FoodItem类中具有getter函数,以便比较器可以访问它:
Class FoodItem
.......
public String getFoodType(){
return foodType;
}
编辑
如果要单独显示每个列表,请将这两个列表存储在活动对象中,然后当用户选择语言(英语/德语)时:
请列出您的适配器代码,您的getDailyGerman getDailyEnglishfunctions@Mr.Me我已添加适配器代码。@Mr.Me hi。。你有什么线索吗?我被困了很长时间。你怎么知道下载完成了?我的意思是,如果在将项添加到适配器之前调用notifyDataSetChanged(),我们仍然会得到一个空列表,对吗?如果在插入所有数据后调用notifyDataSetChanged(),则我的列表将同时显示英语和德语数据。您好。。这是正确的。但是,我只想显示德国数据。我有一个菜单,用户可以在其中选择更改语言。那么,我应该只显示英文数据。现在,两者都合并到listview中,而我只希望出现一种类型。
public class FoodItemComparatorimplements Comparator<FoodItem>{
public int compare(FoodItem item1, item2) {
String foodType1 = item1.getFoodType();
String foodType2 = item2.getFoodType();
if (foodType1.equals(foodType2))
return 0;
if (foodType1.equals("English"))
return 1;
if (foodType2.equals("English))
return -1;
return foodType1.compareTo(foodType2);
}
Class FoodItem
.......
public String getFoodType(){
return foodType;
}
FoodItemAdapter adapter = new FoodItemAdapter(activity.this, layout, germanList);
listView.setAdapter(adapter);