如何覆盖 ListView 中的项目列表创建?

How to override item list creation in ListView?

我想使用 simple_list_item_1 布局创建一个自定义列表,以便我可以更改字体、背景等。您如何进行此操作?

我尝试使用扩展 ArrayAdapter 的自定义适配器覆盖 getView,但每当我对列表执行某些操作(例如搜索)时,生成的列表会丢失所有自定义设置,直到我最小化键盘。这就是为什么我认为如果我能首先重写列表创建方法会更好。

这是自定义适配器class

public class AlphabeticalAdapter extends ArrayAdapter<String> implements SectionIndexer {
private HashMap<String, Integer> _alphaIndexer;
private String[] _sections;
private Typeface _typeface;

public AlphabeticalAdapter(Context c, int resource, List<String> data) {
    // create ArrayAdapter<String>
    super(c, resource, data);

    try {
        // generate typeface
        _typeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/hs_bold.otf");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public int getPositionForSection(int section) {
    return _alphaIndexer.get(_sections[section]);
}

public int getSectionForPosition(int position) {
    return 1;
}

public Object[] getSections() {
    return _sections;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    TextView text = (TextView) convertView;

    if (text != null) {
        text.setTypeface(_typeface);
    }

    return super.getView(position, convertView, parent);
}

}

引用我自己的话:

Step #3: If you want to have dynamic effects, based on model data, override getView() and modify the row widgets as needed. Just make sure that you always modify the row widgets, as rows get recycled, and so you do not necessarily know what the starting state of your widgets are.

在您的情况下,您并不总是在每次 getView() 调用时都定制小部件。只有当 convertView 不是 null 时,您才这样做。当您最初填充 ListView.

时,convertView 将是 null

以下实现总是调用 setTypeface():

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView text=(TextView)super.getView(position, convertView, parent);

    text.setTypeface(_typeface);

    return(text);
}

现在,我还没有检查调用 setTypeface() 的影响。理想情况下,它很便宜,所以每次都调用它就可以了。如果,OTOH,分析表明每次调用 setTypeface() 都会增加太多开销,那么您可以考虑优化问题。特别是,在这种情况下,您希望每一行都使用相同的字体——它不会根据您呈现的行而有所不同。在这种情况下,您只需要在创建新 TextViewgetView() 调用上调用 setTypeface(),而 应该 convertViewnull。因此,以下开销较少但风险更大,因为您正在对超类的实现做出一些假设:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView text=(TextView)super.getView(position, convertView, parent);

    if (convertView==null) {
        text.setTypeface(_typeface); // because a new TextView definitely was created, since we could not reuse the convertView as it was null
    }

    return(text);
}