Zmiana rysowania tła widżetu searchview

Próbuję zmienić drawable, który znajduje się w Android actionbar searchview widget.

Obecnie wygląda to tak: Tutaj wpisz opis obrazka

Ale muszę zmienić niebieskie tło na czerwone.

Próbowałem wielu rzeczy brakuje rolling mój własny widget wyszukiwania, ale nic nie wydaje się działać.

Czy ktoś może wskazać mi właściwy kierunek, aby to zmienić?

Author: Léo Léopold Hertz 준영, 2012-06-18

9 answers

Intro

Niestety nie ma sposobu, aby ustawić styl pola tekstowego SearchView za pomocą motywów, stylów i dziedziczenia w XML, jak można to zrobić z tłem elementów w rozwijanym pasku ActionBar . Dzieje się tak dlatego, że selectableItemBackground jest wymieniony jako styleable w R.stylable, podczas gdy searchViewTextField (atrybut tematu, który nas interesuje) nie jest. W związku z tym nie możemy łatwo uzyskać do niego dostępu z zasobów XML (pojawi się błąd No resource found that matches the given name: attr 'android:searchViewTextField').

Ustawianie tła pola tekstowego SearchView z kod

Więc jedynym sposobem na poprawne zastąpienie tła pola tekstowego SearchView jest wejście do jego wnętrza, uzyskanie dostępu do widoku, który ma ustawione tło na podstawie searchViewTextField i ustawienie własnego.

Uwaga: rozwiązanie poniżej zależy tylko od id (android:id/search_plate) elementu wewnątrz SearchView, więc jest bardziej niezależne od wersji SDK niż przechodzenie przez dzieci (np. użycie searchView.getChildAt(0), aby dostać się do właściwego widoku wewnątrz SearchView), ale nie jest kuloodporne. Zwłaszcza jeśli jakiś producent zdecyduje się na reimplement wewnętrzne SearchView i element o wyżej wymienionym id nie jest obecny - kod nie będzie działał.

W SDK, tło dla pola tekstowego w SearchView jest deklarowane przez dziewięć łat , więc zrobimy to w ten sam sposób. Możesz znaleźć oryginalne PNGobrazy w drawable-mdpikatalogu Android Git repository. Interesują nas dwa obrazy. Jeden dla stanu, gdy pole tekstowe jest zaznaczone (o nazwie textfield_search_selected_holo_light.9.png ) i jeden, gdzie nie jest (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 skupiony Stan. Dzieje się tak dlatego, że {[19] } nie występuje w R. drawable. Dlatego nie jest łatwo dostępny przez @android:drawable/textfield_search_default_holo_light, które można użyć w selektorze pokazanym poniżej, zamiast odwoływać się do lokalnego drawable.

Uwaga: używałem światła Holo motyw jako podstawa, ale możesz zrobić to samo z Holo Dark . Wydaje się, że nie ma realnej różnicy w wybranym stanie 9-łaty między jasnym i ciemnym tematami. Jednak istnieje różnica w 9-łatkach dla domyślnego stanu (zobacz Light vs Dark). Prawdopodobnie nie ma więc potrzeby tworzenia lokalnych kopii 9-łat dla wybranego stanu , zarówno dla ciemnego , jak i jasnego tematów (zakładając, że chcesz obsłuż oba i spraw, aby oba wyglądały tak samo jak w Holo Theme ). Po prostu wykonaj jedną lokalną kopię i użyj jej w selektorze drawable dla obu motywów.

Teraz będziesz musiał edytować pobrane dziewięć łatek zgodnie z Twoimi potrzebami(tj. zmieniając niebieski kolor na czerwony). Możesz spojrzeć na plik używając draw 9-patch tool , Aby sprawdzić, czy został poprawnie zdefiniowany po edycji.

Edytowałem pliki używając GIMP {[47] } Z narzędziem one-pixel pencil (dość łatwe), ale pewnie użyjesz własnego narzędzia. Oto mój spersonalizowany 9-patch dla focused state :

Tutaj wpisz opis obrazka

Uwaga: dla uproszczenia, użyłem tylko obrazów dla mdpi gęstości. Musisz utworzyć 9-łaty dla wielu gęstości ekranu, jeśli chcesz uzyskać najlepszy wynik na dowolnym urządzeniu. Zdjęcia dla Holo SearchView można znaleźć w mdpi, hdpi i XHDPI drawable.

Teraz musimy stworzyć drawable selector, tak, że właściwy obraz jest wyświetlany na podstawie stanu widoku. Utwórz plik res/drawable/texfield_searchview_holo_light.xml o następującej treści:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
        android:drawable="@drawable/textfield_search_selected_holo_light" />
    <item android:drawable="@drawable/textfield_search_default_holo_light" />
</selector>

Użyjemy powyższego utworzonego drawable do Ustawienia tła dla widoku LinearLayout, który przechowuje pole tekstowe w SearchView - jego id to android:id/search_plate. Oto jak to zrobić szybko w kodzie, podczas tworzenia menu opcji:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }       

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);

        // Getting SearchView from XML layout by id defined there - my_search_view in this case
        SearchView searchView = (SearchView) menu.findItem(R.id.my_search_view).getActionView();
        // Getting id for 'search_plate' - the id is part of generate R file,
        // so we have to get id on runtime.
        int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
        // Getting the 'search_plate' LinearLayout.
        View searchPlate = searchView.findViewById(searchPlateId);
        // Setting background of 'search_plate' to earlier defined drawable.            
        searchPlate.setBackgroundResource(R.drawable.textfield_searchview_holo_light);          

        return super.onCreateOptionsMenu(menu);
    }

}

