2013-06-28 21 views
1

因此,我正在製作此應用程序。該應用程序解析一個網站,或更具體地說,一個vbulletin板。當我在論壇中解析一個線程時,我已經將它分開了,這樣當我解析該線程中的每個帖子時,我會在這個部分中獲得帖子的實際內容,並且按照正確的順序存儲這些部分在一個陣列:ListView適配器具有任意數量的行類型(不知道不同行類型的數量)

[Plain text] 
[Quote from somebody] 
[Plain text] 
[Another quote] 
[Another quote again] 
[Some more plain text] 

然而,後可以以任意順序排列你可能知道的,可以由比示例更多或更少的部分,它不必有它的報價或者,它可能只是一個或幾個引號。一切皆有可能。

當我在我的應用程序中列出帖子時,我使用了一個ListView。這個列表視圖的每一行然後是總是由標題和前面提到的部分的任意組合組成。

我一直在想Google搜索的方式是在一個XML文件中只有一個「基本佈局」,只有一個佈局標籤,並且每個部分都有獨立的佈局,分開存儲XML文件,並且在我的適配器中每次調用getView()時,都會查看我的「Post-list」中該位置的帖子,然後遍歷該帖子中的各個部分,並將新的「Quote-layout 「存儲在帖子中的每個引用部分,併爲帖子中的每個純文本部分填充」純文本佈局「。併爲每個人填寫屬於該職位的所有內容。

我認爲這可行,但可能存在性能問題?據我瞭解,它的佈局通貨膨脹是相當昂貴的,我不能夠回收視圖傳遞給getView(),因爲它可能有一堆的部分添加到它,我可能不需要在另一個調用getView ()..也就是說,如果我理解getView()和回收有點。

這是我與適配器的getView()方法是指一個基本的例子:

@Override 
public View getView(int i, View view, ViewGroup viewGroup) { 
    // Inflate the base-layout, which the others are added to. 
    view = mInflater.inflate(R.layout.forum_post,null); 

    View header = mInflater.inflate(R.layout.post_header_layout, null); 
    View message = mInflater.inflate(R.layout.post_text_layout, null); 
    View quote = mInflater.inflate(R.layout.post_quote_layout, null); 

    ((ViewGroup)view).addView(header); 
    ((ViewGroup)view).addView(message); 
    ((ViewGroup)view).addView(quote); 
    return view; 
} 

然後膨脹更多報價的視圖/消息的視圖在需要時我提取數據從我保存的帖子列表中。

的基佈局僅僅是一個的LinearLayout標籤

我膨脹只是RelativeLayouts一些TextViews的佈局和一個ImageView的加入。

此代碼生成這樣的結果,其中,我有一個部首與 用戶名,圖片,等等。,純文本,和一個報價截面的一個部分。 這似乎並不雖然能夠正常工作的時候,因爲當我嘗試了一下剛纔好像列表的副本卡的背景和另外一個滾動在它的上面得到..

http://s14.postimg.org/rizid8q69/view.png

有沒有更好的方法來做到這一點?因爲我想這不是很有效率

+0

你想膨脹你的行在列表視圖中不同的佈局? – Raghunandan

回答

5

您需要覆蓋getViewItemTypegetViewTypeCount

getItemViewType(int position) - 返回一個佈局類型,你應該使用基於

位置

然後你誇大佈局只有當它的零和使用getItemViewType確定類型信息。

例子:

private static final int TYPE_ITEM1 = 0; 
    private static final int TYPE_ITEM2 = 1; 
    private static final int TYPE_ITEM3 = 2; 
    @Override; 
    public int getItemViewType(int position) 
    { 
    int type; 
    if (position== 0){ // your condition 
     type = TYPE_ITEM1; //type 0 for header 
    } else if(position == 1){ 
     type = TYPE_ITEM2; //type 1 for message 
    }else { 
     type = TYPE_ITEM3; //type 2 for Quote 
    } 
    return type; 
    } 
@Override 
public int getViewTypeCount() { 
    return 3; //three different layouts to be inflated 
} 

getView

int type= getItemViewType(i); // determine type using position. 
switch (type) { 
case TYPE_ITEM1: 
    view= mInflater.inflate(R.layout.post_header_layout, null); // inflate layout for header 
break; 
case TYPE_ITEM2: 
    view = mInflater.inflate(R.layout.post_text_layout, null); // inflate layout for quote 
break; 
case TYPE_ITEM3: 
     quote = mInflater.inflate(R.layout.post_quote_layout, null); // inflate layout for message 
break;  
.... 

您需要使用View持有人的平滑滾動和性能。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

您可以檢查以下

http://android.amberfog.com/?p=296

+0

@ user1944184不知道如何膨脹佈局? – Raghunandan

+0

我想你誤會了?因爲我知道我有兩種不同類型的行時,在另一個適配器中使用了這兩種方法。 但是,這次您的getItemViewType()中的每個類型都不是ListView中的單獨行,它們在ListView中的每行中都是單獨的行,並且ListView中可以有任意數量的type2和type3行行。 已經檢查了教程,但它沒有幫助,因爲我的列中的行不是一組不同的類型 也許我沒有解釋我的問題很好.. 也許我必須以編程方式 – user1944184

+0

@ user1944184哇!我真的不明白你的問題。對不起,不能進一步幫助。 – Raghunandan

0

首先要重用已作爲參數傳遞一個的convertView教程。這樣你可以避免給物品充氣View。其次,你可以使用ViewHolder這樣的東西來存儲對你的View s的引用。使用ViewHolder可以提高性能,無論您是在擴大視圖還是通過id查找它們,因爲這兩種方法都非常昂貴。

ViewHolder設置爲項目View上的標籤。

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View view; 
    ViewHolder viewHolder; 

    // if possible reuse view 
    if (convertView == null) { 
     final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(resource, parent, false); 
     viewHolder = new ViewHolder(mInflater.inflate(R.layout.post_header_layout, null)); 
     view.setTag(viewHolder); 
    } else { 
     // reuse view 
     view = convertView; 
     viewHolder = (ViewHolder) view.getTag(); 
    } 

    //set text, listeners, icon, etc. 

    return view; 
} 

ViewHolder只是引用視圖的私有內部類存儲。

私有靜態類ViewHolder {

private final View view; 

    private ViewHolder(View view) { 
     this.view = view; 
    } 
} 

ListView使用在Google IO 2010給出。

0

充氣器需要知道真實的類型,即將成爲父母的ViewGroup的,因此下面的代碼是錯誤的:

view = mInflater.inflate(R.layout.forum_post,null); 

,相反,你應該使用這一個:

view = mInflater.inflate(R.layout.forum_post,viewGroup,false); 

同樣的事情對於其他inflate:使用真實父代(在此情況下爲view)或與(未來)父代具有相同類型的其他viewGroup;否則LayoutParameters將不會被設置爲正確的類型,並且您在XML代碼中指定的值將會丟失(從未使用過)。

相關問題