Android的 - 有困难的非同步调用后更新ListAdapter [英] Android - having trouble updating a ListAdapter after an Asynch call

查看:184
本文介绍了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方法进行。任何帮助,如何正确地做到这一点是非常AP preciated。

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

MainActivity

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天全站免登陆