2012-07-02 15 views

risposta

31

Come Romain Guy (Google Engineer funziona con il toolkit dell'interfaccia utente) Detto nel suo post

Impostando la larghezza su wrap_content si sta dicendo che ListView è largo quanto il più ampio dei suoi figli. ListView deve quindi misurare i suoi elementi e ottenere gli elementi che deve chiamare getView() sull'adapter. Questo può accadere più volte a seconda del numero di passaggi di layout, del comportamento del layout principale, ecc.

Quindi, se si imposta la larghezza del layout o l'altezza di layout di ListView su wrap_content, ListView proverà a misurare ogni singola vista che è collegato ad esso - che non è sicuramente quello che vuoi.

tenere a mente: l'impostazione evitano wrap_content per ListViews o GridView in ogni momento, per maggiori dettagli si veda questo Google I/O video parlare del mondo del listview

+8

Questo consiglio non sembra esattamente universale.La combinazione ListView/Adapater è più generica e scalabile di quanto le persone potrebbero realizzare all'inizio, il che significa che anche le persone potrebbero non rendersi conto delle conseguenze dell'utilizzo di wrap_content con insiemi di dati arbitrari. Ma questo non vuol dire che non ci sono molti casi in cui il set di dati è di dimensioni fisse o limitate. In questi casi, l'uso di wrap_content sarebbe più un giudizio. – spaaarky21

+3

Sembra che qualcosa di cui ci si deve preoccupare, ma al momento non funziona. –

+1

Non so perché questa risposta è stata accettata: non risponde affatto alla domanda. Pappagalli anche il post di Romain's Guy - che riguardava una domanda completamente diversa: il numero di volte in cui un layout viene misurato - e indica un video che in realtà spiega perché wrap_content dovrebbe funzionare, almeno per 3 voci di elenco e "una sorta di lavoro "per elenchi più complessi (ad un costo notevole delle prestazioni). – Rick77

3
I want my list view to wrap its content horizontally and not to fill all the width. 

In caso di List View non si può dare wrap_content, perché se si dà wrap_content per elenco Visualizza solo primi tre articoli (righe) verrà mostrata resto verrà ignorato .. Così don' t uso wrap_content .. usare sempre fill_parent o match_parent per elenco Visualizza

per la progettazione efficiente sulla lista Visualizza si può vedere questo World of ListView

+2

Non usare fill_parent. Era deprecato in Android 2.2: http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#FILL_PARENT – spaaarky21

29

Per raggiungere wrap_content altezza in ListView, abbiamo bisogno di usare CustomListView che extends il nostro nativo ListView.

MyListView.java

public class MyListView extends ListView { 

    private android.view.ViewGroup.LayoutParams params; 
    private int oldCount = 0; 

    public MyListView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 
     if (getCount() != oldCount) 
     { 
      int height = getChildAt(0).getHeight() + 1 ; 
      oldCount = getCount(); 
      params = getLayoutParams(); 
      params.height = getCount() * height; 
      setLayoutParams(params); 
     } 

     super.onDraw(canvas); 
    } 

} 

nel vostro layout uso visualizzazione personalizzata come questo,

layout.xml

<com.yourpackagename.MyListView 
     ...  
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     ... /> 
+0

Funziona perfettamente! – beetree

+1

Fantastico! Ha funzionato per me quando volevo usare un ListView all'interno di RecyclerView. – VSG24

+3

Questa risposta è utile, ma quando ListView si trova all'interno di RecyclerView, lo scorrimento verso l'alto sembra essere buggato. Quindi la vera soluzione è sovrascrivere il metodo onMeasure. Vedere questa risposta: http://stackoverflow.com/a/24186596/1901561 – RIscRIpt

3

Può essere implementato utilizzando LinearLayout Crea come questo esempio

public class LinearLayoutAdapter { 
LinearLayout linearLayout; 
ArrayList<String> arrayList 
private View rootView; 
private static LayoutInflater inflater; 
public ChoicesAdapter_(ArrayList<String> arrayList ,LinearLayout linearLayout) 
{ 
    this.index =index; 
    this.arrayList=arrayList; 
    this.linearLayout=linearLayout; 
    notifyDataSetChanged(); 
} 
private void notifyDataSetChanged() { 
    linearLayout.removeAllViews(); 
    for (int i =0;i<getCount();i++){ 
     linearLayout.addView(getView(i,null,null)); 
    } 
} 
public int getCount() { 
    return arrayList.size(); 
} 
public Object getItem(int position) { 
    return null; 
} 
public long getItemId(int position) { 
    return 0; 
} 
public View getView(final int position, View convertView, ViewGroup parent) { 
    rootView = inflater.inflate(R.layout.row_list, null); 
    TextView textView = (TextView)rootView.findViewById(R.id.text);  
    textView.setText(arrayList.get(position)); 
    return rootView; 
} 

MainActivity esempio

public class MainActivity extends Activity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ArrayList<String> arrayList = new ArrayList<String>(); 
    arrayList.add("Accent"); 
    arrayList.add("Acclaim"); 
    arrayList.add("Accord"); 
    arrayList.add("Achieva"); 
    arrayList.add("Aerio"); 
    arrayList.add("Aerostar"); 
    LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linearLayout); 
    linearLayoutAdapter= LinearLayoutAdapter(arrayList,linearLayout); 
} 

}

esempio XML

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@android:id/text" 
android:layout_width="match_parent" 
android:layout_height="50dp" 
android:gravity="center" 
android:textColor="@color/dark_gray" 
android:background="@color/white" 
android:textSize="20dp" 
android:text="" /> 
+0

Sì, è possibile farlo, ma si perde (o si ha molto da implementare) il sistema di riciclo per le visualizzazioni in elenco. Funziona bene per pochi oggetti ma, con pochi elementi, potresti non utilizzare una listview né un adattatore. –

Problemi correlati