遗憾的是,无法使用XML中的主题,样式和继承来设置 SearchView 文本字段样式can do with background of items in ActionBar dropdown . 这是因为 selectableItemBackgroundis listed as styleable在 R.stylable 中,而 searchViewTextField (主题属性我们're interested in) is not. Thus, we cannot access it easily from within XML resources (you' ll得到 No resource found that matches the given name: attr 'android:searchViewTextField' 错误) .
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Getting SearchView from XML layout by id defined there - my_search_view in this case
SearchView searchView = (SearchView) menu.findItem(R.id.my_search_view).getActionView();
// Getting id for 'search_plate' - the id is part of generate R file,
// so we have to get id on runtime.
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
// Getting the 'search_plate' LinearLayout.
View searchPlate = searchView.findViewById(searchPlateId);
// Setting background of 'search_plate' to earlier defined drawable.
searchPlate.setBackgroundResource(R.drawable.textfield_searchview_holo_light);
return super.onCreateOptionsMenu(menu);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custommenu, menu);
}
9 回答
简介
遗憾的是,无法使用XML中的主题,样式和继承来设置
SearchView
文本字段样式can do with background of items in ActionBar dropdown . 这是因为selectableItemBackground
is listed as styleable在R.stylable
中,而searchViewTextField
(主题属性我们're interested in) is not. Thus, we cannot access it easily from within XML resources (you' ll得到No resource found that matches the given name: attr 'android:searchViewTextField'
错误) .从代码中设置SearchView文本字段背景
因此,正确替换
SearchView
文本字段的背景的唯一方法是进入它的内部,获取对具有基于searchViewTextField
的背景集的视图的访问权并设置我们自己的 .NOTE: 下面的解决方案仅取决于
SearchView
中元素的id(android:id/search_plate
),因此它比儿童遍历更加独立于SDK版本(例如,使用searchView.getChildAt(0)
来到SearchView
内的右视图),但它不是防弹的 . 特别是如果某些制造商决定重新实现SearchView
的内部,并且不存在具有上述id的元素 - 则代码将不起作用 .在SDK中,
SearchView
中的文本字段的背景是通过nine-patches声明的,因此我们将以相同的方式执行 . 您可以在Android git repository的drawable-mdpi目录中找到原始png图像 . 我们对两张图片感兴趣 . 一个用于选择文本字段时的状态(名为textfield_search_selected_holo_light.9.png),另一个用于不存在的状态(名为textfield_search_default_holo_light.9.png) .不幸的是,即使您只想自定义聚焦状态,也必须创建两个图像的本地副本 . 这是因为R.drawable在R.drawable中不存在 . 因此,它不容易通过
@android:drawable/textfield_search_default_holo_light
访问,它可以在下面显示的选择器中使用,而不是引用局部drawable .NOTE: 我使用Holo Light主题作为基础,但你可以使用Holo Dark做同样的事情 . 似乎在Light和Dark主题之间选定的状态9补丁没有真正的区别 . 但是,默认状态的9补丁存在差异(请参阅Light与Dark) . 因此,对于Dark和Light主题,可能不需要为选定状态制作9个补丁的本地副本(假设您要同时处理两者,并使它们看起来与Holo Theme中的相同) . 只需制作一个本地副本,并在两个主题的选择器drawable中使用它 .
现在,您需要根据需要编辑下载的九个补丁(即将蓝色更改为红色) . 您可以使用draw 9-patch tool查看文件,以检查编辑后是否正确定义了文件 .
我使用GIMP使用一个像素的铅笔工具编辑文件(非常简单),但是'll probably use the tool of your own. Here'是我的自定义9补丁,用于聚焦状态:
NOTE: 为简单起见,我只使用了mdpi密度的图像 . 如果您希望在任何设备上获得最佳结果,则必须为多个屏幕密度创建9个补丁 . Holo
SearchView
的图像可以在mdpi,hdpi和xhdpi drawable中找到 .现在,我们需要创建可绘制选择器,以便根据视图状态显示正确的图像 . 使用以下内容创建文件
res/drawable/texfield_searchview_holo_light.xml
:我们将使用上面创建的drawable来设置
LinearLayout
视图的背景,该视图在SearchView
中保存文本字段 - 其id为android:id/search_plate
. 所以这里是如何在创建选项菜单时快速在代码中执行此操作:最终效果
这是最终结果的屏幕截图:
我是怎么做到这一点的
我认为值得注意的是我如何做到这一点,因此在定制其他视图时可以使用这种方法 .
检出视图布局
我已经检查了
SearchView
布局的样子 . 在SearchView contructor中,可以找到一个膨胀布局的线:现在我们知道
SearchView
布局在名为res/layout/search_view.xml
的文件中 . 查看search_view.xml,我们可以找到一个内部LinearLayout
元素(id为search_plate
),里面有android.widget.SearchView$SearchAutoComplete
(看起来像我们的搜索视图文本字段):现在,我们现在基于当前主题的
searchViewTextField
属性设置背景 .调查属性(可以轻松设置吗?)
要检查
searchViewTextField
属性的设置方式,我们会调查res/values/themes.xml . 默认情况下SearchView
有一组与SearchView
相关的属性Theme
:我们看到默认主题的值是
@drawable/textfield_searchview_holo_dark
. 对于Theme.Light
值is also set in that file .现在,如果通过R.styleable可以访问此属性会很棒,但不幸的是,它不是 . 为了进行比较,请参阅themes.xml和R.attr中存在的其他主题属性,如textAppearance或selectableItemBackground . 如果在
R.attr
(和R.stylable
)中存在searchViewTextField
,我们可以在为XML中的整个应用程序定义主题时使用我们的drawable选择器 . 例如:应该修改什么?
现在我们知道,我们必须通过代码访问
search_plate
. 但是,我们仍然不知道它应该是什么样子 . 简而言之,我们搜索在默认主题中用作值的drawable:textfield_searchview_holo_dark.xml和textfield_searchview_holo_light.xml . 看一下内容,我们看到drawable是selector
,它基于视图状态引用了另外两个drawable(后来发生了9个补丁) . 您可以在androiddrawables.com上找到来自(几乎)所有Android版本的聚合9-patch drawables自定义
我们识别one of the 9-patches中的蓝线,因此我们创建它的本地副本并根据需要更改颜色 .
如果您使用appcompat库,上述解决方案可能无法正常工作 . 您可能必须修改代码才能使其适用于appcompat库 .
这是appcompat库的工作解决方案 .
你的
onCreateOptionsMenu
方法必须是:当你的搜索项目是
menu_search
这里是
searchviewredversion
(这个是xhdpi版本):http://img836.imageshack.us/img836/5964/searchviewredversion.png上面的解决方案不适用于ActionBarSherlock 4.2,因此它不向后兼容Android 2.x.这是在ActionBarSherlock 4.2上设置SearchView背景和提示文本的工作代码:
我've tired to do this as well and I'm使用v7 . 当我试图通过
getIdentifier()
抓取searchPlate
时,应用程序崩溃了,所以我这样做了:我也遇到了同样的问题 . 我使用appcompat v7库并为它定义了自定义样式 . 在drawable文件夹中放入bottom_border.xml文件,如下所示:
在values文件夹styles_myactionbartheme.xml中:
我定义了custommenu.xml文件来显示菜单:
您的活动应该扩展ActionBarActivity而不是Activity .
在清单文件中:
有关更多信息,请参见此处
这里http://www.jayway.com/2014/06/02/android-theming-the-actionbar/
首先,让我们创建一个名为search_widget_background.xml的XML文件,用作drawable,即在drawable目录下 .
此drawable将用作我们的搜索小部件的背景 . 我将颜色设置为红色,因为这是您要求的,但您可以将其设置为@color标签定义的任何颜色 . 您甚至可以使用为shape tag定义的属性进一步修改它(制作圆角,做椭圆形背景等) .
下一步是将搜索小部件的背景设置为此背景 . 这可以通过以下方式完成:
and this is the searchablecolor.xml file
我在这篇文章的最后用图像解释这适用于xamarin表格 . 但我认为你可以理解它,因为它是基于android的searchview的源代码
How to change searchbar cancel button image in xamarin forms