2010-04-14 15 views
20

Jak ukryć przedmiot w oknie listy lub przynajmniej ustawić jego wysokość na zero?Android: jak ukryć element ListView?

Próbowałem ustawić widoczność widoku na GONE, ale nadal utrzymuje przestrzeń (wysokość) przedmiotu.

+1

Czy jesteś pewien swojej komentarzu View.GONE? – Samuh

+0

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

Odpowiedz

2

Zrobiłem kilka majsterkowania z listy przeciągnij i upuść z here. Kiedy przedmiot zostanie wysunięty z listy, aby go przesunąć w obrębie zajmowanej przez niego komórki, jego wysokość jest ustawiona na 1 piksel (patrz linia 238), więc wydaje się, że "zniknął". Nie mogłem znaleźć sposobu, aby lepiej sobie z tym poradzić, ponieważ ustawienie wysokości na 0 kończy się niepowodzeniem, ponieważ widoczność GONE.

To powiedziawszy, jeśli naprawdę chcesz pozbyć się wiersza mniej tymczasowo, dobrym pomysłem może być zmiana podkładu Adapter i zadzwonić pod numer i zadzwonić pod numer .

0

dodać do obiektu ListView: android: dividerHeight = "0px" android: dzielnik = "# FFFFFF"

Przegroda kolor nie ma znaczenia tylko ustawienie dividerHeight nie działa

ten czy usunąć dzielnik ...

2

Mam spojrzenie na kod źródłowy. I jest tylko jeden sposób na ukrycie przedmiotu bez notifyDataSetChanged(). Musisz ustawić widoczność GONE dla wszystkich widoków wewnętrznych i usunąć obraz tła i wypustki dla widoku elementu.

Uwaga: Wiersz z takim niewidocznym elementem będzie można wybrać.

P.S: Jest to bardzo przydatne dla ExpandableListView, jeśli chcesz ukryć widok grupy sam.

24

Odzyskuję stare pytanie, ale właśnie miałem ten problem, gdy chciałem tymczasowo ukrywać elementy listy w oparciu o kryteria poza danymi z listy. W końcu robiłem tworzenie układu "pustego elementu" w xml i zwracałem to na podstawie moich kryteriów zamiast widoku konwersji w getView() ...

zamiast zwracania convertView, zwróciłem moją 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

Dlaczego nie po prostu zwrócić nowy obiekt View? W ten sposób nie dodasz narzutów związanych z nadmuchiwaniem widoku. – mdelolmo

+0

@tawani czy to zaproponowane rozwiązanie nie zadziałało dla ciebie? Proszę oznaczyć to jako odpowiedź. – Sufian

+4

Metoda @ mdelolmo działa. Właśnie przetestowałem to i to oszczędza ci potrzebę dodatkowych plików xml i inflacji. Nie musisz nawet ustawiać parametrów układu, po prostu 'return new View (context);' –

7

Kiedy przychodzi do ListView, aby to wydajny, używamy ViewHolder wzór. Sposób korzystania ViewHolder Wzorzec i R.layout.row_null z następujących 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> 

jest do korzystania z getViewTypeCount() i getItemViewType(int position) następująco.

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

Robimy Sprawdzenie elementu View Typ i jeśli spełnia on hide czek, to zwraca 1, w przeciwnym wypadku 0. ListView wie, że będą 2 rodzaje Widok z getViewTypeCount. Teraz getView zwróci odpowiedni widok w zależności od hideStatusCheck. Aby stworzyć solidny ListView, chcemy użyć wzorca ViewHolder. Nie musimy używać ViewHolder, gdy jest on ukryty. Po prostu pompujemy R.layout.row_null i zwracamy. Będziemy używać ViewHolder dla R.layout.normal_item. Oto trudna część, zakładając, że kontrola ukrywania nie jest statyczna. Pierwsza kontrola rowView==null jest standardowa.Drugim sprawdzeniem rowView.getTag()==null jest sprawdzenie, czy widok powraca do stanu normalnego z ukrycia. Trzecim sprawdzeniem w ostatniej klauzuli else jest sprawdzenie, czy obiekt ViewHolder zachowany w tagu jest prawym ViewHolder. Jeśli te warunki zostaną spełnione, zawsze zawyżamy widok. Tak, prawdą jest, że wzorzec ViewHolder nie jest używany w całości, ale wykorzystuje pewne rozszerzenia. To lepsze niż nic.

0

Myślę, że mam o wiele łatwiejsze/bezpieczniejsze rozwiązanie: wystarczy "osadzić" swój przedmiot w układzie i zmienić widoczność tego układu nadrzędnego.

<?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> 

Następnie w kodzie po prostu zrobić:

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

W ten sposób można zawsze stosować/używać tego samego elementu, a po prostu ukryć/pokazać.

+0

To jest poprawna odpowiedź, którą zamierzałem napisać :) –

11

jeśli chcesz ukryć element takiego:

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

nie może być AbsListView.LayoutParams (-1,0);

jeśli convertview są ponownie wykorzystywane należy dodać to poniżej, aby ustawić go z powrotem wysokość:

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