Android - 在异步调用后更新 ListAdapter 时遇到问题 [英] Android - having trouble updating a ListAdapter after an Asynch call

查看:14
本文介绍了Android - 在异步调用后更新 ListAdapter 时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在像这样设置一个 ListView 适配器:

I am setting up a ListView adapter like this:

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 方法中执行此操作:

and then making a remote Asynch call to get the list from my database, and trying to do this in the onPostExecute method:

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);         

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

but I get a Null Pointer exception on this line:

ListView list = new ListView (this);

但我认为通常我在 postExecute 方法中需要如何完成这件事.非常感谢有关如何正确执行此操作的任何帮助.

But I think generally I am way off in how this needs to be done in the postExecute method. Any help with how to do this correctly is much appreciated.

推荐答案

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

In your OnCreate you define a new SimpleAdapter and attach it to your ListView. This is correct. The datasource (mylist in your case) is empty at this point so you will fill it with in an AsyncTask.

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

In your onPostExecute you are creating a new ArrayList. Depending on the result you receive, you fill it. After you did this, you are setting the adapter again. Which will do nothing because the adapter has no data.. What you want to do, is give your new filled list to your Adapter so it can fill the ListView with your data.

解决方案 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);   
}

这是您可以做到并适合您当前实施的一种方式.

This is one way you can do it and fits you current implementation.

解决方案 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
}

更新

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

Check out this tutorial. I use the same layouts and same source to fill my list but I have altered it so it is similar to your case. Good luck :)

主活动

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();
        }
    }
}

这篇关于Android - 在异步调用后更新 ListAdapter 时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