Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Honeycomb - customize SearchView inside the action bar

I have a field where the user can type a search query in the action bar of the application. This is declared in the action bar using a menu inflate in the 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>

I need to customize the appearance of the SearchView (for instance background and text color). So far I could not find a way to do it using XML (using styles or themes).

Is my only option to do it in the code when inflating the menu?


Edit #1: I have tried programmatically but I cannot get a simple way to set the text color. Plus when I do searchView.setBackgroundResource(...) The background is set on the global widget, (also when the SearchView is iconified).

Edit #2: Not much information on the Search Developer Reference either

like image 976
Vincent Mimoun-Prat Avatar asked Jul 27 '11 12:07

Vincent Mimoun-Prat


Video Answer


2 Answers

Seibelj had an answer that is good if you want to change the icons. But you'll need to do it for every API version. I was using ICS with ActionBarSherlock and it didn't do justice for me but it did push me in the correct direction.

Below I change the text color and hint color. I showed how you might go about changing the icons too, though I have no interest in that for now (and you probably want to use the default icons anyways to be consistent)

@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...");
    }
}
like image 187
Cookster Avatar answered Sep 28 '22 11:09

Cookster


adding my take on things which is probably a little more efficient and safe across different android versions.

you can actually get a numeric ID value from a string ID name. using android's hierarchyviewer tool, you can actually find the string IDs of the things you are interested in, and then just use findViewById(...) to look them up.

the code below sets the hint and text color for the edit field itself. you could apply the same pattern for other aspects that you wish to style.

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));
    }
}
like image 30
Jeffrey Blattman Avatar answered Sep 28 '22 09:09

Jeffrey Blattman