Próbuję zmienić element do rysowania, który znajduje się w widżecie widoku paska akcji systemu Android.
Obecnie wygląda to tak:
ale muszę zmienić niebieskie tło do rysowania na kolor czerwony.
Próbowałem wielu rzeczy poza rozwijaniem własnego widgetu wyszukiwania, ale wydaje się, że nic nie działa.
Czy ktoś może wskazać mi właściwy kierunek, aby to zmienić?
SearchView
tła, ponieważ nie jest ono dostępne w trybie za pośrednictwemR.styleable
. Moja odpowiedź poniżej opisuje, jak to zrobić w kodzie.Odpowiedzi:
Intro
Niestety nie ma sposobu na ustawienie
SearchView
stylu pola tekstowego za pomocą motywów, stylów i dziedziczenia w XML, tak jak można to zrobić z tłem elementów w menu rozwijanym ActionBar . Dzieje się tak, ponieważselectableItemBackground
jest wymieniony jako podlegający stylizacji wR.stylable
, podczas gdysearchViewTextField
(atrybut motywu, który nas interesuje) nie. Dlatego nie możemy uzyskać do niego łatwego dostępu z zasobów XML (pojawi sięNo resource found that matches the given name: attr 'android:searchViewTextField'
błąd).Ustawianie tła pola tekstowego SearchView z kodu
Tak więc jedynym sposobem na poprawne podstawienie tła
SearchView
pola tekstowego jest wejście do jego wnętrza, uzyskanie dostępu do widoku, który ma ustawione tłosearchViewTextField
i ustawienie własnego.UWAGA: Poniższe rozwiązanie zależy tylko od id (
android:id/search_plate
) elementu wewnątrzSearchView
, więc jest bardziej niezależne od wersji SDK niż przechodzenie dzieci (np. Użycie,searchView.getChildAt(0)
aby uzyskać właściwy widok wewnątrzSearchView
), ale nie jest kuloodporne. Zwłaszcza jeśli jakiś producent zdecyduje się na ponowne zaimplementowanie elementów wewnętrznychSearchView
i brak elementu o podanym powyżej id - kod nie zadziała.W SDK tło pola tekstowego w
SearchView
jest deklarowane za pomocą dziewięciu łat , więc zrobimy to w ten sam sposób. Oryginalne obrazy png można znaleźć w katalogu drawable-mdpi repozytorium git systemu Android . Interesują nas dwa obrazy. Jeden dla stanu, gdy zaznaczone jest pole tekstowe (o nazwie textfield_search_selected_holo_light.9.png ), a drugi dla miejsca, w którym go nie ma (o nazwie textfield_search_default_holo_light.9.png ).Niestety, będziesz musiał utworzyć lokalne kopie obu obrazów, nawet jeśli chcesz dostosować tylko stan skupienia . Dzieje się tak, ponieważ
textfield_search_default_holo_light
nie ma go w R.drawable . W związku z tym nie jest łatwo dostępny za pomocą@android:drawable/textfield_search_default_holo_light
, którego można użyć w selektorze pokazanym poniżej, zamiast odwoływania się do lokalnego drawable.UWAGA: użyłem motywu Holo Light jako podstawy, ale możesz zrobić to samo z Holo Dark . Wydaje się, że nie ma istotnej różnicy w wybranych państwowych 9-łaty między Światła i Ciemności tematów. Istnieje jednak różnica w 9 łatach dla stanu domyślnego (patrz Jasny kontra Ciemny ). Więc prawdopodobnie nie ma potrzeby tworzenia lokalnych kopii 9 poprawek dla wybranego stanu , zarówno dla motywów Dark i Light (zakładając, że chcesz obsłużyć oba i sprawić, by wyglądały tak samo jak w Holo Theme ). Po prostu wykonaj jedną lokalną kopię i użyj jej wselektor do rysowania dla obu tematów.
Teraz musisz edytować pobrane dziewięć poprawek według swoich potrzeb (tj. Zmieniając kolor niebieski na czerwony). Możesz rzucić okiem na plik za pomocą narzędzia Draw 9-patch, aby sprawdzić, czy jest poprawnie zdefiniowany po edycji.
Edytowałem pliki za pomocą GIMP-a z jednym pikselowym narzędziem ołówka (dość łatwe), ale prawdopodobnie użyjesz własnego narzędzia. Oto moja dostosowana łatka 9 dla stanu skupienia :
UWAGA: Dla uproszczenia użyłem tylko obrazów dla gęstości mdpi . Będziesz musiał utworzyć 9 łatek dla wielu gęstości ekranu, jeśli chcesz uzyskać najlepszy wynik na dowolnym urządzeniu. Obrazy dla Holo
SearchView
można znaleźć w formacie mdpi , hdpi i xhdpi do rysowania.Teraz musimy utworzyć selektor do rysowania, aby odpowiedni obraz był wyświetlany na podstawie stanu widoku. Utwórz plik
res/drawable/texfield_searchview_holo_light.xml
z następującą zawartością:Użyjemy powyższego utworzonego drawable, aby ustawić tło dla
LinearLayout
widoku, który zawiera pole tekstoweSearchView
- jego identyfikator toandroid:id/search_plate
. Oto jak to zrobić szybko w kodzie podczas tworzenia menu opcji:Efekt końcowy
Oto zrzut ekranu końcowego wyniku:
Jak do tego doszedłem
Myślę, że warto poznać, jak do tego doszedłem, aby to podejście można było wykorzystać podczas dostosowywania innych widoków.
Sprawdzam układ widoku
Sprawdziłem, jak
SearchView
wygląda układ. W konstruktorze SearchView można znaleźć wiersz, który zawyża układ:Teraz wiemy, że
SearchView
układ znajduje się w pliku o nazwieres/layout/search_view.xml
. Spoglądając na search_view.xml , możemy znaleźć wewnętrznyLinearLayout
element (z idsearch_plate
), który maandroid.widget.SearchView$SearchAutoComplete
wewnątrz (wygląda jak nasze pole tekstowe widoku wyszukiwania):Teraz wiemy, że tło jest ustawione na podstawie
searchViewTextField
atrybutu bieżącego motywu .Badanie atrybutu (czy jest to łatwe do ustalenia?)
Aby sprawdzić, jak
searchViewTextField
ustawiany jest atrybut, sprawdzamy plik res / values / themes.xml . Istnieje grupa atrybutów powiązanychSearchView
domyślnieTheme
:Widzimy, że dla motywu domyślnego wartością jest
@drawable/textfield_searchview_holo_dark
. DlaTheme.Light
wartości jest także ustawić w tym pliku .Byłoby wspaniale, gdyby ten atrybut był dostępny przez R.styleable , ale niestety tak nie jest. Dla porównania zobacz inne rozrywki atrybuty, które są obecne zarówno w themes.xml i R.attr jak textAppearance lub selectableItemBackground . Gdyby
searchViewTextField
był obecny wR.attr
(iR.stylable
), moglibyśmy po prostu użyć naszego selektora do rysowania podczas definiowania motywu dla całej naszej aplikacji w XML. Na przykład:Co należy zmodyfikować?
Teraz wiemy, że będziemy musieli uzyskać dostęp
search_plate
przez kod. Jednak nadal nie wiemy, jak to powinno wyglądać. Krótko mówiąc, wyszukujemy obiekty do rysowania używane jako wartości w domyślnych motywach: textfield_searchview_holo_dark.xml i textfield_searchview_holo_light.xml . Patrząc na treść, widzimy, że to,selector
co można rysować, odnosi się do dwóch innych rysunków (które później są 9-łatkami) w oparciu o stan widoku. Zagregowane elementy do rysowania z 9 łatkami z (prawie) wszystkich wersji Androida można znaleźć na androiddrawables.comDostosowywanie
Rozpoznajemy niebieską linię w jednej z 9 łat , więc tworzymy jej lokalną kopię i zmieniamy kolory według potrzeb.
źródło
SearchView
sobie). Czy to w porządku, jeśli połączę Twoją odpowiedź (nadpisując onCreateOptionsMenu) z moją?onCreate()
metody doonCreateOptionsMenu()
metody, jak sugerowałeś. Zagłosowano na twoją odpowiedź.Powyższe rozwiązania mogą nie działać, jeśli używasz biblioteki appcompat. Być może będziesz musiał zmodyfikować kod, aby działał dla biblioteki appcompat.
Oto działające rozwiązanie dla biblioteki appcompat.
źródło
Twoja
onCreateOptionsMenu
metoda musi być:gdzie poszukiwany element nie jest
menu_search
właściwya oto
searchviewredversion
(ta jest wersją xhdpi): http://img836.imageshack.us/img836/5964/searchviewredversion.pngźródło
Powyższe rozwiązanie nie działa z ActionBarSherlock 4.2 i dlatego nie jest wstecznie kompatybilne z Androidem 2.x. Oto działający kod, który konfiguruje tło SearchView i tekst podpowiedzi w ActionBarSherlock 4.2:
źródło
Jestem zmęczony, aby to zrobić i używam v7. Aplikacja uległa awarii, kiedy próbowałem złapać
searchPlate
przez the,getIdentifier()
więc zrobiłem to w ten sposób:źródło
Aktualizacja
Jeśli używasz AndroidX, możesz to zrobić w ten sposób
źródło
Ja też napotkałem ten sam problem, użyłem biblioteki appcompat v7 i zdefiniowałem dla niej własny styl. W folderze do rysowania umieść plik bottom_border.xml, który wygląda następująco:
W folderze wartości styles_myactionbartheme.xml:
Zdefiniowałem plik custommenu.xml do wyświetlania menu:
Twoja aktywność powinna rozszerzać ActionBarActivity zamiast Activity.
W pliku manifestu:
Więcej informacji można znaleźć tutaj:
tutaj http://www.jayway.com/2014/06/02/android-theming-the-actionbar/
źródło
Najpierw utwórzmy plik XML o nazwie search_widget_background.xml, który będzie używany jako plik do rysowania, tj. W katalogu do rysowania.
Ten element do rysowania będzie używany jako tło dla naszego widżetu wyszukiwania. Ustawiłem kolor na czerwony, ponieważ o to prosiłeś, ale możesz ustawić dowolny kolor zdefiniowany przez tag @color. Możesz nawet zmodyfikować go dalej, używając atrybutów zdefiniowanych dla etykiety kształtu (wykonaj zaokrąglone rogi, zrób owalne tło itp.).
Następnym krokiem jest ustawienie tła naszego widżetu wyszukiwania na to. Można to osiągnąć w następujący sposób:
źródło
SearchView
(nazwanymsearch_plate
), a nie naSearchView
sobie. Zobacz moją odpowiedź, aby uzyskać więcej informacji. Muszę jednak przyznać, że nie próbowałem użyć odpowiedzi @ (baba tenor).SearchView
samo tło zawsze będzie znajdować się poniżej tła elementów, które są w środkuSearchView
. Wewnątrz jestLinearLayout
widok,SearchView
który ma idsearch_plate
, który ustawia ten niebieski element podkreślony jako tło. Zobacz moją odpowiedź po szczegóły. Tak więc w przypadku twojego rozwiązania wynikiem jest niebieskie tło dla całego widżetu z nadal widocznym niebieskim podkreśleniem. Testowałem na Jelly Bean , ale nie sądzę, żeby wersja docelowa SDK miała tutaj znaczenie.a to jest plik searchablecolor.xml
źródło
Wyjaśniłem na końcu tego posta za pomocą obrazów, które dotyczą formularzy Xamarin. Ale myślę, że możesz to zrozumieć, ponieważ jest oparty na kodzie źródłowym searchview na Androida
Jak zmienić obraz przycisku anulowania paska wyszukiwania w formularzach Xamarin
źródło
Jeśli zawyżasz Searchview w ten sposób "getMenuInflater (). Inflate (R.menu.search_menu, menu);". Następnie możesz dostosować ten widok wyszukiwania za pomocą style.xml, jak poniżej.
źródło
Dużo nad tym grzebałem iw końcu znalazłem to rozwiązanie i na mnie działa!
Możesz tego użyć
Jeśli używasz appcompat, spróbuj tego:
Jeśli używasz androidx, spróbuj tego:
Spowoduje to zmianę domyślnej ikony widoku usługi.
Mam nadzieję, że to pomoże!
źródło