使用Runnable填充ListView - 返回太多

时间:2012-07-07 02:29:53

标签: android arrays listview

我正在组合一个app,它在relativeLayout中有一个listview,里面有几个LinearLayout。所以我有我的适配器,以及将项目放入列表的功能。此函数仅在apps主进程的OnCreate函数中调用,并在线程的runnable中调用。你们都能看到为什么这个东西可能会多次调用添加到我的阵列中的原因吗? (当我只向数组添加一个东西时,for循环被调用数千次。 在主进程的OnCreate方法中:

      array = new ArrayList<Item>(); //The misbehaving array
      ListView lv = (ListView)findViewById(R.id.ItemList);
      this.m_adapter = new ItemAdapter(this, R.layout.Itemlist_item, array);
      lv.setAdapter(this.m_adapter);
      viewItems = new Runnable(){
          @Override
          public void run() {
             getItems();
          }
      };
      Thread thread =  new Thread(null, viewItems, "ListThread");
      thread.start(); 

getItems函数和第二个Runnable:

private void getItems(){
  try{
     //Try Some Stuff
  } 
  catch (Exception e) {
     Log.e("BACKGROUND_PROC", e.getMessage());
  }
  runOnUiThread(returnRes);
}
private Runnable returnRes = new Runnable() {
  @Override 
  public void run() {
    if(array != null && array.size() > 0){
        listAdapter.notifyDataSetChanged();
        //This loop is where I'm seeing the problem
        for(int i=0;i<array.size();i++) {
            listAdapter.add(array.get(i));
        }
    }
  }
};

列表适配器:

  public class ItemAdapter extends ArrayAdapter<Item> {

        public ArrayList<Item> items;
        public ItemAdapter(Context context, int textViewResourceId, ArrayList<Item> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }
        @Override
        public View getView(int position, View conView, ViewGroup parent) {
            View v = conView; //The content view

            if (v == null){
                LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.itemlist_item, null);
            }

            Item o = items.get(position);
            if (o != null){
                TextView name = (TextView)v.findViewById(R.id.item_name);
                if(name != null){
                    name.setText("name:"+o.getItemName());
                }
            }

            return v;

        }

    }

任何帮助都非常感谢。 谢谢, -Chris

1 个答案:

答案 0 :(得分:0)

问题是ListView和其他适用于适配器的UI小部件不允许适配器的内容在其上意外更改。在下次尝试与适配器交互之前,您需要告诉ListView您所做的更改。如果你允许另一个线程修改适配器,或者在主线程上修改它,但在允许其他任何事情发生之前不告诉ListView有关更改,你将随机(由于比赛)获得{{ {1}}关于适配器意外更改。

相反,像这样的东西应该起作用(来自HackBod的帖子here):

ListView

然后使用

填充public class MyAdapter extends BaseAdapter<Item> { private ArrayList<Item> mItems; public int getCount() { return mItems != null ? mItems.size() : 0; } public MyItem getItem(int position) { return mItems.get(i); } /* ... */ }
ListView