蜂窝 – 在操作栏内自定义SearchView

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

<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(使用样式或主题)的方法。

膨胀菜单的时候,是我唯一的select吗?


编辑#1:我已经试过编程,但我不能得到一个简单的方法来设置文本的颜色。 另外,当我做searchView.setBackgroundResource(…)背景设置在全局小部件,(也是当SearchView被图标化)。

编辑#2:关于search开发者参考的信息也不多

Solutions Collecting From Web of "蜂窝 – 在操作栏内自定义SearchView"

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

至于在SearchView上更改文本样式可能不可能,因为SearchViewViewGroup 。 你应该尝试通过主题来改变文本颜色。

Seibelj有一个很好的答案,如果你想改变图标。 但是,您需要为每个API版本执行此操作。 我正在使用ICS和ActionBarSherlock,这对我来说并不公平,但它确实推动了我朝着正确的方向前进。

下面我改变文字颜色和提示颜色。 我向你展示了如何改变图标,尽pipe现在我对此没有兴趣(而且你可能想使用默认的图标来保持一致)

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

join我的东西,这可能是一个更高效和安全的跨越不同的Android版本。

您实际上可以从stringID名称获取数字ID值。 使用android的hierarchyviewer工具,你实际上可以find你感兴趣的东西的stringID,然后使用findViewById(...)来查找它们。

下面的代码为编辑字段本身设置提示和文本颜色。 您可以将相同的模式应用于您想要devise的其他方面。

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

如果有人想直接修改视图,可以通过这个方法来改变颜色/字体/图像,并自定义search框。 它被包装在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> 

很明显,这很不好,但是现在就行了。

从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. 普雷斯托! 确保你使用getSupportActionBar().getThemedContext() (或者ActionBarSherlock的getSupportActionBar() ),如果有任何小部件被启动,你可能有其他的主题有效。

你如何在活动中充气菜单xml? 如果在Activity中使用getMenuInflator()来扩充菜单,那么菜单和searchView将获得附加到该活动的主题上下文。

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