2015-01-10 29 views
0

我想使用simple_list_item_1佈局創建一個自定義列表,以便我可以更改字體,背景等。您如何去做這件事?如何覆蓋ListView中的項目列表創建?

我試圖通過使用延伸ArrayAdapter的自定義適配器覆蓋getView,但每當我對列表執行某些操作(例如搜索)時,生成的列表都會丟失所有自定義,直到我最小化鍵盤。這就是爲什麼我認爲如果我能夠首先覆蓋列表創建方法會更好。

這是自定義適配器類

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); 
} 

}

+0

「你怎麼去做這件事? - 步驟#1:將'simple_list_item_1'佈局複製到您的項目中並進行修改以適應。您可以在Android SDK安裝中找到此佈局的副本。第二步:在你的'ArrayAdapter'構造函數中使用你修改過的佈局。步驟#3:如果你想擁有基於模型數據的動態效果,可以重寫'getView()'並根據需要修改行窗口部件。只要確保你總是修改行部件,因爲行可以被回收,所以你不一定知道你的部件的起始狀態是什麼。 – CommonsWare

+0

「,但每當我對列表執行某些操作(例如搜索)時,生成的列表就會丟失所有定製,直到我最小化鍵盤」 - 大概在您的getView()'實現中存在一個錯誤。我們無法幫助你,因爲你的問題不包含你的'getView()'代碼,更不用說任何關於定製丟失的描述了。隨意編輯你的問題,並添加這種東西,如果你想要特定的幫助。屏幕截圖也是有用的,但你可能需要在別處上傳並鏈接到它們,因爲你可能沒有代表直接上傳圖片。 – CommonsWare

+0

@CommonsWare我已經添加了自定義適配器類。基本上,當我加載活動(並填充列表)時,有一個短暫的時間列表未格式化。在任何格式化完成之前需要一秒鐘的時間。 – geft

回答

1

從我的評論引用自己:

第3步:如果你想有動態效果,基於模型數據,重寫getView()並根據需要修改行部件。只要確保始終修改行小部件,因爲行可以循環使用,所以您不必知道小部件的起始狀態。

就你而言,你並不總是在每個getView()調用上定製小部件。當convertView不是null時,您只會這樣做。 convertView將在null當您最初填充您的ListView

下面的實現總是調用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()都會增加太多開銷,那麼您可以查看優化事項。特別是在這種情況下,您希望爲每一行使用相同的字體 - 它不會根據要渲染的行而變化。在這種情況下,您只需致電setTypeface()撥打getView()致電,其中創建了新的TextView,並且應爲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); 
} 
+0

非常感謝。實際上,在看到你的答案之前,我遵循了你的第一個建議(找到實際的佈局文件並修改它),並且它完美地工作。儘管如此,你的答案也回答了我的問題。這對動態添加很有用。 – geft