Selektor koloru tła TextView


121

Próbuję zmienić kolor tła TextViewwidżetu Androida, gdy użytkownik go dotknie. W tym celu stworzyłem selektor, który jest przechowywany w res/color/selector.xmli z grubsza wygląda tak:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:color="@color/semitransparent_white"
        />
    <item
        android:color="@color/transparent"
        />
</selector>

clickableAtrybutem TextViewjest truew przypadku, który jest przedmiotem zainteresowania.

Kiedy przypisuję ten selektor do TextViewas android:background="@color/selector", otrzymuję następujący wyjątek w czasie wykonywania:

BŁĄD / AndroidRuntime (13130): spowodowane przez: org.xmlpull.v1.XmlPullParserException: binarny wiersz pliku XML nr 6: tag wymaga atrybutu „drawable” lub tagu podrzędnego definiującego element do rysowania

Kiedy zmieniam atrybut na rysowalny, działa, ale wynik wygląda zupełnie nieprawidłowo, ponieważ identyfikatory wydają się być interpretowane jako odniesienia do obrazu, a nie odniesienia do kolorów (jak sugeruje element „do rysowania”).

Wprawia mnie w zakłopotanie, że mogę bezpośrednio ustawić odniesienie koloru, np. „@ Kolor / czarny”, jako atrybut tła. To działa zgodnie z oczekiwaniami. Używanie selektorów nie działa.

Z selektora też mogę korzystać textColorbez problemów.

Jaki jest prawidłowy sposób zastosowania selektora koloru tła TextVieww systemie Android?


Kolor można interpretować jako rysowalny. Jak dokładnie wynik jest błędny?
Romain Guy

Zamiast tego pokazuje kolor, ale obraz z moich zasobów do rysowania jako tło.
digitalbreed

2
Powyższe powinno działać, jeśli używasz android: drawable, a nie android: color - przynajmniej w tym przypadku działa dla mnie: android: drawable = "@ color / my_custom_color". Moje kolory są zdefiniowane w values ​​/ colors.xml
AgentKnopf

Odpowiedzi:


226

Problem polega na tym, że nie możesz zdefiniować koloru tła za pomocą selektora kolorów, potrzebujesz selektora z możliwością rysowania . Tak więc niezbędne zmiany wyglądałyby następująco:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@drawable/selected_state" />
</selector>

Musisz również przenieść ten zasób do drawablekatalogu, w którym miałoby to większy sens, ponieważ nie jest to selektor kolorów jako taki.

Następnie musiałbyś utworzyć taki res/drawable/selected_state.xmlplik:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <solid android:color="@color/semitransparent_white" />
</shape>

i na koniec użyłbyś tego w ten sposób:

android:background="@drawable/selector"

Uwaga : powodem, dla którego OP pobierał zasób obrazu, jest prawdopodobnie to, że próbował po prostu odwołać się do swojego zasobu, który nadal był w katalogu kolorów, ale używał, @drawablewięc skończył się kolizją identyfikatorów, wybierając niewłaściwy zasób.

Mam nadzieję, że to nadal może komuś pomóc, nawet jeśli OP prawdopodobnie już, mam nadzieję, rozwiązał swój problem.


1
Dzięki, Benoit. Problem został rozwiązany (muszę przyznać, nie pamiętam, jak to zrobiłem w końcu) i projekt został pomyślnie zakończony. Cieszę się, że wróciłeś tutaj, aby publikować i pomagać ludziom, którzy mają ten sam problem w przyszłości.
digitalbreed

Nie mogę tego zrobić. Próbuję zastosować go do przycisku i ustawia tło na domyślny kolor selektora, ale nie zmienia się na kształt zdefiniowany w state_pressed. Czego mogłem przegapić? Mogę otworzyć nowe pytanie, na wypadek gdybyś wskazał mi właściwy kierunek.
Maragues

@Maragues trudno to stwierdzić, nie widząc żadnego kodu. Zalecam otwarcie nowego pytania i opublikowanie odpowiedniego kodu, abyśmy mogli dowiedzieć się, co może być nie tak. Możesz dodać komentarz do tego posta z linkiem do swojego nowego posta.
Benoit Martin,

