2012-03-13 13 views
5

Mam ListView, który zawiera niestandardowe wiersze. Zwyczaj ten rząd ma następujące elementy interfejsuZmiana atrybutów widoku na pozycji pozycji listy

  1. ImageView imageView1, imageView2
  2. TextView textview1, textView2, textView3

Wymóg jest, gdy lista rząd jest wybrany nie byłyby następujące zmiany

imageView1 background, kolor został zmieniony

imageView1 kolor został zmieniony

textview1 kolor, wielkość i krój to zmienia kolor

textview2, rozmiar jest zmieniany

kolor textview3, rozmiar jest zmieniany

Jaki byłby najlepszy sposób zaprojektować dla tego?

AFAIK Nie możemy zastosować stylów w selektorze. Czy istnieje lepszy sposób pracy nad tym zamiast obsługi w kodzie Java?

Mamy setOnItemSelectedListener który może być ustawiony na ListView, który miałby następujące metody callback:

i) onItemSelected

ii) onNothingSelected

Jednak nie ma metody wywołania zwrotnego, która zawiera szczegółowe ustalenia dotyczące przedmiot, który stracił ostrość. Czy to jest lepsze miejsce do wprowadzania zmian?

Z góry dziękuję.

+0

"AFAIK nie możemy zastosować stylów w selektorze.Czy jest lepszy sposób pracować nad tym zamiast obsługi w kodzie Java?" Jeśli nie możesz tego zrobić w selektorze, jak inaczej można to zrobić, ale w Javie? Może mógłbyś zastąpić atrybuty stylu, do których odwołuje się domyślny selektor? – nmr

+0

Można zastosować style, aby zmienić kolor tła/rysowanie. Nie pomogłoby to zmienić rozmiaru czcionki. Czy muszę również określić selektor dla każdego z widoków podrzędnych? W kodzie java jak w, wewnątrz getView(). –

Odpowiedz

2

myślę, co chcesz tu zrobić, to stworzyć Compound Control. Możesz znaleźć przykład w swoim katalogu SDK w podkatalogu // Sample ApemDemos (możesz chcieć pobrać Android source, jeśli nie masz tych katalogów).

Co należy zrobić, to utworzyć klasę, która dziedziczy z dowolnego rodzaju układu używanego w niestandardowym wierszu. Załóżmy, że w tym przykładzie jest to LinearLayout. W konstruktorze podklasy można nadmuchać układ z zasobu, znaleźć podrzędne widoki i dołączyć je do zmiennych instancji, a następnie zwrócić LinearLayout do wywołującego.

W tej podklasie można zastąpić setSelected i manipulować widokami podrzędnymi w dowolny sposób.

Oto przykład tego, co opisuję na podstawie Twojego posta:

public class MyCustomLayout extends LinearLayout { 
    public ImageView imageView1; // These are public since you likely want 
    public ImageView imageView2; // to set them in your Adapter. 
    public TextView textView1; 
    public TextView textView2; 
    public TextView textView3; 

    public MyCustomLayout(Context ctxt) { 
     super(ctxt); 

     // The call below attaches the items in the mycustomlayout.xml file to this 
     // instance, which serves as the root element in the layout. 
     LayoutInflater.from(ctxt).inflate(R.layout.mycustomlayout, this, true); 

     imageView1 = (ImageView)findViewById(R.id.imageview1); 
     imageView2 = (ImageView)findViewById(R.id.imageview2); 
     textView1 = (TextView)findViewById(R.id.textview1); 
     textView2 = (TextView)findViewById(R.id.textview2); 
     textView3 = (TextView)findViewById(R.id.textview3); 
    } 

    @Override 
    public void setSelected(boolean selected) { 
     super.setChecked(selected); 
     if (selected) { 
      imageView1.setBackgroundColor(0xFFFF0000); // whatever color you want 
      // Do all the rest of the setting of your subviews here for 
      // the case when the row is selected. 
     } else { 
      imageView1.setBackgroundColor(0xFF000000); // whatever color you want 
      // Do all the rest of the setting of your subviews here for 
      // the case when the row is not selected 
     } 
    } 
} 

Teraz w mycustomlayout.plik xml, chcesz użyć tagu <merge> tak, aby nie tworzyć niepotrzebnych układ:

<merge xmlns:android="http://schemas.android.com/apk/res/android"> 
    <ImageView 
     android:id="@+id/imageview1" /> 
    <ImageView 
     android:id="@+id/imageview2" /> 
    <TextView 
     android:id="@+id/textview1" /> 
    <TextView 
     android:id="@+id/textview2" /> 
    <TextView 
     android:id="@+id/textview3" /> 
</merge> 

Mam pomijana całą konfigurację subviews powyżej, oczywiście, ale należy się pomysł o tym, jak skonfigurować plik XML. Możesz również zrobić to w kodzie, jeśli nie chcesz oszukać przy pomocy XML i LayoutInflater. Możesz spojrzeć na this helpful blog post na blogu deweloperów systemu Android, który omawia podobny przypadek pod koniec.

