0

我正在尝试将一组获取结果显示为列表。每当我尝试使用虚拟数据时,它都会正确显示,但是当我将其更改为从服务器检索到的数据时,什么也没有发生。我没有收到任何错误,所以这很令人困惑

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;

import android.app.ListFragment;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

public class BlogFragment extends ListFragment {

    String[] countries = new String[] {
        "India",
        "Pakistan",
        "Sri Lanka",
        "China",
        "Bangladesh",
        "Nepal",
        "Afghanistan",
        "North Korea",
        "South Korea",
        "Japan"
    };

    String [] titles ={};
    ArrayAdapter<String> adapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        /** Creating an array adapter to store the list of countries **/
        new AsyncFetchData().execute();
        adapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1,titles);

        return super.onCreateView(inflater, container, savedInstanceState);
    }

    private class AsyncFetchData extends AsyncTask
    {

        @Override
        protected Object doInBackground(Object... arg0) {


            JSONArray a = new JSONArray();
            ArrayList<String> aList = new ArrayList<String>();
            a = ServerAPI.getData();
            for (int i = 0; i < a.length(); i++) {
                String title = null;
                String content = null;
                try {
                    title = a.getJSONObject(i).getString("title");
                    content = a.getJSONObject(i).getString("content");
                    aList.add(title);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(title);
//              System.out.println(content);
            }
            titles = aList.toArray(new String[aList.size()]);
            /** Setting the list adapter for the ListFragment */


            return null;
        }

        protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        ArrayAdapter aa = new ArrayAdapter(getActivity().getBaseContext(), android.R.layout.simple_list_item_1, titles);
        aa.notifyDataSetChanged();  
        setListAdapter(aa); 
    }
    }
}

字符串数组countries在方法中正确显示,runOnUiThread而标题没有。我检查了标题字符串数组中的数据,它是有效的。知道为什么会这样吗?

4

3 回答 3

0

首先为新标题创建一个新适配器,然后设置该适配器。

于 2014-11-16T11:24:42.627 回答
0

问题是:

您的适配器已经使用旧数据集进行了初始化。因此,您正在更新基础数据,但适配器仍保存旧数据。

您需要使用新数据更新适配器。

为了那个原因,

称呼

adapter.notifyDatasetChanged(); 

就在之前

setListAdapter(adapter);

notifyDataSetChanged: 通知附加的观察者底层数据已经改变,任何反映数据集的视图都应该刷新自己。

于 2014-11-16T11:16:32.640 回答
0

我在您的代码中看到了一些奇怪的东西:

  1. onCreateView你开始新的AsyncFetchData().execute()。如果要下载当前列表项的数据,它可能会很有用,对于整个列表,它是以其他方式制作的(不在 onCreateView 内)

  2. 我希望 onCreateView 创建一个新视图而不是调用super.onCreateView来访问视图元素(并用下载的数据填充它们)

ListFragment 使用的标准模式是:

public class MyListFragment extends ListFragment {

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
        "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
        "Linux", "OS/2" };
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
        android.R.layout.simple_list_item_1, values);
    setListAdapter(adapter);
  }

}

如果要使用从AsyncTask下载的数据更新列表,则应更新适配器引用的数组中的数据,而无需重新创建适配器本身。并在新数据准备好后立即在 UI 线程上调用adapter.notifyDataChanged()(就像您尝试做的那样,但通常它是在专为这种情况设计的AsyncTask.postExecute()中制作的。

我猜你在下载之前没有任何数据要显示。然后你不需要显示空列表,可能是某种进度条。它可能是TextView “请稍候,正在下载...” 下载完成后,您将用ListView(或片段)替换 TextView,可能带有动画。这样,ListView 将立即创建,您无需关心它的异步下载。

添加:关于进度条 - 使用标准的会更好:

ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("Please wait, downloading...");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setIndeterminate(true);

AsyncTask.onPreExecute()是一个很好的地方。不要忘记在onPostExecute()中关闭它

于 2014-11-16T11:30:10.477 回答