簡體   English   中英

多次調用自定義列表視圖適配器 getView 方法,並且順序不一致

[英]custom listview adapter getView method being called multiple times, and in no coherent order

我有一個自定義列表適配器:

class ResultsListAdapter extends ArrayAdapter<RecordItem> {

在覆蓋的“getView”方法中,我打印以檢查位置是什么以及它是否是 convertView:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        System.out.println("getView " + position + " " + convertView);

這個的輸出(當列表首次顯示時,還沒有用戶輸入)

04-11 16:24:05.860: INFO/System.out(681): getView 0 null  
04-11 16:24:29.020: INFO/System.out(681): getView 1 android.widget.RelativeLayout@43d415d8  
04-11 16:25:48.070: INFO/System.out(681): getView 2 android.widget.RelativeLayout@43d415d8  
04-11 16:25:49.110: INFO/System.out(681): getView 3 android.widget.RelativeLayout@43d415d8  
04-11 16:25:49.710: INFO/System.out(681): getView 0 android.widget.RelativeLayout@43d415d8  
04-11 16:25:50.251: INFO/System.out(681): getView 1 null  
04-11 16:26:01.300: INFO/System.out(681): getView 2 null  
04-11 16:26:02.020: INFO/System.out(681): getView 3 null  
04-11 16:28:28.091: INFO/System.out(681): getView 0 null  
04-11 16:37:46.180: INFO/System.out(681): getView 1 android.widget.RelativeLayout@43cff8f0  
04-11 16:37:47.091: INFO/System.out(681): getView 2 android.widget.RelativeLayout@43cff8f0  
04-11 16:37:47.730: INFO/System.out(681): getView 3 android.widget.RelativeLayout@43cff8f0  

AFAIK,雖然我找不到明確說明,但 getView() 僅對可見行調用。 由於我的應用程序以四個可見行開頭,因此至少從 0-3 循環的位置編號是有意義的。 但剩下的就是一團糟:

  • 為什么每行調用 getview 三次?
  • 當我還沒有滾動時,這些 convertViews 來自哪里?

我做了一些研究,但沒有得到好的答案,我確實注意到人們將這個問題與布局問題聯系起來。 因此,以防萬一,這是包含列表的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent" 
    android:orientation="vertical" >

    <TextView android:id="@+id/pageDetails"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" />

    <ListView android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:drawSelectorOnTop="false" />

</LinearLayout>

以及每一行的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="108dp"    
android:padding="4dp">

<ImageView
    android:id="@+id/thumb"        
    android:layout_width="120dp"
    android:layout_height="fill_parent"        
    android:layout_alignParentTop="true"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_marginRight="8dp"        
    android:src="@drawable/loading" />

<TextView  
    android:id="@+id/price"
    android:layout_width="wrap_content"
    android:layout_height="18dp"         
    android:layout_toRightOf="@id/thumb"
    android:layout_alignParentBottom="true"       
    android:singleLine="true" />

<TextView  
    android:id="@+id/date"
    android:layout_width="wrap_content"
    android:layout_height="18dp"         
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true" 
    android:paddingRight="4dp"       
    android:singleLine="true" />

<TextView
    android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="17dp" 
    android:layout_toRightOf="@id/thumb"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:paddingRight="4dp"   
    android:layout_alignWithParentIfMissing="true"
    android:gravity="center" />

</RelativeLayout>

感謝您的時間

這不是問題,絕對不能保證調用getView()的順序或調用次數。 在您的特定情況下,通過給ListView一個height=wrap_content ,您正在做最糟糕的事情。 這迫使ListView在布局時測量適配器之外的幾個子項,以了解它應該有多大。 這就是為ListView提供你看到的轉換視圖,甚至在你滾動之前傳遞給convertViews getView()的原因。

嘗試在列表視圖的layout_height屬性上使用match_parent 它將防止getView()被如此頻繁地調用。

當我將 layout_width 和 layout_height 都更改為match_parent時,我擺脫了這個問題(僅更改 layout_height 沒有幫助)。


有用的注釋請注意您是否有嵌套項目。 您必須將“最高”更改為match_parent 希望它可以幫助某人。

我無法回答您的“為什么”問題,但我絕對有辦法解決煩人的“ ListView items repeating ”問題(如果您的收藏中有超過屏幕高度的項目)。

正如上面許多人提到的,將ListVew標簽的android:layout_height屬性保留為fill_parent

關於 getView() 函數,解決方案是使用一個名為ViewHolder靜態類 看看這個例子。 它成功地完成了在 Array 或 ArrayCollection 中添加所有項目的任務。

希望對朋友有幫助!!

最好的問候, Siddhant

問:為什么Adapter會多次調用getView()? Ans:由於 Listview 在滾動時呈現是用下一個即將出現的視圖刷新它的視圖,為此適配器需要通過調用 getView() 來獲取視圖。

問題:如果列表視圖的寬度和高度設置為fill_parent,為什么它的調用更少? Ans: 因為充氣機對於列表的屏幕區域具有固定大小,所以它計算一次以將視圖渲染到屏幕上。

希望它能解決您的疑問。

我在 AutoCompleteTextView 中的下拉菜單中遇到了同樣的問題。 我與這個問題斗爭了兩天,直到我到達這里,你告訴我解決方案。

如果我寫 dropDownHeight="match_parent" 問題就解決了。 現在問題與 UI 有關(當您有一個項目時,下拉菜單太大)但多次調用的問題(更重要)已得到修復。

謝謝!!

對於所有仍然(在將ListViewheight設置為match_parent之后)被卡住的人(就像我一樣):

您還必須將父布局的height設置為match_parent

請參見下面的示例。 LinearLayout是這里的父級:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/something" />

        <ListView
            android:id="@+id/friendsList"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

“為什么每行調用 getview 三次?” 因為當您在 listview 上滾動時會調用 getView 並且更好地說,當您的列表視圖的位置發生更改時會調用它!

我有同樣的問題。 如果我將高度設置為 fill_parent,那么我會“通常”每行得到 2 個調用。 但是,如果我將 ListView 的高度設置為精確值,假設為 300dp,那么我每行都會得到一個 GetView 調用。

因此,在我看來,唯一的方法是首先確定屏幕的高度,然后以編程方式將 listview 的高度設置為該值。 我不喜歡它。 我希望有更好的方法。

這可能來晚了,但如果你使用layout_weight記得總是設置layout_width="0dp"

我做了這個解決方案,也許不是最好的,但確實有效......

//initialize control string
private String control_input = " ";

然后 =

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

    View gridview = convertView;

    // change input_array for the array you use
    if (!control_input.equals(input_array[position])) {
        control_input = input_array[position];

        //do your magic

    } 

    return gridview;
}

希望能幫助到你!

我有一個類似的問題, getView在索引 0 ( i = 0 )上被調用了三次,然后再繼續。 在我的情況下,我想計算物品的總價格,但是由於這個問題,第一個物品被計算為 x3。 為了解決這個問題,我創建了一個int indexFix = 0; 並在i改變時增加它

    if (indexFix == i)
    {
        Total += itemTotal;
        indexFix++;
    }

我嘗試了上述解決方案,但在我的情況下似乎都沒有。 如果您無法修復它,只需控制在getView中執行的操作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM