简体   繁体   中英

why is my convertView == null on getView method?

I have an Activity with viewList + Custom Adapter.

I want to update the viewList on runtime (using callback when some resources are done downloading). I call the ui-thread to invoke this method:

    public void refreshListIcons() {

            if (categories != null) {

                SettingsValue[] values = adapter.getValues();
                for (int i = 0; i < values.length; i++) {
                    values[i].icon = ResManager
                            .GetSkinDrawable(categories[i].iconName + ".bin");
                }

                adapter.setValues(values);

                mListView.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
    }

and then the adapter.getView method is called:

but why is convertView==null ?

one the first time the activity is created I understand.

But now this is my second time (runtime update).

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.settings_item, null);
        }
...
}

It causes re-inflating too many times and crashes my app.

my entire adapter's code:

package com.waze.settings;


public class SettingValueAdapter extends BaseAdapter {

    private SettingsValue[] values;
    private LayoutInflater inflater;
    public SettingValueAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }

    public SettingsValue[] getValues() {
        return values;
    }

    @Override
    public int getCount() {
        if (values == null) {
            return 0;
        }
        return values.length;
    }


    @Override
    public Object getItem(int arg0) {
        return values==null? null : values[arg0];       
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.settings_item, null);
        }
        SettingsValue item = values[position];
        CheckedTextView name = (CheckedTextView) convertView.findViewById(R.id.itemText);
        ImageView iconView = (ImageView) convertView.findViewById(R.id.itemIcon);
        if (iconView != null && (item != null) && (item.icon != null)) {
            iconView.setImageDrawable(item.icon);
            iconView.setVisibility(View.VISIBLE);
        } else {
            iconView.setVisibility(View.GONE);
        }
        name.setText(item.display);
        name.setChecked(item.isSelected);
        View container = convertView.findViewById(R.id.itemContainer);
        if (position == 0) {
            if (position == values.length-1) {
                container.setBackgroundResource(R.drawable.item_selector_single);
            } else {
                container.setBackgroundResource(R.drawable.item_selector_top);
            }
        } else {
            if (position == values.length-1) {
                container.setBackgroundResource(R.drawable.item_selector_bottom);
            } else {
                container.setBackgroundResource(R.drawable.item_selector_middle);
            }
        }
        container.setPadding(0, 0, 0, 0);
        return convertView;
    }

    public void setValues(SettingsValue[] values) {
        this.values = values;
        notifyDataSetChanged();
    }
}

I guess you shouldn't set the adapter again. Instead modify your refresh method as:

public void refreshListIcons() {

        if (categories != null) {

            SettingsValue[] values = adapter.getValues();
            for (int i = 0; i < values.length; i++) {
                values[i].icon = ResManager
                        .GetSkinDrawable(categories[i].iconName + ".bin");
            }

            adapter.notifyDataSetChanged();


           /* 
             adapter.setValues(values);
             mListView.setAdapter(adapter);
             adapter.notifyDataSetChanged();*/
        }
}

Also add a viewHolder class in your adapter.

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