更改搜索视图小部件的背景绘图

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (28)

我正在试图更改Androidactionbar搜索视图小部件中的可绘制性。

目前的情况如下:

但是我需要把蓝色背景画成红色。

我尝试过很多事情,除了滚动我自己的搜索小部件,但似乎没有任何工作。

有人能指点我改变这件事的正确方向吗?

提问于
用户回答回答于

从代码中设置SearchView文本字段背景

所以,正确地替换背景的唯一方法是SearchView文本字段是进入它的内部,获取对具有背景设置的视图的访问searchViewTextField并建立我们自己的。

注:下面的解决方案仅依赖于id(android:id/search_plate)中的元素SearchView,因此它比子遍历更独立于SDK版本(例如,使用searchView.getChildAt(0)才能到达正确的视野SearchView),但这不是防弹衣。尤其是如果一些制造商决定重新实现SearchView并且上面提到的id元素不存在--代码不能工作。

在SDK中,SearchView通过九块所以我们会用同样的方式。

不幸的是必须创建这两个映像的本地副本,即使只想自定义聚焦状态。这是因为textfield_search_default_holo_light不存在,因此很难通过@android:drawable/textfield_search_default_holo_light,可以在下面所示的选择器中使用,而不是引用本地绘图。

现在,需要根据需要编辑下载的九个补丁(即将蓝色改为红色)。若要检查编辑后是否正确定义了它,请执行以下操作。

但你可能会使用你自己的工具。这是我定制的9补丁聚焦状态:

注:为了简单起见,我只使用图像MDPI密度。你必须创造9-补丁对于多个屏幕密度,如果,希望在任何设备上的最佳结果。

现在,我们需要创建可绘制的选择器,以便根据视图状态显示正确的图像。创建文件res/drawable/texfield_searchview_holo_light.xml内容如下:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
        android:drawable="@drawable/textfield_search_selected_holo_light" />
    <item android:drawable="@drawable/textfield_search_default_holo_light" />
</selector>

我们将使用上面创建的可绘图设置背景LinearLayout视图中保存文本字段。SearchView-它的身份是android:id/search_plate...。因此,在创建选项菜单时,如何在代码中快速完成此操作:

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

}

最终效果

以下是最终结果的截图:

检出视图布局

我查过SearchView布局看起来像。

inflater.inflate(R.layout.search_view, this, true);

现在我们知道了SearchView布局在名为res/layout/search_view.xm我们可以找到一个内在的LinearLayout元素(带有id)search_plate)android.widget.SearchView$SearchAutoComplete在它里面(看起来像我们的搜索视图文本字段):

    <LinearLayout
        android:id="@+id/search_plate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal"
        android:background="?android:attr/searchViewTextField">

现在,我们根据当前主题的背景设置searchViewTextField属性。

调查属性(它容易设置吗?)

检查searchViewTextField属性设置,我们将研究有一组属性与SearchView违约Theme:

<style name="Theme">
    <!-- (...other attributes present here...) -->

    <!-- SearchView attributes -->
    <item name="searchDropdownBackground">@android:drawable/spinner_dropdown_background</item>
    <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
    <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
    <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
    <item name="searchViewSearchIcon">@android:drawable/ic_search</item>
    <item name="searchViewGoIcon">@android:drawable/ic_go</item>
    <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
    <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
    <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>

我们看到默认主题的值是@drawable/textfield_searchview_holo_dark

如果searchViewTextField曾在R.attr(和R.stylable)在用XML为整个应用程序定义主题时,我们可以简单地使用可绘制的选择器。例如:

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="AppTheme" parent="android:Theme.Light">
        <item name="android:searchViewTextField">@drawable/textfield_searchview_holo_light</item>
    </style>
</resources>

用户回答回答于

如果使用appcompat库,上述解决方案可能无法工作。您可能必须修改代码以使其适用于appcompat库。

以下是appcompat库的工作解决方案。

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {

    getMenuInflater().inflate(R.menu.main_menu, menu); 

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchAutoComplete.setHintTextColor(Color.WHITE);
    searchAutoComplete.setTextColor(Color.WHITE);

    View searchplate = (View)searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
    searchplate.setBackgroundResource(R.drawable.texfield_searchview_holo_light);

    ImageView searchCloseIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
    searchCloseIcon.setImageResource(R.drawable.abc_ic_clear_normal);

    ImageView voiceIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_voice_btn);
    voiceIcon.setImageResource(R.drawable.abc_ic_voice_search);

    ImageView searchIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
    searchIcon.setImageResource(R.drawable.abc_ic_search);


    return super.onCreateOptionsMenu(menu);
}

扫码关注云+社区