简体   繁体   中英

ListView notifyDatasetChanged does not refresh view

In my application, I tried to update the listview by

adater.notifyDataSetChanged();

But it does not work.

I know people have met this problem like this: Android ListView not refreshing after notifyDataSetChanged

But I have tried that method, it does not work for me.

This is my core codes(I tried to refresh the view once the drawer is opened):

public class DrawerItem {
    private String name;
    private int icon = -1;
    private String counter = "0";
    private boolean showCounter;
    private ItemType itemType;

    public DrawerItem(String name, int icon, ItemType itemType, boolean showCounter) {
        this.name = name;
        this.icon = icon;
        this.showCounter = showCounter;
        this.itemType = itemType;
    }
    //getter and setter omitted
    public enum ItemType {
        Action, Layer, Title
    }
}


private List<DrawerItem> getDrawerItems() {
    ArrayList<DrawerItem> items = new ArrayList<DrawerItem>();

    DrawerItem layer = new DrawerItem("Layer", -1, DrawerItem.ItemType.Title, false);
    DrawerItem layer01 = new DrawerItem("Layer01", R.drawable.drawer_ic1, DrawerItem.ItemType.Action, false);
    DrawerItem layer02 = new DrawerItem("Layer02", R.drawable.drawer_ic2, DrawerItem.ItemType.Action, true);
    DrawerItem layer03 = new DrawerItem("Layer03", R.drawable.drawer_ic3, DrawerItem.ItemType.Action, true);
    DrawerItem layer04 = new DrawerItem("Layer04", R.drawable.drawer_ic4, DrawerItem.ItemType.Action, false);


    items.add(layer);
    items.add(layer01);
    items.add(layer02);
    items.add(layer03);
    items.add(layer04);
    if (mLayerPoint2 != null) {
        layer02.setCounter(String.valueOf(mLayerPoint2.getFeatureCounter()));
    }

    if (mLayerPoint3 != null) {
        layer03.setCounter(String.valueOf(mLayerPoint3.getFeatureCounter()));
    }
    return items;
}

private class DrawerAdapter extends ArrayAdapter<DrawerItem> {
    private List<DrawerItem> mData = new ArrayList<DrawerItem>();
    public DrawerAdapter(Context context, int resource) {
        super(context, resource);
    }
    public void swapItems(List<DrawerItem> items) {
        this.mData.clear();
        this.mData.addAll(items);
        this.notifyDataSetChanged();
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        DrawerItem item = getItem(position);

        if (convertView == null) {
            switch (item.getItemType()) {
                case Action:
                    convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_action, null);
                    .....
                    break;
                case Title:
                    convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_title, null);
                    ...
                    break;
            }
        }
        return convertView;
    }
}


public void onCreate(...){
    mDrawerList = (ListView) findViewById(R.id.left_drawer);
    mDrawerListAdapter = new DrawerAdapter(this, R.layout.drawer_item_action);
    List<DrawerItem> items = getDrawerItems();
    mDrawerListAdapter.addAll(items);
    mDrawerList.setAdapter(mDrawerListAdapter);
    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.app_name, R.string.app_name) {
        public void onDrawerClosed(View view) {
        }

        public void onDrawerOpened(View drawerView) {
            mDrawerListAdapter.swapItems(getDrawerItems());
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

What's the problem?

SOLVED:

Caused from my f**ing stupid getView method of the DrawerAdapter :

public View getView(int position, View convertView, ViewGroup parent) {
    DrawerItem item = getItem(position);

    if (convertView == null) {
        switch (item.getItemType()) {
            case Action:
                convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_action, null);
                .....
                break;
            case Title:
                convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_title, null);
                ...
                break;
        }
    }
    return convertView;
}

Fix it to:

    switch (item.getItemType()) {
        case Action:
            if (convertView == null) {
                convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_action, null);
            }
            ....
            break;
        case Title:
            if (convertView == null) {
                convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.drawer_item_title, null);
            }
            ....
            break;
    }

Issue is with you swapItems ,You really not required to explicitly call the notifyDataSetChanged. if your using ArrayAdapter.

Since when you add an item to ArrayAdapter , the ListView will be notified on the changes. So you have to add the item to the adapter.

Remove this line and the swapItems() method in the DrawerAdapter.

private List<DrawerItem> mData = new ArrayList<DrawerItem>();

When you need to refresh with new item, clear the existing item in the adapter and add new items from onDrawerOpened()

So, your onDrawerOpened() need to be changed as below

 public void onDrawerOpened(View drawerView) {
        // clear the existing items
        mDrawerListAdapter.clear();
        // add the new item
        mDrawerListAdapter.addAll(getDrawerItems())
    }

Thats all.. Hope it works for you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM