Изменение фонового рисунка виджета searchview


Я пытаюсь изменить drawable, который сидит в Android actionbar searchview виджета.

В настоящее время это выглядит так:

но мне нужно изменить синий фон drawable на красный цвет.

Я пробовал много вещей, за исключением прокатки моего собственного виджета поиска, но ничего не работает.

кто-нибудь может мне точку в правильном направлении, чтобы изменить это?

9 118

9 ответов:

интро

к сожалению, нет никакого способа, чтобы установить SearchView стиль текстового поля с использованием тем, стилей и наследования в XML, как вы можно сделать с фоном элементов в выпадающем списке ActionBar. Это потому что selectableItemBackgroundуказан как styleable на R.stylable, а searchViewTextField (атрибут темы, который нас интересует) нет. Таким образом, мы не можем легко получить к нему доступ из XML-ресурсов (вы получите No resource found that matches the given name: attr 'android:searchViewTextField' ошибка).

Настройка SearchView фон текстового поля из кода

Итак, единственный способ правильно заменить фон SearchView текстовое поле, чтобы попасть в его внутренности, получить доступ к просмотру, который имеет фоновый набор на основе searchViewTextField и ставим свои.

Примечание: Решение ниже зависит только от id (android:id/search_plate) элемента внутри SearchView, поэтому он более независим от SDK-версии, чем обход детей (например, с помощью searchView.getChildAt(0) чтобы получить правильный вид внутри SearchView), но это не пуля-доказательство. Особенно, если какой-то производитель решает переопределить внутренние элементы SearchView а элемента с вышеупомянутым идентификатором нет-код работать не будет.

в SDK, фон для текстового поля в SearchView объявляется через девять-патчи, так что мы сделаем это таким же образом. Вы можете найти оригинал png изображения drawable-mdpi.

исследуя атрибут (он легко устанавливается?)

чтобы проверить, как searchViewTextField атрибут установлен, мы исследуем res / значения / темы.xml. Существует группа атрибутов, связанных с SearchView по умолчанию 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>

мы видим, что для темы по умолчанию значение равно @drawable/textfield_searchview_holo_dark. Ибо Theme.Light значение также установлен в этом файле.

теперь, было бы здорово, если бы этот атрибут был доступен через R. styleable, но, к сожалению, это не так. Для сравнения см. Другие тема атрибуты, которые присутствуют как в темы.xml и R. attr как textAppearance или selectableItemBackground. Если searchViewTextField присутствовал в R.attrR.stylable) мы могли бы просто использовать наши drawable селектор при определении темы для всего нашего приложения в XML. Например:

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

что следует изменить?

теперь мы знаем, что нам придется получить доступ search_plate через код. Однако мы до сих пор не знаем, как это должно выглядеть. Короче говоря, мы ищем чертежи, используемые в качестве значений в темах по умолчанию:textfield_searchview_holo_dark.xml и textfield_searchview_holo_light.xml. Глядя на содержание мы видим, что мешочки-это selector который ссылается на два других чертежа (которые позже становятся 9-патчами) на основе состояния представления. Вы можете найти агрегированные 9-патч drawables из (почти) всех версий Android на androiddrawables.com

настройка

мы узнаем синюю линию в один из 9-патчи, поэтому мы создаем локальную копию и меняем цвета по желанию.

вышеуказанные решения могут не работать, если вы используете библиотеку appcompat. Возможно, вам придется изменить код, чтобы он работал для библиотеки appcompat.

вот рабочее решение для библиотеки 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);
}

код onCreateOptionsMenu метод должен быть:

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

где ваш поисковый запрос menu_search конечно

и вот это searchviewredversion (Это версия xhdpi):http://img836.imageshack.us/img836/5964/searchviewredversion.png

enter image description here

решение выше не работает с ActionBarSherlock 4.2 и поэтому оно не обратно совместимо с Android 2.x. вот рабочий код, который настраивает фон SearchView и текст подсказки на 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));
}

Я тоже устал это делать, и я использую v7. Приложение было разбито, когда я попытался захватить searchPlate через getIdentifier() Так я сделал это так:

View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);

я тоже столкнулся с той же проблемой.Я использовал библиотеку appcompat v7 и определил для нее пользовательский стиль. В рисуемую папку положить bottom_border.xml-файл, который выглядит так:

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

в папке значений 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>

я определил custommenu.xml-файл для отображения меню:

<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"/>

ваша деятельность должна расширить ActionBarActivity вместо активности.

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

в файле манифеста:

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

дополнительные информацию смотрите здесь:
Здесь http://www.jayway.com/2014/06/02/android-theming-the-actionbar/

во-первых, давайте создадим XML-файл с именем search_widget_background.xml, который будет использоваться как drawable, т. е. под 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>

этот холст будет использоваться в качестве фона для нашего виджета поиска. Я установил цвет на красный, потому что это то, что вы просили, но вы можете установить его на любой цвет, определенный тегом @color. Вы даже можете изменить его дальше, используя атрибуты, определенные для форма тег (сделать закругленные углы, сделать овал фоне, так далее.).

следующий шаг-установить фон нашего поискового виджета на этот. Это может быть достигнуто следующим образом:

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

и это searchablecolor.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>

Я объяснил в конце этого поста с изображениями это относится к формам xamarin. Но я думаю, что вы можете понять это, потому что он основан на исходном коде searchview android

как изменить изображение кнопки отмены панели поиска в формах xamarin