2012-07-07 34 views
0

在下面的代码中,我试图创建一个ListActivity。 此列表中的元素正在由自定义ArrayAdapter - OrderAdapter填充。Android:AsyncTask UI更新问题

所有的元素获取机制都在AsyncTask类中。 我可以设置m_adapter中的元素,但无法更新列表的UI。

活动正在关闭。

代码:

public class SoftwarePassionView extends ListActivity { 

    private ProgressDialog m_progressDialog = null; 
    private ArrayList<Order> m_orders = null; 
    private OrderAdapter m_adapter; // Defined Below 
    private Runnable viewOrders; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     try { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.softwarepassionview); 
      m_adapter = new OrderAdapter(SoftwarePassionView.this, 
        R.layout.row, m_orders); 

      new AsyncOperation().execute(); 

     } catch (Exception e) { 
      Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); 
     } 
    } 

    public class OrderAdapter extends ArrayAdapter<Order> { 

     private ArrayList<Order> items; 

     public OrderAdapter(Context context, int textViewResourceId, 
       ArrayList<Order> elements) { 
      super(context, textViewResourceId, elements); 
      this.items = elements; 
     } 

     public void setList(ArrayList<Order> items) { 
      this.items = new ArrayList<Order>(); 
      this.items.addAll(items); 

     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      super.getView(position, convertView, parent); 
      View v = convertView; 
      try { 
       if (v == null) { 
        LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        v = vi.inflate(R.layout.row, null); 
       } 
       Order o = items.get(position); 
       if (o != null) { 
        TextView orderName = (TextView) v 
          .findViewById(R.id.topText); 
        TextView orderStatus = (TextView) v 
          .findViewById(R.id.bottomText); 
        orderName.setText(o.getOrderName()); 
        orderStatus.setText(o.getOrderStatus()); 
       } 
      } catch (Exception e) { 
       Toast.makeText(SoftwarePassionView.this, e.toString(), 
         Toast.LENGTH_SHORT).show(); 
      } 
      return v; 
     } 
    } 

    public class AsyncOperation extends AsyncTask { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected Object doInBackground(Object... params) { 
      getOrders(); 
      if (m_orders != null && m_orders.size() > 0) { 
       m_adapter.setList(m_orders); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Object result) { 
      super.onPostExecute(result); 
      m_adapter.notifyDataSetChanged(); 
      setListAdapter(m_adapter); 
     } 
    } 

    private void getOrders() { 
     try { 
      m_orders = new ArrayList<Order>(); 
      Order o1 = new Order(); 
      o1.setOrderName("T-Shirt Purchase"); 
      o1.setOrderStatus("Dispatched"); 
      Order o2 = new Order(); 
      o2.setOrderName("Deo Purchase"); 
      o2.setOrderStatus("Pending"); 
      m_orders.add(o1); 
      m_orders.add(o2); 

      Thread.sleep(2000); 
     } catch (Exception e) { 
      Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); 
     } 
    } 

} 
+0

删除super.onPostExecute()和尝试,否则再次定义adater并将其设置列表视图。 – 2012-07-07 07:54:23

+0

都尝试过。对于第二点,我创建了一个新的适配器'OrderAdapter adapter = new OrderAdapter(SoftwarePassionView.this,R.layout.row2,m_orders); \t \t \t setListAdapter(adapter);'in' onPostExecute'。不工作 – reiley 2012-07-07 08:27:19

回答

1

后,我有固定的错误现在尝试

public class SoftwarePassionView extends ListActivity { 

private ProgressDialog m_progressDialog = null; 
private ArrayList<Order> m_orders = new ArrayList<Order>(); //why you have putting it null? 
private OrderAdapter m_adapter; // Defined Below 
private Runnable viewOrders; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    try { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.softwarepassionview); 
     m_adapter = new OrderAdapter(SoftwarePassionView.this, 
       R.layout.row, m_orders); 
     setListAdapter(m_adapter); // you are getting npe as you have not init "m_orders" 
     new AsyncOperation().execute(); 

    } catch (Exception e) { 
     Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
} 

public class OrderAdapter extends BaseAdapter { 

    private ArrayList<Order> items=new ArrayList<Order>(); 

    public OrderAdapter(Context context, int textViewResourceId, 
      ArrayList<Order> elements) { 
     //super(context, textViewResourceId, elements); 
     this.items = elements; 
    } 

