我有一个字段,用户可以在应用程序的操作栏中键入搜索查询。这在活动栏中使用菜单膨胀在操作栏中声明:
<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:关于Search Developer Reference的信息不多
答案 0 :(得分:9)
如果你想改变图标,Seibelj有一个很好的答案。但你需要 为每个API版本执行此操作。我正在使用带有ActionBarSherlock的ICS,这对我来说并不合适,但确实让我朝着正确的方向前进。
下面我更改文字颜色和提示颜色。我展示了如何改变它 图标也是,虽然我现在对此没兴趣(你可能想要使用默认图标来保持一致)
@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...");
}
}
答案 1 :(得分:5)
添加我对不同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));
}
}
答案 2 :(得分:3)
您可以使用属性android:actionLayout
代替您可以指定要充气的布局。只需拥有SearchView
的布局,您就不必真正修改任何内容。
关于更改SearchView
上可能无法实现的文字样式,因为SearchView
是ViewGroup
。您可能应该尝试通过主题更改文本颜色。
答案 3 :(得分:2)
如果有人想直接修改视图,您可以通过以下方式更改颜色/字体/图像并自定义搜索框。它包含在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>
显然,这很麻烦,但现在还可以。
答案 4 :(得分:1)
从ICS可以使用主题和样式。我正在使用ActionBarSherlock,它也适用于HC及以下。
添加样式以定义“android:textColorHint”:
<style name="Theme.MyHolo.widget" parent="@style/Theme.Holo">
<item name="android:textColorHint">@color/text_hint_corp_dark</item>
</style>
将此作为“actionBarWidgetTheme”应用于您的主题:
<style name="Theme.MyApp" parent="@style/Theme.Holo.Light.DarkActionBar">
...
<item name="android:actionBarWidgetTheme">@style/Theme.MyHolo.widget</item>
</style>
的Presto!如果启动了任何可能有其他主题生效的小部件,请确保使用getSupportActionBar().getThemedContext()
(或getSupportActionBar()
用于ActionBarSherlock)。
答案 5 :(得分:0)
如何在Activity中扩展菜单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;
}