我有一个扩展ListFragment的类(ListMainContentFragment)。其目的是获取JSON数据并使用自定义适配器将其显示在永无止境的列表中。最初,我从我的主要活动中调用了Fragment和AsyncTask,并且在我添加OnScrollListener之前完全正常,因为我需要从OnScrollListener中再次调用AsyncTask。所以我将整个AsyncTask代码移到了ListFragment中。现在,JSON数据将被解析,但不显示列表。出于某种原因,代码认为已显示列表并且正在调用onScroll方法。没有错误被抛出。代码如下。
// List Fragment
public static class ListMainContentFragment extends ListFragment {
public static final String ARG_DATA_TO_DISPLAY = "parsed_data";
public static List<Result> currentResults;
public ListMainContentFragment() {
// Empty constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
try {
new GetJobsTask().execute(currentURL).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
JobsListAdaptor adapter = new JobsListAdaptor(inflater.getContext(), currentResults);
setListAdapter(adapter);
// Integer rSize = adapter.getCount();
// Log.i("Scroll", "List generating with "+rSize.toString()+" entries");
return inflater.inflate(R.layout.list_of_jobs, container, false);
}
/** Start Handling JSON Data **/
private class GetJobsTask extends AsyncTask<String, Void, List<Result>> {
AndroidHttpClient mClient = AndroidHttpClient.newInstance("");
// Get JSON data, use JSONResponseHandler to parse into List of type Result
@Override
protected List<Result> doInBackground(String... url) {
HttpGet request = new HttpGet(url[0]);
JSONResponseHandler responseHandler = new JSONResponseHandler();
try {
return mClient.execute(request, responseHandler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Close the Http client and log the number of results obtained.
@Override
protected void onPostExecute(List<Result> results) {
if (mClient != null)
mClient.close();
currentResults = results;
Log.i("onPostExecute", "There are "+results.size()+" entries");
}
}
/** End Handling JSON Data **/
public void onViewCreated(View view, Bundle savedInstanceState){
Log.i("Scroll", "OnViewCreated entered");
ListView mListView = (ListView) view.findViewById(android.R.id.list);
Log.i("Scroll", "ListView accessed");
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Auto-generated method stub
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
Log.i("Scroll", "List scrolled");
switch(view.getId()) {
case android.R.id.list:
final Integer lastItem = firstVisibleItem + visibleItemCount;
if ((lastItem == totalItemCount) & (preLast != lastItem)) {
Log.i("Scroll", "Last item reached");
currentURL = "http://api.indeed.com/ads/apisearch?publisher=9616825572719411&v=2&format=json&l=austin&limit=10&start="+lastItem.toString();
new GetJobsTask().execute(currentURL);
preLast = lastItem;
}
}
}
});
}
}
这是我的Logcat输出:
05-31 17:57:39.245: I/Scroll(2559): OnViewCreated entered
05-31 17:57:39.245: I/Scroll(2559): ListView accessed
05-31 17:57:39.245: I/Scroll(2559): List scrolled
05-31 17:57:39.249: I/Scroll(2559): List scrolled
05-31 17:57:39.261: I/onPostExecute(2559): There are 20 entries
从logcat信息看,即使在onPostExecute完成之前,也会调用onScroll方法。并且只在onPostExecute中,我将AsyncTask的结果分配给变量currentResults。我尝试添加get()方法以强制主线程等待AsyncTask完成,但它似乎没有做我期望它做的事情。
我错过了什么?
答案 0 :(得分:0)
每次更改适配器内容时,都应调用:
getListAdapter().notifyDataSetChanged();
此外,您不会更改适配器内容本身。尝试:
currentResults.clear();
currentResults.addAll(results);
getListAdapter().notifyDataSetChanged();
答案 1 :(得分:0)
原因是,您在AsyncTask执行之前设置了列表适配器。这意味着列表适配器已设置,但没有任何内容可供显示。
try {
new GetJobsTask().execute(currentURL).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// Because the AsyncTask is handled in another thread, it returns straight away,
// so this is called before the AsyncTask is finished.
JobsListAdaptor adapter = new JobsListAdaptor(inflater.getContext(), currentResults);
setListAdapter(adapter);
相反,将此代码移动到onPostExecute方法中,如下所示:
@Override
protected void onPostExecute(List<Result> results) {
if (mClient != null) {
mClient.close();
}
JobsListAdaptor adapter = new JobsListAdaptor(inflater.getContext(), results);
setListAdapter(adapter);
Log.i("onPostExecute", "There are "+results.size()+" entries");
}