我試圖讓我無盡的列表工作,但所有的時間我得到有關修改適配器的內容IllegalStateException。我完全不知道爲什麼會發生。Android - 適配器的內容已更改?
錯誤是相當
IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131493058, class android.widget.ListView) with Adapter(class ListNewsAdapter)]
這裏是我的AsyncTask:
public class ListDownloadNewAsyncTask extends AsyncTask<Void, Void, NewsArrayList> {
private String mLastId = null;
@Override
protected void onPreExecute() {
ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
if (adapter != null && adapter.getCount() > 0) {
mLastId = adapter.getItem(adapter.getCount() - 1).getId();
}
super.onPreExecute();
}
@Override
protected NewsArrayList doInBackground(Void... params) {
NewsArrayList downloadedNews = null;
try {
downloadedNews = JSONLoader.loadNews(getActivity(), mLastId);
} catch (Exception ex) { }
return downloadedNews;
}
@Override
protected void onPostExecute(NewsArrayList result) {
mLeftToDownload = result.getLeft();
ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
if (adapter == null) {
adapter = new ListNewsAdapter(getActivity(), R.layout.news_list_row, result.getNewsArray(), NewsListFragment.this);
listView.setAdapter(adapter);
} else {
adapter.addAll(result.getNewsArray());
adapter.notifyDataSetChanged();
isLoading = false;
}
super.onPostExecute(result);
}
}
我正在尋找不已的ListView任何代碼片段,但我發現大部分事情是靜態或動態創建- 未下載。
所以我的問題是......我在這裏錯過了什麼?或者我做錯了什麼?
編輯:這是我的適配器類
public class ListNewsAdapter extends ArrayAdapter<News> {
private final ArrayList<News> news;
private final int newsRowResourceId;
private View progressView;
NewsListFragment fragment;
public ListNewsAdapter(Context context, int newsRowResourceId, ArrayList<News> news, NewsListFragment fragment) {
super(context, newsRowResourceId, news);
this.news = news;
this.newsRowResourceId = newsRowResourceId;
this.fragment = fragment;
}
@Override
public int getCount() {
return NewsListFragment.isLoading() ? news.size() + 1 : news.size();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewHolder holder;
try {
if (convertView == null || convertView.findViewById(R.id.title) != null || convertView == progressView) {
convertView = inflater.inflate(newsRowResourceId, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.description = (TextView) convertView.findViewById(R.id.description);
holder.image = (ImageView) convertView.findViewById(R.id.news_list_item_image);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position < getCount()) {
News newsRow = news.get(position);
if (newsRow != null) {
holder.title.setText(newsRow.getTitle().trim().replaceAll("[\n\r]", " "));
holder.description.setText(newsRow.getDescription().trim().replaceAll("[\n\r]", " "));
if (newsRow.getPhotoUrl() != null && !newsRow.getPhotoUrl().equalsIgnoreCase("null")) {
Ion.with(holder.image).placeholder(R.drawable.icon).load(newsRow.getPhotoUrl());
} else {
holder.image.setImageResource(R.drawable.icon);
}
}
}
convertView.setClickable(true);
convertView.setFocusable(true);
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Main.instance.changeNewsFragment(news.get(position).getNewsUrl());
}
});
return convertView;
} catch (IndexOutOfBoundsException e) {
progressView = inflater.inflate(R.layout.progress_list_item, null);
return progressView;
}
}
static class ViewHolder {
TextView title;
TextView description;
ImageView image;
}
}
編輯:我想到了一兩件事。我認爲推出從的AsyncTask OnScrollListener:
public abstract class InfiniteScrollListener implements AbsListView.OnScrollListener {
private int bufferItemCount = 10;
public InfiniteScrollListener(int bufferItemCount) {
this.bufferItemCount = bufferItemCount;
}
public abstract void loadMore();
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if ((mLeftToDownload > 0) && !isLoading && ((firstVisibleItem + visibleItemCount) >= (totalItemCount - bufferItemCount))) {
Log.d("test", "from onScroll: " + mLeftToDownload + ", " + isLoading + ", " + (firstVisibleItem + visibleItemCount) + ">=" + (totalItemCount - bufferItemCount));
isLoading = true;
loadMore();
}
}
}
和
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.news_list_fragment, null);
listView = (ListView) v.findViewById(R.id.list_news);
mLeftToDownload = -1;
listView.setOnScrollListener(new InfiniteScrollListener(5) {
@Override
public void loadMore() {
new ListDownloadNewAsyncTask().execute();
}
});
listView.setItemsCanFocus(true);
new ListDownloadNewAsyncTask().execute();
return v;
}
所以,我認爲它可能是用相同的適配器上工作的兩個任務。所以我修改了onscroll
方法中的if
聲明的最後部分,這減少了崩潰的數量,但我仍然有一些。
編輯:logcat的用於@Elltz
05-12 00:58:51.027 5108-5108/app.packg E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131493058, class android.widget.ListView) with Adapter(class ListNewsAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1538)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4385)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:524)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4849)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)
此列表僅加載一次,還是不斷得到新的結果? –
@DroidChris:列表正在獲得新的結果(一旦用戶滾動到底部,獲得幾個舊的新聞)。 – Seraphis
@iRaviiVooda:第一組物品放在適配器的構造函數中。 – Seraphis