Honeycomb - 自定义操作栏中的SearchView

发布于 2024-11-26 17:25:50 字数 777 浏览 0 评论 0原文

我有一个字段,用户可以在应用程序的操作栏中键入搜索查询。这是使用活动中的菜单膨胀在操作栏中声明的:

<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:搜索开发人员参考 要么

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

灼疼热情 2024-12-03 17:25:50

如果您想更改图标,Seibelj 有一个很好的答案。但你需要
对每个 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...");
    }
}

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...");
    }
}
暮光沉寂 2024-12-03 17:25:50

添加我对跨不同 Android 版本可能更高效、更安全的事情的看法。

实际上,您可以从字符串 ID 名称获取数字 ID 值。使用android的hierarchyviewer工具,你实际上可以找到你感兴趣的事物的字符串ID,然后只需使用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));
    }
}

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));
    }
}
久隐师 2024-12-03 17:25:50

您可以使用属性 android:actionLayout 来代替,它可以让您指定要膨胀的布局。只需使用 SearchView 进行布局,您就不必真正修改任何内容。

至于更改 SearchView 上的文本样式,这可能是不可能的,因为 SearchView 是一个 ViewGroup。您可能应该尝试通过主题更改文本颜色。

You can use the attribute android:actionLayout instead which lets you specify a layout to be inflated. Just have a layout with your SearchView and you won't have to modify anything really.

As to changing text style on the SearchView that is probably not possible as the SearchView is a ViewGroup. You should probably try changing text color via themes instead.

怪我入戏太深 2024-12-03 17:25:50

如果有人想直接修改视图,您可以通过以下方法更改颜色/字体/图像并根据自己的喜好自定义搜索框。它被包装在 try/catch 中,以防版本或发行版之间存在差异,因此如果失败,应用程序不会崩溃。

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

显然,这是 hacky,但它现在可以工作。

In case anyone wants to modify the views directly, here is how you can change the colors/fonts/images and customize the search box to your pleasure. It is wrapped in a try/catch in case there are differences between versions or distributions, so it won't crash the app if this fails.

        // 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");
        }

This example shows changing the text color and the background colors of the cancel/accept images. searchView is a SearchView object already instantiated with it's background color:

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

Here is the drawable code:

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

Obviously, this is hacky, but it will work for now.

心的憧憬 2024-12-03 17:25:50

在 ICS 中,这可以使用主题和样式来实现。我正在使用 ActionBarSherlock,这使得它也适用于 HC 及以下版本。

  1. 添加样式来定义“android:textColorHint”:

    
    

  2. 将其作为“actionBarWidgetTheme”应用到您的主题:

    
    

  3. Presto!如果启动了任何可能有其他主题生效的小部件,请确保使用 getSupportActionBar().getThemedContext()(或 ActionBarSherlock 的 getSupportActionBar())。急

From ICS this is doable using themes and styles. I'm using ActionBarSherlock which makes it applicable also for HC and below.

  1. Add a style to define "android:textColorHint":

    <style name="Theme.MyHolo.widget" parent="@style/Theme.Holo">
        <item name="android:textColorHint">@color/text_hint_corp_dark</item>
    </style>
    
  2. Apply this as "actionBarWidgetTheme" to your theme:

    <style name="Theme.MyApp" parent="@style/Theme.Holo.Light.DarkActionBar">
        ...
        <item name="android:actionBarWidgetTheme">@style/Theme.MyHolo.widget</item>
    </style>
    
  3. Presto! Make sure that you use getSupportActionBar().getThemedContext() (or getSupportActionBar() for ActionBarSherlock) if any widgets are initiated where you might have other themes in effect.

吝吻 2024-12-03 17:25:50

如何在 Activity 中扩充菜单 xml?如果您在 Activity 中使用 getMenuInflator() 来扩充菜单,则菜单和 searchView 都会获得已附加到 Activity 的主题上下文。

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

如果你检查 API-15 的 Activity.getMenuInflator() 的源代码,你可以看到主题上下文代码。这里是。

     */
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;
}

How do you inflate the menu xml in your Activity? if you inflate the menu by using getMenuInflator() in your Activity, then the menu and also the searchView get the themed context, that have attached to the activity.

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

if you check the source code of Activity.getMenuInflator() at API-15, you can see the themed context codes. Here it is.

     */
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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文