2010-04-14 23 views
20

¿Cómo se puede ocultar un elemento en un ListView o al menos establecer su altura en cero?Android: cómo ocultar un elemento de ListView

He intentado establecer la visibilidad de la Vista a GONE, pero aún mantiene el espacio del artículo (alto).

+1

¿Estás seguro de sus comentarios sobre View.GONE? – Samuh

+0

Consulte http://stackoverflow.com/questions/5041499/how-to-hide-an-item-in-a-listview-in-android – mattlary

Respuesta

2

Hice algunos retoques con una lista de arrastrar y soltar desde here. Cuando un elemento se saca de la lista para ser movido por el espacio de la celda que ocupa tiene su altura establecida en 1px (vea la línea 238) para que parezca "desaparecido". No pude encontrar una manera de manejar esto mejor ya que establecer la altura en 0 falla al igual que la visibilidad GONE.

Dicho esto, si realmente desea deshacerse de una fila menos temporalmente, podría ser una buena idea cambiar el respaldo del Adapter y llamar al notifyDataSetChanged() en él.

0

añadir a su objeto ListView: androide: dividerHeight = "0px" androide: Divisor = "# FFFFFF"

de color Divisor no importa ajuste de sólo dividerHeight no funciona

Este elimina el divisor aunque ...

2

He visto el código fuente. Y solo hay una forma de ocultar el artículo sin notifyDataSetChanged(). Debe establecer la visibilidad GONE para todas las vistas interiores y eliminar la imagen de fondo y los rellenos para la vista del elemento.

Nota: Se podrá seleccionar la fila con dicho elemento invisible.

P.S: Esto es muy útil para ExpandableListView si quiere ocultar la vista grupal.

24

Resolviendo una pregunta anterior, pero acabo de tener este problema en el que quería ocultar elementos de la lista temporalmente en función de los criterios fuera de los datos de la lista. Lo que terminé haciendo fue crear un diseño de "elemento nulo" en xml y lo devolví según mis criterios en lugar de la vista de conversión en getView() ...

en lugar de devolver el convertView, devolví mi null_item ... .

return inflater.inflate(R.layout.null_item, null); 

null_item.xml:

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

</LinearLayout> 
+7

¿Por qué no solo devuelve un nuevo objeto de vista? De esta forma, no agregaría la sobrecarga de inflar la vista. – mdelolmo

+0

@tawani ¿esta solución propuesta no funcionó para usted? Por favor marca esto como respuesta. – Sufian

+4

El método de @ mdelolmo funciona. Acabo de probarlo y le ahorra la necesidad de archivos extra xml e inflación. Ni siquiera necesita establecer parámetros de diseño, simplemente 'devuelva una nueva Vista (contexto);' –

7

Cuando se trata de ListView, para que sea eficaz, utilizamos el patrón ViewHolder. La manera de utilizar Patrón ViewHolder y R.layout.row_null de la siguiente XML

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

es utilizar con getViewTypeCount() y getItemViewType(int position) de la siguiente manera.

@Override 
    public int getViewTypeCount() { 
     return 2; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return (hideStatusCheck(position)) ? 1 : 0; 
    } 

    @Override 
    public View getView(int pos, View convertView, ViewGroup parent) { 
     View rowView = convertView; 

     if (hideStatusCheck(pos)) { 
      if (rowView == null || rowView.getTag() != null) { 
       LayoutInflater inflater = mActivity.getLayoutInflater(); 
       rowView = inflater.inflate(R.layout.row_null, parent, false); 
      } 
     } else { 
      if (rowView == null) { 
       rowView = inflateNormalView(parent); 
      } else if (rowView.getTag() == null) { 
       rowView = inflateNormalView(parent); 
      } else { 
       ViewHolder holderToCheck = (ViewHolder) rowView.getTag(); 
       Integer storedPos = (Integer) holderToCheck.getTag(POSITION); 
       if (storedPos == null || storedPos != pos) 
        rowView = inflateNormalView(parent); 
      } 
      ViewHolder holder = (ViewHolder) rowView.getTag(); 
      holder.setTag(POSITION,pos); 
         /* 
         Populate data 
         */ 
      return rowView; 
    } 

    private View inflateNormalView(ViewGroup parent) { 
        View rowView; 
     LayoutInflater inflater = mActivity.getLayoutInflater(); 
     rowView = inflater.inflate(R.layout.normal_item, parent, false); 
     ViewHolder viewHolder = new ViewHolder(); 
     assert rowView != null; 
        /* Initiate normal findViewById thing*/ 
     rowView.setTag(viewHolder); 
     return rowView; 
    } 

que hacemos la comprobación de del elemento Ver tipo y si cumple con la verificación Ocultar, devolverá 1, de lo contrario 0. El ListView sabe que habrá 2 tipos de Vista desde getViewTypeCount. Ahora, getView devolverá la vista apropiada dependiendo de hideStatusCheck. Para hacer un ListView robusto, queremos usar el patrón ViewHolder. No necesitamos usar ViewHolder cuando está oculto. Simplemente inflemos R.layout.row_null y lo devolvemos. Usaremos ViewHolder para R.layout.normal_item. Aquí está la parte difícil asumiendo que el cheque de ocultación no es estático. El primer cheque de rowView==null es estándar.La segunda comprobación de rowView.getTag()==null es ver si la Vista vuelve a la normalidad desde su escondite. El tercer control en la última cláusula else es comprobar si el ViewHolder retenido en la etiqueta es el ViewHolder correcto. Si se cumplen estas condiciones, siempre inflemos la vista nuevamente. Sí, es cierto que, el patrón ViewHolder no se usa en todas partes, pero se usa para ciertas extensiones. Es mejor que nada.

0

Creo que tengo una solución mucho más fácil/más segura: solo tiene que "incrustar" su elemento en un Diseño, y cambiar la visibilidad de este diseño principal.

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

    <!-- Embed ListView Item into a "parent" Layout --> 
    <LinearLayout 
     android:id="@+id/parentLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- This is the normal content of your ListView Item --> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Hello" /> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="World" /> 

    </LinearLayout> 
</LinearLayout> 

Luego, en su código simplemente hacer:

public View getView(int position, View view, ViewGroup parent) { 
    if (view == null) { 
     LayoutInflater li = mActivity.getLayoutInflater(); 
     view = li.inflate(R.layout.my_listview_item, null); 
    } 
    LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout); 
    if (shouldDisplayItem(position)) { 
     parentLayout.setVisibility(View.VISIBLE); 
    } else { 
     parentLayout.setVisibility(View.GONE); 
    } 
    return view; 
} 

Este modo de usar siempre/reutilizar el mismo tema, y ​​acaba de ocultar/mostrar la misma.

+0

Esta es la respuesta correcta que iba a escribir :) –

11

si desea ocultar el elemento de la siguiente manera:

convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1)); 
convertView.setVisibility(View.GONE); 

no pueden ser AbsListView.LayoutParams (-1,0);

si convertview se reutilizan se debe añadir esto a continuación para ajustar la altura del respaldo que:

if(convertView.getVisibility() == View.GONE) { 
    convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT)); 
    convertView.setVisibility(View.VISIBLE); 
} 
Cuestiones relacionadas