2012-07-02 31 views

Respuesta

31

Como Romain Guy (Google Engineer trabaja en el kit de herramientas de UI) Dijo en su publicación

Al establecer el ancho en wrap_content le está diciendo a ListView que sea tan ancho como el más amplio de sus hijos. ListView debe por lo tanto medir sus elementos y obtener los elementos que tiene que llamar getView() en el Adaptador. Esto puede suceder varias veces dependiendo del número de pases de disposición, el comportamiento del diseño principal, etc.

Así que si establece el ancho de diseño o la altura de diseño de su ListView en wrap_content el ListView intentará medir cada vista individual que está unido a él, que definitivamente no es lo que quieres.

tener en cuenta: el establecimiento de evitar wrap_content para listviews o GridViews en todo momento, para más detalles ver este Google I/O video hablar sobre el mundo de vista de lista

+8

Este consejo no parece exactamente universal.La combinación ListView/Adapater es más genérica y escalable de lo que la gente podría pensar al principio, lo que significa que las personas también podrían no darse cuenta de las consecuencias de usar wrap_content con conjuntos de datos arbitrarios. Pero eso no quiere decir que no haya muchos casos en los que el conjunto de datos tenga un tamaño fijo o limitado. En esos casos, usar wrap_content sería más una decisión de juicio. – spaaarky21

+3

Esto parece algo sobre lo que la pelusa debería advertir, pero actualmente no lo hace. –

+1

No sé por qué se aceptó esta respuesta: no responde la pregunta en absoluto. También repite como loro la publicación Guy de Romain, que era una pregunta completamente diferente: el número de veces que se mide un diseño, y apunta a un video que explica por qué debería funcionar wrap_content, al menos para 3 elementos de la lista y "tipo de trabajo "para listas más complejas (a un costo de rendimiento considerable). – Rick77

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

En caso de Lista Vista no se puede dar wrap_content, porque si se le da wrap_content de Lista Ver sólo tres primeros artículos (filas) se mostrará resto será ignorada .. Así que no t uso wrap_content .. siempre use fill_parent o match_parent de Lista ver

para el diseño eficiente de la Lista de Vista se puede ver este World of ListView

+2

No utilice fill_parent. Fue desaprobado en Android 2.2: http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#FILL_PARENT – spaaarky21

29

Para lograr wrap_content altura en ListView, tenemos que utilizar CustomListView ese extends nuestro 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); 
    } 

} 

en su uso layout vista personalizada como esta,

layout.xml

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

¡Funciona a la perfección! – beetree

+1

¡Fantástico! Funcionó para mí cuando quería usar un ListView dentro de RecyclerView. – VSG24

+3

Esta respuesta es útil, pero cuando ListView está dentro de un RecyclerView, el desplazamiento hacia arriba parece tener errores. Entonces la verdadera solución es anular el método de medición. Consulte esta respuesta: http://stackoverflow.com/a/24186596/1901561 – RIscRIpt

3

Se puede implementar mediante el uso de LinearLayout Crear como este ejemplo

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

ejemplo MainActivity

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

}

ejemplo 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í, puede hacerlo, pero pierde (o tiene mucho que implementar) el sistema de reciclaje para las visualizaciones de elementos de lista. Funciona bien para pocos artículos pero, con pocos elementos, puede considerar no usar un listview ni un adaptador. –

Cuestiones relacionadas