9
Dlaczego nie użyć po prostu "drawable =" @ color / your_color "bezpośrednio w elementach selektora? Nie musisz definiować żadnych kształtów ani żadnych innych plików, po prostu miej definicje kolorów w values ​​/ colors.xml (zawsze dobrze nie do kodowania kolorów)
javaxian

Nie działa. Pokazuje mi inny kolor niż oba, które zadeklarowałem w kształcie XML.
Er Rohit Sharma,

122

Rozwiązanie Benoit działa, ale tak naprawdę nie musisz ponosić kosztów ogólnych, aby narysować kształt. Ponieważ kolory mogą być rysowalne, po prostu zdefiniuj kolor w pliku /res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="semitransparent_white">#77ffffff</color>
</resources>

Następnie użyj jako takiego w swoim selektorze:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@color/semitransparent_white" />
</selector>

Z jakiegoś powodu Twoje rozwiązanie nie pokazuje koloru, ale losowy obraz z mojego folderu zasobów do rysowania. Próbowałem wyczyścić projekt / naprawić właściwości / ponownie zapisać / ponownie otworzyć zaćmienie, ponieważ wydaje się to naprawdę dziwne, ale bezskutecznie. Dziwne.
Yahel

@Yahel Prawdopodobnie nazwałeś zasób do rysowania w kolorze tak samo jak rzeczywisty plik do rysowania?
Jona

@Jona: Nie, ale element do rysowania został nazwany background_application, a kolor do rysowania został nazwany background_white_transparent. Oba miały tło ... Widziałem w innym wątku to samo, co dzieje się z innymi, więc zgłosiłem to jako jeden z wielu błędów Androida i przerobiłem cały mój układ, aby go obejść.
Yahel

@Yahel Mmm ... Cóż, widzę ten problem, ale w moim przypadku nie są to te same nazwy plików ... Sprawdź moje pytania tutaj stackoverflow.com/questions/9004744/…
Jona

nie udało się, odpowiedź od Benoit Martina zadziałała.
Emmanuel Touzery

83

Jeszcze prostsze rozwiązanie powyższego:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <color android:color="@color/semitransparent_white" />
    </item>
    <item>
        <color android:color="@color/transparent" />
    </item>
</selector>

Zapisz to w folderze do rysowania i gotowe.


1
Może to działa, ale oficjalnie nie jest obsługiwane (Android Studio traktuje to jako błąd).
Blackhex

@Blackhex Strange. U mnie działa dobrze w Eclipse. Prawdopodobnie jest to błąd Lint, a jeśli tak, powinieneś być w stanie go wyłączyć lub zignorować.
Jason Robinson,

6
Oto, co uważam za rozwiązanie.
Lay González

<item android:state_pressed="true" android:color="@color/vantablack"/>wygląda semantycznie identycznie do<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis

16

Nawet to działa.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/dim_orange_btn_pressed" />
    <item android:state_focused="true" android:drawable="@color/dim_orange_btn_pressed" />
    <item android:drawable="@android:color/white" />
</selector>

Dodałem android:drawableatrybut do każdej pozycji, a ich wartościami są kolory.

Nawiasem mówiąc, dlaczego mówią, że colorjest to jeden z atrybutów selector? Nie piszą, że android:drawablejest to wymagane.

Zasób listy stanów kolorów

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_window_focused=["true" | "false"] />
</selector>

atrybut koloru działa, gdy ustawiasz kolory w widoku tekstu, ale nie z tłem, ponieważ w rzeczywistości kolory tła działają jak ColorDrawable
Dad

Najlepsze i najłatwiejsze do wdrożenia rozwiązanie ze wszystkich powyższych.
4gus71n

6

Kto szuka, aby to zrobić bez tworzenia sektora w tle, po prostu dodaj te linie do TextView

android:background="?android:attr/selectableItemBackground"
android:clickable="true"

Aby go również użyć do wyboru:

android:textIsSelectable="true"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.