【问题标题】:Why does my ListView not update with SimpleAdapter?为什么我的 ListView 不使用 SimpleAdapter 更新?
【发布时间】:2013-03-03 20:07:08
【问题描述】:

我正在从我的服务器检索 JSON 数据,我想用它来更新我的 ListView。检索数据时一切正常,但在完成并尝试更新列表后,我只得到一个没有错误的空页面。 Log.d("ListLocations", "after") 也可以运行,所以我看不到 PostExecute 和 SimpleAdapter 的初始化有任何问题

我已经改编了本教程中的代码:http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/#ff0000

这是我的 ListActivity 类:

public class ListLocations extends ListActivity
{
    //Root url and controller
    private static String root = "someURL/";
    private static String locationsController = "locations";

    // Progress Dialog
    private ProgressDialog pDialog;

    //JSON node names for locations 
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_TERRAIN = "terrain";
    private static final String TAG_DIFFICULTY = "difficulty";
    private static final String TAG_RATINGS = "ratings";
    private static final String TAG_UID = "uid";
    private static final String TAG_LONG= "long";
    private static final String TAG_LAT= "lat";
    private static final String TAG_DISTANCE= "distance";
    private static final String TAG_COMID= "comid";

    //Will be used to contain the list of locations extracted from JSON
    ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_locations);

        new GetLocations().execute(root + locationsController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_list_locations, menu);
        return true;
    }
    class GetLocations extends AsyncTask<String, Void, Void>
    {
        //      private ProgressDialog pDialog;
        protected void onPreExecute()
        {
            super.onPreExecute();
            pDialog = new ProgressDialog(ListLocations.this);
            pDialog.setMessage("Loading locations. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }


        @Override
        public Void doInBackground(String... urls)
        {
            try
            {               
                JSONHandler jsonHandler = new JSONHandler();
                JSONObject json= jsonHandler.getJSONFromUrl(urls[0]);
                Log.d("ListLocations",json.toString());

                JSONArray locations = json.getJSONArray("locations");
                int length = locations.length();

                ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
                for(int i = 0; i < length; i++)
                {
                    JSONObject loc = locations.getJSONObject(i);

                    //Create HashMap    
                    HashMap<String, String> map = new HashMap<String, String>();

                    //Get and store values into map
                    map.put("id", loc.getString(TAG_ID));
                    map.put("name", loc.getString(TAG_NAME));
                    map.put("distance", loc.getString(TAG_DISTANCE));
                    map.put("difficulty", loc.getString(TAG_DIFFICULTY));
                    map.put("terrain", loc.getString(TAG_TERRAIN));
                    map.put("ratings", loc.getString(TAG_RATINGS));
                    map.put("long", loc.getString(TAG_LONG));
                    map.put("lat", loc.getString(TAG_LAT));
                    map.put("uid", loc.getString(TAG_UID));
                    map.put("comid", loc.getString(TAG_COMID));

                    //Add map to list
                    list.add(map);
                }
                System.out.println(list);

            }
            catch (Exception e)
            {
                 e.printStackTrace();            
            }
            Log.d("ListLocations", "Successfully finished HTTP Request");
            return(null);
        }

          /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(Void result) { 
            super.onPostExecute(result);
            pDialog.dismiss();

            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    Log.d("ListLocations", "inside run");
                       ListAdapter adapter = new SimpleAdapter(
                               ListLocations.this, list,
                               R.layout.list_item, new String[] { TAG_ID,
                                       TAG_NAME},
                               new int[] { R.id.id, R.id.name });



                       Log.d("ListLocations", "after");
                       // updating listview
                       setListAdapter(adapter);


                }
            });

        }

    }
}

这是list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <!-- location id (pid) - will be HIDDEN - used to pass to other activity -->
    <TextView
        android:id="@+id/id"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />

    <!-- Name Label -->
    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17dip"
        android:textStyle="bold" />

</LinearLayout>

这是activity_list_locations.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

【问题讨论】:

  • onPostExecute() 在 UI 线程中运行,因此,runOnUIThread() 是多余的。
  • 我应该在哪里调用 runOnUIThread,如果有的话?

标签: android json android-listview simpleadapter


【解决方案1】:

您永远不会将与SimpleAdapter 一起使用的Activity 中的数据放入list 字段中,因为doInBackground 方法中的list 变量是局部变量而不是字段。而不是:

//...
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < length; i++) {
//...

写:

//...
list = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < length; i++) {
//...

所以你不需要创建一个局部变量并将元素放在正确的列表中。

【讨论】:

  • @JohnathanAu 你现在是信徒了吗?:)
  • 这一切都结束了,我觉得世界就是我的牡蛎。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多