2

我正在设置这样的 ListView 适配器:

public class SeeAllQuestionsActivity extends Activity
{
    //ArrayAdapter<Question> adapter;   
    SimpleAdapter mSchedule = null;
    ListView list = new ListView (this);

    TextView loading_questions = null;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);        
        setContentView(R.layout.all_question_page);

        TextView loading_questions = (TextView) findViewById(R.id.loading_questions);

        list = (ListView) findViewById(R.id.list);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
        HashMap<String, String> map = new HashMap<String, String>();

        mSchedule = new SimpleAdapter(this, mylist, R.layout.questions_list,
                new String[] {"train", "from", "to"}, 
                new int[] {R.id.TRAIN_CELL, R.id.FROM_CELL, R.id.TO_CELL});

        list.setAdapter(mSchedule);

        list.setTextFilterEnabled(true);

        list.setOnItemClickListener(new OnItemClickListener() 
        {
            public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) 
            {              
              ...

然后进行远程异步调用以从我的数据库中获取列表,并尝试在 onPostExecute 方法中执行此操作:

ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
                HashMap<String, String> map = new HashMap<String, String>();

                    try
                    {
                        JSONArray obj = new JSONArray(result);

                        if ( obj != null )
                        {

                            for ( int i = 0; i < obj.length(); i++ )
                            {
                                JSONObject o = obj.getJSONObject(i);

                                map.put("train", "Business Name");
                                map.put("from", ">");
                                map.put("to", ">");
                                mylist.add(map);
                                map = new HashMap<String, String>();
                                map.put("train", "103(x)");
                                map.put("from", "6:35 AM");
                                map.put("to", "7:45 AM");
                                mylist.add(map);                                                                    
                            }
                        }
                    }
                    catch ( Exception e )
                    {
                    }                   

                    list.setAdapter(mSchedule);         

但我在这一行得到一个空指针异常:

ListView list = new ListView (this);

但我认为一般来说,我在 postExecute 方法中需要如何完成这项工作还有很长的路要走。非常感谢有关如何正确执行此操作的任何帮助。

4

2 回答 2

1

我记得并且作为一个合乎逻辑的结论:在你打电话的那一刻,this的引用是null将在ListView的构造函数中访问,因此将引发NullPointerException 。如果要动态创建它,则必须在Activity的onCreate方法中调用ListView构造函数。

如果可能的话,至少最好按照 MartijnVanMierloo 的建议来实现它。

于 2012-07-24T12:53:27.913 回答
1

在您的OnCreate中,您定义了一个新的 SimpleAdapter 并将其附加到您的 ListView。这是对的。数据源(mylist在您的情况下)此时为空,因此您将使用AsyncTask.

在您的onPostExecute中,您正在创建一个新的ArrayList. 根据您收到的结果,您填写它。完成此操作后,您将再次设置适配器。因为适配器没有数据,所以什么都不做。您想要做的是将新填充的列表提供给适配器,以便它可以ListView用您的数据填充。

解决方案 1

onPostExecute {
   // create a list to store your data
   new ArrayList

   // fill the new list with the data you received (result)
   fillArrayList from JSON

   // create an adapter and give the new list with it
   mAdapter = new SimpleAdapter(.., ArrayList, ...)
   listView.setAdapter(mAdapter);   
}

这是您可以做到的一种方式,并且适合您当前的实现。

解决方案 2

我会选择这个解决方案

onPostExecute {
    // don't create a new arraylist but use the mylist-object you created in the OnCreate
    fill mylist object with new data 

    // mylist is the datasource of your adapter and it is now changed.
    // let the ListView know his adapter received new information
    mSchedule.notifyDataSetChanged
}

更新

看看这个教程。我使用相同的布局和相同的来源来填充我的列表,但我已经对其进行了更改,因此它与您的情况相似。祝你好运 :)

主要活动

public class MainActivity extends Activity {

    private List<HashMap<String, String>> fillMaps;
    private SimpleAdapter adapter;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView lv = (ListView) findViewById(R.id.listview);

        String[] from = new String[] { "rowid", "col_1", "col_2", "col_3" };
        int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4 };

        // My data
        fillMaps = new ArrayList<HashMap<String, String>>();

        // Create an adapter which will tell my ListView what to show..
        // fillMaps is still empty so at the moment it my ListView will show
        // nothing.
        adapter = new SimpleAdapter(this, fillMaps, R.layout.row, from, to);
        lv.setAdapter(adapter);

        // Retreive data from somewhere
        new UpdateListWithAsyncTask().execute();
    }

    private class UpdateListWithAsyncTask extends AsyncTask<Void, Void, Void> {
        protected Void doInBackground(Void... params) {
            // do stuff
            return null;
        }

        protected void onPostExecute(Void result) {
            // Fill your datasource that your adapter has. In my case fillMaps
            for (int i = 0; i < 10; i++) {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("rowid", "" + i);
                map.put("col_1", "col_1_item_" + i);
                map.put("col_2", "col_2_item_" + i);
                map.put("col_3", "col_3_item_" + i);
                fillMaps.add(map);
            }

            // my datasource is now changed, I want my adapter to know this and
            // update my ListView
            adapter.notifyDataSetChanged();
        }
    }
}
于 2012-07-24T13:17:00.200 回答