Następnie w adapterze getView można po prostu utworzyć (lub odtworzyć) instancje MyCustomLayout, skonfigurować je i pozwolić strukturze dbać o śledzenie, które wiersze są wybierane, a które nie są wybrane.

0

Mam prymitywny sposób ... ale jest to bardzo ciężki proces ... po wybraniu elementu odśwież swój listview ... tylko dla wybranego elementu powinien pokazać konkretną czcionkę itp ... i przechowywać identyfikator wybranego elementu w jakiejś zmiennej, aby go dopasować, wypełniając widoki w adapterze ...

0

Weź jedną statyczną zmienną całkowitą selectedPos na poziomie aktywności.

w zestawie onItemSelected, dla której zmienna selectedPos = position i onNothingSelected ustawiono ją na -1 i wywołanie notifyDataSetChanged() dla obiektu adaptera.

Teraz w klasie adaptera ListView. zapisu stanu w getView jak

if(position == selectedPos) 
{ 
    // set color and background to view 
} 

i nie zapomnij napisać to dwie metody w klasie adaptera

@Override 
public int getItemViewType(int position) { 
return position; 
} 

@Override 
public int getViewTypeCount() { 
return _ArrayListObject.size(); 
} 
+0

Dzięki soni. Jednakże oznaczałoby to ponowne rysowanie listView dla każdego wybranego elementu. Czy można tego w żaden sposób uniknąć? Również notifyDataSetChanged() powinien zostać wywołany, gdy "dane podstawowe zostały zmienione", co nie ma miejsca w tym przypadku. Czy nie ma wsparcia z frameworka do obsługi tego przypadku? –

+0

@hothotmanish nope .. :) :(Po prostu mam ten pomysł w głowie i myślę, że to zadziała dla ciebie .. – MKJParekh

0

Khotmanish,

Nie jestem pewien co masz na myśli przez to najbardziej efektywny droga. Istnieje wiele sposobów, które są bardzo szybkie, ale często zależy to od tego, co wiesz przed czasem, a czego nie.Należy również pamiętać, że właściwości dynamicznego widoku są mocno niezrozumiane, ale bardzo skuteczne pomimo popularnych mitów. Ludzie z Google wykonali niesamowitą robotę przy tworzeniu interfejsu użytkownika.

Jeśli znasz go z wyprzedzeniem, możesz po prostu utworzyć właściwość StateListDrawable dla każdego widoku i zastosować ją do każdego z nich w trakcie działania adaptera.

zbudować StateListDrawable, tworzyć jeden:

StateListDrawable _drawStates; 

Następnie, dla każdego stanu, dodać rozciągliwej czego potrzebujesz:

_drawStates.add(new int[] {android.R.attr.state_pressed}, _newImage); 

To jest tak proste, jak w poniższej linii w swojej getView () dla twojego adaptera:

v.setBackgroundDrawable(_drawStates); 

Alternatywnie możesz zmienić tło dynamicznie zgodnie z wyborem. Można to zrobić w OnListItemClick(). Zobaczysz, że OnListItemClick() wyświetli dokładny widok, który został kliknięty. Gdy już to zrobisz, możesz znaleźć dziecko przez jego id i zmienić jego właściwości i invalidate() go. Często używam tej sztuczki. Oszczędza mi to dużo pamięci, ale nie robię nic, co by naprawdę wymagało dużego procesora. Możesz zmienić prawie każdą nieruchomość tutaj bez prawie żadnego przetwarzania. Oto przykład:

@Override protected void onListItemClick(final ListView inList, final View v, final int atPos, final long rowID) 
{//Get the Child, set the properties 
    ImageView _img = (ImageView)(v.findViewById(R.id.app_package)); 
    _img.setBackgroundColor(myClickedColor); 
    _img.invalidate(); // <---- BEST Option 
// ... OR ... 
    v.invalidate();  // <---- 2nd Best Option 
// ... OR ... 
    inList.invalidate(); // <---- Last resort or specialized implementation 
} 

Ważne jest, aby pamiętać, że robienie tego dynamicznie ma pewne zastrzeżenia, jeśli chodzi o kolory tła. MUSISZ pobrać dziecko z klikniętego widoku ... Nie listy. Po drugie, zmieniając kolory tła, w rzeczywistości zmieniasz tło. Oznacza to, że wszystkie inne "stanowe" właściwości znikają i musisz je ręcznie zmienić (jeśli chcesz na początku).

Teraz bardziej popularnym, ale nieco mniej elastycznym podejściem jest zbudowanie StateListDrawable w XML. Jest wiele zasobów, aby dowiedzieć się, jak to zrobić w witrynie dla programistów Androida.

Nadzieja to pomaga, FuzzicalLogic

+0

Dzięki za odpowiedź Fuzzical Logic, jednak StateListDrawable zmieni tylko kolor/drawables. • Pomóż mi zmienić rozmiar czcionki, ale bardziej interesuję się stanem SelectSelect niż onClick (korzystałem z trackballa zamiast onTouch), dlatego onListItemClick nie pomoże mi w tym :(. dzięki za twoją krótką odpowiedź :) –

Powiązane problemy