![](/img/trans.png)
[英]custom BaseAdapter in listVIew can not notifyDataSetChanged
[英]notifyDataSetChanged does not work in the ListView with custom BaseAdapter
我嘗試創建ListView。 它包含由單個xml模板創建的少量自定義視圖,以及一個用於指示進度的視圖。 ProgressView始終必須位於自定義ListView的底部。 所以,這是代碼:
public class SearchActivity extends Activity implements OnXMLDataGetterComplete {
private ListView mMainLayout;
private HotelsListAdapter mHotelsListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mHotelsListAdapter = new HotelsListAdapter(); //create my custom adapter
mHotelsListAdapter.setLoading(true); //sets that my ListView will be show ProgressView at the bottom
mMainLayout = (ListView) findViewById(R.id.search_activity_layout);
mMainLayout.setAdapter(mHotelsListAdapter); //set adapter for my ListView
getData(); //start to receive data from web
}
//this function runs after HTTP-query
public void onGetData(final List data) { //receives list of some data
runOnUiThread(new Runnable() {
@Override
public void run() {
Iterator<XMLDataGetter.HotelListXMLParser.HotelListXMLEntry> it = data.iterator();
while (it.hasNext()) {
XMLDataGetter.HotelListXMLParser.HotelListXMLEntry item = it.next();
mHotelsListAdapter.setLoading(data.size() != 0);
HotelItemView hotel = new HotelItemView(SearchActivity.this); //create some custom view by received data
...
mHotelsListAdapter.addItem(hotel); //add this view to the adapter
}
mHotelsListAdapter.notifyDataSetChanged(); //THIS NOT WORKS
}
}
}
public class HotelsListAdapter extends BaseAdapter { //ny custom adapter
private List<HotelItemView> mItems = new ArrayList<HotelItemView>(); //list, which contains all created custom views
private boolean mIsLoading = false; //variable, which determines, whether ProgressView will be shown
private RelativeLayout mLoadingView; //layout of activity
public HotelsListAdapter() {
LayoutInflater inflater = (LayoutInflater) ((Context) SearchActivity.this).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLoadingView = (RelativeLayout) inflater.inflate(R.layout.hotel_list_loading, null); //inflate ProgressView
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
if (mIsLoading)
return mItems.size() + 1; //custom adapter contains children vies + ProgressView
else
return mItems.size(); //custom adapter contains only children views
}
@Override
public Object getItem(int position) {
if (position > mItems.size() - 1)
return mLoadingView; //return ProgressView
else
return mItems.get(position); //return child view
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return (View) getItem(position);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public boolean isEmpty() {
return false;
}
public void addItem(HotelItemView item) {
mItems.add(item);
}
public void clear() {
mItems.clear();
}
public void setLoading(boolean loading) {
mIsLoading = loading;
}
public boolean isLoading() {
return mIsLoading;
}
}
}
此示例帶有ProgressBarView,但我嘗試刪除有關它的引用:
@Override
public int getCount() {
return mItems.size(); //custom adapter contains only children views
}
@Override
public Object getItem(int position) {
return mItems.get(position); //return child view
}
並且notifyDataSetChanged()仍然無法正常工作。 我怎么了 我無法顯示添加的視圖。
我試圖在otifyDataSetChanged()之前添加mMainLayout.invalidateViews()。 因此,我看到了我的視圖列表,但是每三到五次出現異常“適配器的內容已更改,但ListView並未收到通知”。 我該怎么辦?
最主要的是,我不需要清除適配器。 添加子視圖必須是增量的。 我也嘗試擴展ListAdapter,但是它根本沒有這樣的方法
也許不要覆蓋適配器的registerDataSetObserver方法。
其他一些提示:
如果沒有理由不使用它,我建議您使用ArrayAdapter,因為它可以為您節省一些基本配置並為您處理列表管理。 另外,不要將“視圖”保存在要顯示的列表中,而是保存包含數據的項目。 ListAdapters可以為您回收視圖,因此列表中的每個項目都沒有一個視圖,但是可見的每個項目都沒有一個視圖。 在getView方法中,如果“ convertView”參數不為空,則可以重用此視圖,因此只需填充其數據並返回即可。 這將提高列表的性能,並大大減少內存消耗。
對於Async東西,最好使用AsyncTask,它與Android系統更好地集成在一起,並且在后台任務之前和之后在UI Thread中運行東西等事情變得更加容易。
嘗試
mHotelsListAdapter.setNotifyOnChange(true);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.