Соты - настроить SearchView внутри панели действий - PullRequest
9 голосов
/ 27 июля 2011

У меня есть поле, в котором пользователь может ввести поисковый запрос в панели действий приложения. Это объявляется в панели действий с использованием меню надувать в Activity:

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
>
    <item
        android:id="@+id/action_search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView"
        android:title="@string/search"
    ></item>
</menu>

Мне нужно настроить внешний вид SearchView (например, фон и цвет текста). До сих пор я не мог найти способ сделать это, используя XML (используя стили или темы).

Мой единственный вариант сделать это в коде при накачивании меню?


Редактировать # 1: я пробовал программно, но я не могу найти простой способ установить цвет текста. Плюс, когда я выполняю searchView.setBackgroundResource (...) Фон устанавливается в глобальном виджете (также, когда SearchView отображается в виде значка).

Редактировать # 2: Не так много информации о Справочнике разработчика по поиску либо

Ответы [ 6 ]

9 голосов
/ 25 января 2012

У Сейбеля был хороший ответ, если вы хотите сменить значки. Но вам нужно сделать это для каждой версии API. Я использовал ICS с ActionBarSherlock, и он не оправдал меня, но подтолкнул меня в правильном направлении.

Ниже я изменяю цвет текста и цвет подсказки. Я показал, как вы можете изменить значки тоже, хотя меня это пока не интересует (и вы, вероятно, все равно хотите использовать значки по умолчанию, чтобы быть последовательными)

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // Set up the search menu
    SearchView searchView = (SearchView)menu.findItem(R.id.action_search).getActionView();
    traverseView(searchView, 0);

    return true;
}

private void traverseView(View view, int index) {
    if (view instanceof SearchView) {
        SearchView v = (SearchView) view;
        for(int i = 0; i < v.getChildCount(); i++) {
            traverseView(v.getChildAt(i), i);
        }
    } else if (view instanceof LinearLayout) {
        LinearLayout ll = (LinearLayout) view;
        for(int i = 0; i < ll.getChildCount(); i++) {
            traverseView(ll.getChildAt(i), i);
        }
    } else if (view instanceof EditText) {
        ((EditText) view).setTextColor(Color.WHITE);
        ((EditText) view).setHintTextColor(R.color.blue_trans);
    } else if (view instanceof TextView) {
        ((TextView) view).setTextColor(Color.WHITE);
    } else if (view instanceof ImageView) {
        // TODO dissect images and replace with custom images
    } else {
        Log.v("View Scout", "Undefined view type here...");
    }
}
5 голосов
/ 03 июля 2012

добавлю мое мнение о вещах, которые, вероятно, немного более эффективны и безопасны в разных версиях Android.

вы можете получить числовое значение идентификатора из имени идентификатора строки. используя инструмент Android hierarchyviewer, вы можете найти строковые идентификаторы интересующих вас вещей, а затем просто использовать findViewById(...) для их поиска.

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

private static synchronized int getSearchSrcTextId(View view) {
    if (searchSrcTextId == -1) {
        searchSrcTextId = getId(view, "android:id/search_src_text");
    }
    return searchSrcTextId;
}

private static int getId(View view, String name) {
    return view.getContext().getResources().getIdentifier(name, null, null);
}

@TargetApi(11)
private void style(View view) {
    ImageView iv;

    AutoCompleteTextView actv = (AutoCompleteTextView) view.findViewById(getSearchSrcTextId(view));
    if (actv != null) {
        actv.setHint(getDecoratedHint(actv,
            searchView.getContext().getResources().getString(R.string.titleApplicationSearchHint),
            R.drawable.ic_ab_search));
        actv.setTextColor(view.getContext().getResources().getColor(R.color.ab_text));
        actv.setHintTextColor(view.getContext().getResources().getColor(R.color.hint_text));
    }
}
3 голосов
/ 28 июля 2011

Вместо этого вы можете использовать атрибут android:actionLayout, который позволяет указывать макет, который будет раздуваться.Просто создайте макет с вашим SearchView, и вам не придется ничего менять.