Efekt końcowy

Oto zrzut ekranu ostatecznego wyniku:]}

Tutaj wpisz opis obrazka

How I got to this

Myślę, że warto wiedzieć, jak do tego doszedłem, aby takie podejście można było wykorzystać przy dostosowywaniu innych widoków.

Sprawdzanie układu widoku

Sprawdziłem jak wygląda SearchView układ. W SearchView contructor można znaleźć linię nadmuchującą układ:

inflater.inflate(R.layout.search_view, this, true);

Teraz wiemy, że SearchView układ jest w pliku o nazwie res/layout/search_view.xml. Patrząc na search_view.xml możemy znaleźć wewnętrzny LinearLayout element (o id search_plate), który ma android.widget.SearchView$SearchAutoComplete wewnątrz niego (wygląda jak nasze wyszukiwanie Zobacz pole tekstowe):

    <LinearLayout
        android:id="@+id/search_plate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal"
        android:background="?android:attr/searchViewTextField">

Teraz, gdy tło jest ustawione na podstawie atrybutu searchViewTextField bieżącego motywu.

Badający atrybut (czy można go łatwo ustawić?)

Aby sprawdzić jak ustawiony jest atrybut searchViewTextField, badamy res/values/themes.xml . Istnieje grupa atrybutów związanych z SearchView w domyślnym Theme:

<style name="Theme">
    <!-- (...other attributes present here...) -->

    <!-- SearchView attributes -->
    <item name="searchDropdownBackground">@android:drawable/spinner_dropdown_background</item>
    <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
    <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
    <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
    <item name="searchViewSearchIcon">@android:drawable/ic_search</item>
    <item name="searchViewGoIcon">@android:drawable/ic_go</item>
    <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
    <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
    <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>

Widzimy, że dla domyślnego motywu wartością jest @drawable/textfield_searchview_holo_dark. Dla Theme.Light wartość jest również ustawiona w tym pliku .

Teraz, to byłoby świetnie, gdyby ten atrybut był dostępny przez R. styleable, ale niestety tak nie jest. Dla porównania, zobacz inne theme atrybuty, które są obecne zarówno w themes.xml i R. attr jak textAppearance lub selectableItemBackground . Jeśli searchViewTextField był obecny w R.attr (i R.stylable), możemy po prostu użyć naszego rysowalnego selektora podczas definiowania motywu dla całej naszej aplikacji w XML. Na przykład:

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="AppTheme" parent="android:Theme.Light">
        <item name="android:searchViewTextField">@drawable/textfield_searchview_holo_light</item>
    </style>