    public void setList(ArrayList<Order> items) { 
     this.items.clear(); 
     this.items.addAll(items); 
     this.notifyDataSetChanged(); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     super.getView(position, convertView, parent); 
     View v = convertView; 
     try { 
      if (v == null) { 
       LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = vi.inflate(R.layout.row, null); 
      } 
      Order o = items.get(position); 
      if (o != null) { 
       TextView orderName = (TextView) v 
         .findViewById(R.id.topText); 
       TextView orderStatus = (TextView) v 
         .findViewById(R.id.bottomText); 
       orderName.setText(o.getOrderName()); 
       orderStatus.setText(o.getOrderStatus()); 
      } 
     } catch (Exception e) { 
      Toast.makeText(SoftwarePassionView.this, e.toString(), 
        Toast.LENGTH_SHORT).show(); 
     } 
     return v; 
    } 

public int getCount() { 

    return this.items.size(); 
} 

public Object getItem(int arg0) { 
    // TODO Auto-generated method stub 
    return this.items.get(arg0); 
} 

public long getItemId(int arg0) { 
    // TODO Auto-generated method stub 
    return 0; 
} 

} 

public class AsyncOperation extends AsyncTask { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected Object doInBackground(Object... params) { 
     getOrders(); 
     // if (m_orders != null && m_orders.size() > 0) { NO nead to set list here 
     //  m_adapter.setList(m_orders); 
     // } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Object result) { 

     if (m_orders != null && m_orders.size() > 0) { 
      m_adapter.setList(m_orders); 
     } 
     super.onPostExecute(result); 
     //setListAdapter(m_adapter); 
    } 
} 

private void getOrders() { 
    try { 
     m_orders = new ArrayList<Order>(); 
     Order o1 = new Order(); 
     o1.setOrderName("T-Shirt Purchase"); 
     o1.setOrderStatus("Dispatched"); 
     Order o2 = new Order(); 
     o2.setOrderName("Deo Purchase"); 
     o2.setOrderStatus("Pending"); 
     m_orders.add(o1); 
     m_orders.add(o2); 

     Thread.sleep(2000); 
    } catch (Exception e) { 
     Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
} 

}

+0

phew ...感谢您更正的版本。不工作。甚至尝试了一个新的简化项目。这个错误来自日志'E/ArrayAdapter(7245):你必须提供一个TextView'的资源ID。我改变了'm_adapter = new OrderAdapter(SoftwarePassionView.this, R.layout.row,m_orders);''m_adapter = new OrderAdapter(SoftwarePassionView.this, R.layout.row,R.id.tvOrderName,m_orders) ;'(我的row.xml中的T​​extView的id),但现在它给了我NPE。有什么建议么。 **&谢谢你的帮助这么多** – reiley 2012-07-07 21:27:26

+0

我已经编辑我的答案..现在检查...可能会帮助你... – 2012-07-08 04:56:38

+0

它的工作..你可以解释'BaseAdapter'做了什么区别。谢谢 – reiley 2012-07-08 07:32:39

0

检查this post,这个问题几乎是一样的。

我认为,作为项目具有相同的refreance(从活动传递到适配器)这样的项目(在适配器和活动都指向相同的ArrayList),所以两者都获得清晰所以这些线路没有意义的,因为已空

尝试这样:

public class OrderAdapter extends ArrayAdapter<Order> { 
     // private ArrayList<Order> items; 
     private ArrayList<Order> items = new ArrayList<Order>(); 

     public OrderAdapter(Context context, int textViewResourceId, 
       ArrayList<Order> elements) { 
      super(context, textViewResourceId, elements); 
      this.items = elements; 
     } 

     public void setList(ArrayList<Order> items) { 
     this.items.addAll(items); 

     } 

和:

@Override 
     protected void onPostExecute(Object result) { 
      super.onPostExecute(result); 
      //m_adapter.notifyDataSetChanged(); 
      // setListAdapter(m_adapter); 
      m_adapter.notifyDataSetChanged(); 
     } 

,并使用setListAdapter(m_adapter);创建m_adapter

+0

如果你在'onCreate()'中创建'm_adapter'后意味着设置'setListAdapter(m_adapter)',那么它给出'nullPointerException' – reiley 2012-07-07 09:16:43

+0

'nullPointerException'的原因是,'m_orders'在' setListAdapter'被调用。我已修复问题并在下面发布答案..看看.. – 2012-07-07 17:16:26