Что касается изменения стиля текста на SearchView, что, вероятно, невозможно, так как SearchView является * 1007.*.Возможно, вам следует попробовать изменить цвет текста с помощью тем.

2 голосов
/ 26 августа 2011

Если кто-то захочет изменить вид напрямую, вот как вы можете изменить цвета / шрифты / изображения и настроить окно поиска по своему усмотрению. Он упакован в попытку / уловку в случае различий между версиями или дистрибутивами, поэтому в случае сбоя приложения не произойдет сбой.

        // SearchView structure as we currently understand it:
        // 0 => linearlayout
        //      0 => textview (not sure what this does)
        //      1 => image view (the search icon before it's pressed)
        //      2 => linearlayout
        //           0 => linearlayout
        //               0 => ImageView (Search icon on the left of the search box)
        //               1 => SearchView$SearchAutoComplete (Object that controls the text, subclass of TextView)
        //               2 => ImageView (Cancel icon to the right of the text entry)
        //           1 => linearlayout
        //               0 => ImageView ('Go' icon to the right of cancel)
        //               1 => ImageView (not sure what this does)
        try {
            LinearLayout ll = (LinearLayout) searchView.getChildAt(0);
            LinearLayout ll2 = (LinearLayout) ll.getChildAt(2);
            LinearLayout ll3 = (LinearLayout) ll2.getChildAt(0);
            LinearLayout ll4 = (LinearLayout) ll2.getChildAt(1);
            TextView search_text = (TextView) ll3.getChildAt(1);
            search_text.setTextColor(R.color.search_text);
            ImageView cancel_icon = (ImageView)ll3.getChildAt(2);
            ImageView accept_icon = (ImageView)ll4.getChildAt(0);
            cancel_icon.setBackgroundDrawable(d);
            accept_icon.setBackgroundDrawable(d);
        } catch (Throwable e) {
            Log.e("SearchBoxConstructor", "Unable to set the custom look of the search box");
        }

В этом примере показано изменение цвета текста и цветов фона отмены / принятия изображений. searchView - это объект SearchView, для которого уже создан цвет фона:

Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
searchView.setBackgroundDrawable(d);

Вот код для рисования:

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

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

</shape>

Очевидно, что это хакерство, но пока оно будет работать.

1 голос
/ 28 января 2013

В ICS это возможно с использованием тем и стилей.Я использую ActionBarSherlock, что делает его применимым также для HC и ниже.

  1. Добавить стиль для определения "android: textColorHint":

    <style name="Theme.MyHolo.widget" parent="@style/Theme.Holo">
        <item name="android:textColorHint">@color/text_hint_corp_dark</item>
    </style>
    
  2. Примените это как "actionBarWidgetTheme" к вашей теме:

    <style name="Theme.MyApp" parent="@style/Theme.Holo.Light.DarkActionBar">
        ...
        <item name="android:actionBarWidgetTheme">@style/Theme.MyHolo.widget</item>
    </style>
    
  3. Presto!Убедитесь, что вы используете getSupportActionBar().getThemedContext() (или getSupportActionBar() для ActionBarSherlock), если какие-либо виджеты запускаются там, где у вас могут быть другие действующие темы.

0 голосов
/ 24 августа 2012

Как вы раздуваете меню xml в своей активности?если вы надуваете меню с помощью getMenuInflator () в своей деятельности, то меню, а также searchView получают тематический контекст, связанный с действием.

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

Если вы проверите исходный код Activity.getMenuInflator () в API-15, вы можете увидеть тематические контекстные коды.Вот оно.

     */
public MenuInflater getMenuInflater() {
    // Make sure that action views can get an appropriate theme.
    if (mMenuInflater == null) {
        initActionBar();
        if (mActionBar != null) {
            mMenuInflater = new MenuInflater(mActionBar.getThemedContext());
        } else {
            mMenuInflater = new MenuInflater(this);
        }
    }
    return mMenuInflater;
}
...