</resources>

Co należy je zmodyfikować?

Teraz wiemy, że będziemy musieli uzyskać dostęp przez kod. Nadal jednak nie wiemy, jak to powinno wyglądać. W skrócie, szukamy rysunków używanych jako wartości w domyślnych tematach: textfield_searchview_holo_dark.xml i textfield_searchview_holo_light.xml . Patrząc na zawartość widzimy, że drawable to selector, które odwołują się do dwóch innych drawables (które później są 9-łatkami) na podstawie stanu widoku. Można znaleźć zbiorcze 9 - patch drawables z (prawie) wszystkich wersji Androida na androiddrawables.com

Dostosowywanie

Rozpoznajemy niebieską linię w jednej z 9-łat , więc tworzymy jej lokalną kopię i zmieniamy kolory zgodnie z życzeniem.

 249
Author: vArDo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:37

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 rozwiązanie robocze dla biblioteki appcompat.

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {

    getMenuInflater().inflate(R.menu.main_menu, menu); 

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchAutoComplete.setHintTextColor(Color.WHITE);
    searchAutoComplete.setTextColor(Color.WHITE);

    View searchplate = (View)searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
    searchplate.setBackgroundResource(R.drawable.texfield_searchview_holo_light);

    ImageView searchCloseIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
    searchCloseIcon.setImageResource(R.drawable.abc_ic_clear_normal);

    ImageView voiceIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_voice_btn);
    voiceIcon.setImageResource(R.drawable.abc_ic_voice_search);

    ImageView searchIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
    searchIcon.setImageResource(R.drawable.abc_ic_search);


    return super.onCreateOptionsMenu(menu);
}
 31
Author: Abdul Rahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-22 18:32:17

Twoja metoda onCreateOptionsMenu musi być:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
        v.setBackgroundResource(R.drawable.searchviewredversion);
        return super.onCreateOptionsMenu(menu);
    }

Gdzie znajduje się Twoja pozycja wyszukiwania menu_search poza kursem

A oto searchviewredversion (ta jest wersją xhdpi): http://img836.imageshack.us/img836/5964/searchviewredversion.png

Tutaj wpisz opis obrazka

 14
Author: VinceFR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 13:31:37

Powyższe rozwiązanie nie działa z ActionBarSherlock 4.2 i dlatego nie jest kompatybilne wstecz z Androidem 2.x. oto działający kod, który ustawia tło SearchView i tekst podpowiedzi na ActionBarSherlock 4.2:

public static void styleSearchView(SearchView searchView, Context context) {
    View searchPlate = searchView.findViewById(R.id.abs__search_plate);
    searchPlate.setBackgroundResource(R.drawable.your_custom_drawable);
    AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(R.id.abs__search_src_text);
    searchText.setHintTextColor(context.getResources().getColor(R.color.your_custom_color));
}
 13
Author: David Vávra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-20 15:53:46

Ja też mam dość i używam v7. Aplikacja została zawieszona, gdy próbowałem złapać searchPlate przez getIdentifier(), więc zrobiłem to w ten sposób:

View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
 5
Author: Ido,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-03 22:05:47

Ja też miałem ten sam problem.Użyłem biblioteki appcompat v7 i zdefiniowałem dla niej własny styl. W drawable folder umieścić bottom_border.plik xml, który wygląda tak:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
  <shape >
      <solid android:color="@color/blue_color" />
  </shape>
</item>
<item android:bottom="0.8dp"
  android:left="0.8dp"
  android:right="0.8dp">
  <shape >
      <solid android:color="@color/background_color" />
  </shape>
</item>

<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="2.0dp">
  <shape >
      <solid android:color="@color/main_accent" />
  </shape>
 </item>
</layer-list>

