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) 
            {              
              ...

次に、リモートAsynch呼び出しを行ってデータベースからリストを取得し、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);         

しかし、この行でNullPointer例外が発生します。

ListView list = new ListView (this);

しかし、一般的に、postExecuteメソッドでこれを行う必要がある方法はかなり遠いと思います。これを正しく行う方法についての助けは大歓迎です。

4

2 に答える 2

1

私が覚えているように、そして論理的な結論として:あなたの呼び出しの瞬間にこれの参照は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);   
}

これは、それを実行できる1つの方法であり、現在の実装に適合します。

解決策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 に答える