W folderze values styles_myactionbartheme.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="AppnewTheme" parent="Theme.AppCompat.Light">
    <item name="android:windowBackground">@color/background</item>
    <item name="android:actionBarStyle">@style/ActionBar</item>
    <item name="android:actionBarWidgetTheme">@style/ActionBarWidget</item>
</style> 
<!-- Actionbar Theme -->
<style name="ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/main_accent</item>
    <!-- <item name="android:icon">@drawable/abc_ic_ab_back_holo_light</item> -->
</style> 
<style name="ActionBarWidget" parent="Theme.AppCompat.Light">
    <!-- SearchView customization-->
     <!-- Changing the small search icon when the view is expanded -->
    <!-- <item name="searchViewSearchIcon">@drawable/ic_action_search</item> -->
     <!-- Changing the cross icon to erase typed text -->
  <!--   <item name="searchViewCloseIcon">@drawable/ic_action_remove</item> -->
     <!-- Styling the background of the text field, i.e. blue bracket -->
    <item name="searchViewTextField">@drawable/bottom_border</item>
     <!-- Styling the text view that displays the typed text query -->
    <item name="searchViewAutoCompleteTextView">@style/AutoCompleteTextView</item>        
</style>

  <style name="AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
    <item name="android:textColor">@color/text_color</item>
  <!--   <item name="android:textCursorDrawable">@null</item> -->
    <!-- <item name="android:textColorHighlight">@color/search_view_selected_text</item> -->
</style>
</resources>

Zdefiniowałem custommenu.plik XML do wyświetlania menu:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:com.example.actionbartheme="http://schemas.android.com/apk/res-auto" >  

<item android:id="@+id/search"
      android:title="@string/search_title"
      android:icon="@drawable/search_buttonn" 
     com.example.actionbartheme:showAsAction="ifRoom|collapseActionView"   
                 com.example.actionbartheme:actionViewClass="android.support.v7.widget.SearchView"/>

Twoja aktywność powinna rozszerzyć ActionBarActivity zamiast aktywności.

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.custommenu, menu);
}

W pliku manifestu:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppnewTheme" >

Więcej informacji można znaleźć tutaj:
Proszę. http://www.jayway.com/2014/06/02/android-theming-the-actionbar/

 3
Author: Suhas Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 09:11:05

Najpierw stwórzmy plik XML o nazwie search_widget_background.xml, który ma być używany jako drawable, tzn. w katalogu drawable.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/red" />

</shape>

Ten drawable 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ć go na dowolny kolor zdefiniowany przez tag @ color. Możesz nawet zmodyfikować go dalej, używając atrybutów zdefiniowanych dla znacznika shape (wykonaj zaokrąglone rogi, wykonaj owalne tło itp.).

Następnym krokiem jest Ustaw tło naszego widżetu wyszukiwania na to. Można to osiągnąć poprzez:

    public boolean onCreateOptionsMenu(Menu menu) {

        SearchView searchView = (SearchView)menu.findItem(R.id.my_search_view).getActionView();
        Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
        searchView.setBackground(d);
...
    }
 2
Author: Erol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 15:52:29
public boolean onCreateOptionsMenu(Menu menu) {
........

        // Set the search plate color
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        View view = searchView.findViewById(linlayId);
        Drawable drawColor = getResources().getDrawable(R.drawable.searchcolor);
        view.setBackground( drawColor );
........
    }

A to jest searchablecolor.plik xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
      <shape >
          <solid android:color="#ffffff" />
      </shape>
  </item>

  <!-- main color -->
  <item android:bottom="1.5dp"
      android:left="1.5dp"
      android:right="1.5dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>

  <!-- draw another block to cut-off the left and right bars -->
  <item android:bottom="18.0dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>
</layer-list>
 1
Author: M.Raheel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-30 14:37:20

Wyjaśniłem na końcu tego postu ze zdjęciami dotyczy to formularzy xamarin. Ale myślę, że możesz to zrozumieć, ponieważ jest on oparty na kodzie źródłowym searchview Androida

Jak zmienić obraz przycisku SEARCHBAR Anuluj w formularzach xamarin

 0
Author: vu ledang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 03:58:27