Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 更改searchview小部件的可绘制背景_Android_Styles_Android Actionbar_Searchview_Background Drawable - Fatal编程技术网

Android 更改searchview小部件的可绘制背景

Android 更改searchview小部件的可绘制背景,android,styles,android-actionbar,searchview,background-drawable,Android,Styles,Android Actionbar,Searchview,Background Drawable,我正在尝试更改Android actionbar searchview小部件中的drawable 现在看起来是这样的: 但是我需要把蓝色背景改成红色 除了滚动我自己的搜索小部件,我已经尝试了很多方法,但似乎没有任何效果 有人能告诉我改变这一点的正确方向吗?首先,让我们创建一个名为search\u widget\u background.XML的XML文件,用作可绘制目录,即在可绘制目录下 <?xml version="1.0" encoding="utf-8"?> <shap

我正在尝试更改Android actionbar searchview小部件中的drawable

现在看起来是这样的:

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

除了滚动我自己的搜索小部件,我已经尝试了很多方法,但似乎没有任何效果


有人能告诉我改变这一点的正确方向吗?

首先,让我们创建一个名为search\u widget\u background.XML的XML文件,用作可绘制目录,即在可绘制目录下

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/red" />

</shape>
简介 不幸的是,您无法使用XML中的主题、样式和继承设置
SearchView
文本字段样式。这是因为
R.stylable
中的
selectableItemBackground
,而
searchViewTextField
(我们感兴趣的主题属性)不是。因此,我们无法从XML资源中轻松访问它(您将得到一个
找不到与给定名称匹配的资源:attr'android:searchViewTextField'
错误)

从代码设置SearchView文本字段背景 因此,正确替换
SearchView
文本字段背景的唯一方法是进入其内部,获取对基于
SearchView文本字段设置背景的视图的访问权限,并设置我们自己的背景

注意:下面的解决方案只取决于
SearchView
中元素的id(
android:id/search\u plate
),因此它比子遍历更独立于SDK版本(例如使用
SearchView.getChildAt(0)
SearchView
中获得正确的视图),但它不是防弹的。特别是如果一些制造商决定重新实现
SearchView
的内部构件,并且不存在具有上述id的元素,则代码将无法工作

在SDK中,
SearchView
中的文本字段的背景是通过声明的,因此我们将以相同的方式进行声明。您可以在的目录中找到原始png图像。我们对两张图片感兴趣。一个用于选择(命名)文本字段时的状态,另一个用于未选择(命名)文本字段时的状态

不幸的是,即使您只想自定义聚焦状态,也必须创建两个映像的本地副本。这是因为
textfield\u search\u default\u holo\u light
在中不存在。因此,通过android:drawable/textfield\u search\u default\u holo\u light
@android:drawable/textfield\u search\u default\u holo\u light很难访问它,它可以在如下所示的选择器中使用,而不是引用本地drawable

注意:我使用全息光主题作为基础,但你也可以使用全息暗主题。在选定的状态9补丁和主题之间似乎没有真正的区别。然而,默认状态的9-patches有所不同(请参见vs)。因此,对于暗主题和亮主题,可能不需要为所选状态制作9面片的本地副本(假设您想要处理这两个主题,并使它们看起来与Holo主题中的相同)。只需制作一个本地副本,并在选择器中使用它即可绘制两个主题

现在,您需要根据需要编辑下载的九个补丁(即,将蓝色更改为红色)。您可以使用查看文件,以检查编辑后是否正确定义了该文件

我用一个像素铅笔工具编辑过文件(非常简单),但你可能会用你自己的工具。以下是我为聚焦状态定制的9-patch:

注意:为了简单起见,我只对mdpi密度使用了图像。如果你想在任何设备上获得最佳效果,你必须为多个屏幕密度创建9个补丁。Holo
SearchView
的图像可在中找到,并可绘制

现在,我们需要创建可绘制选择器,以便根据视图状态显示正确的图像。创建包含以下内容的文件
res/drawable/texfield\u searchview\u holo\u 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>
最终效果 以下是最终结果的屏幕截图:

我是怎么做到的 我认为值得一提的是我是如何做到这一点的,以便在定制其他视图时可以使用这种方法

检出视图布局 我已经检查了
SearchView
布局的外观。在中,可以找到一条使布局膨胀的线:

inflater.inflate(R.layout.search_view, this, true);
现在我们知道
SearchView
layout位于名为
res/layout/search\u view.xml
的文件中。通过查看,我们可以找到一个内部
LinearLayout
元素(id为
search\u plate
),其中包含
android.widget.SearchView$SearchAutoComplete
(看起来像我们的搜索视图文本字段):

我们看到默认主题的值是
@drawable/textfield\u searchview\u holo\u dark
。用于
Theme.Light

现在,如果这个属性可以通过访问就好了,但不幸的是,它不是。要进行比较,请参见和like或中存在的其他主题属性。如果
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>

@可绘图/文本字段\搜索视图\全息灯
应该修改什么? 现在我们知道,我们必须通过代码访问
search\u plate
。然而,我们仍然不知道它应该是什么样子。简而言之,我们搜索在默认主题中用作值的Drawable:和。查看内容,我们看到可绘制的是
selector
,它根据视图状态引用了另外两个可绘制的内容(后来出现的是9-patches)。你可以在(几乎)所有版本的Android上找到聚合的9-patch Drawable

定制
我们识别中的蓝线,因此我们创建它的本地副本并根据需要更改颜色。

您的
onCreateOptions菜单方法必须是:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
        v.setBackgroundResource(R.drawable.searchviewredversion);
        return super.onCreateOptionsMenu(menu);
    }
您的搜索项目位于
菜单\u search
场外

这是
searchviewer
    <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">
<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>
<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>
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
        v.setBackgroundResource(R.drawable.searchviewredversion);
        return super.onCreateOptionsMenu(menu);
    }
public static void styleSearchView(SearchView searchView, Context context) {
    View searchPlate = searchView.findViewById(R.id.abs__search_plate);
    searchPlate.setBackgroundResource(R.drawable.your_custom_drawable);
    AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(R.id.abs__search_src_text);
    searchText.setHintTextColor(context.getResources().getColor(R.color.your_custom_color));
}
  @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);
}
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
  <shape >
      <solid android:color="@color/blue_color" />
  </shape>
</item>
<item android:bottom="0.8dp"
  android:left="0.8dp"
  android:right="0.8dp">
  <shape >
      <solid android:color="@color/background_color" />
  </shape>
</item>

<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="2.0dp">
  <shape >
      <solid android:color="@color/main_accent" />
  </shape>
 </item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="AppnewTheme" parent="Theme.AppCompat.Light">
    <item name="android:windowBackground">@color/background</item>
    <item name="android:actionBarStyle">@style/ActionBar</item>
    <item name="android:actionBarWidgetTheme">@style/ActionBarWidget</item>
</style> 
<!-- Actionbar Theme -->
<style name="ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/main_accent</item>
    <!-- <item name="android:icon">@drawable/abc_ic_ab_back_holo_light</item> -->
</style> 
<style name="ActionBarWidget" parent="Theme.AppCompat.Light">
    <!-- SearchView customization-->
     <!-- Changing the small search icon when the view is expanded -->
    <!-- <item name="searchViewSearchIcon">@drawable/ic_action_search</item> -->
     <!-- Changing the cross icon to erase typed text -->
  <!--   <item name="searchViewCloseIcon">@drawable/ic_action_remove</item> -->
     <!-- Styling the background of the text field, i.e. blue bracket -->
    <item name="searchViewTextField">@drawable/bottom_border</item>
     <!-- Styling the text view that displays the typed text query -->
    <item name="searchViewAutoCompleteTextView">@style/AutoCompleteTextView</item>        
</style>

  <style name="AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
    <item name="android:textColor">@color/text_color</item>
  <!--   <item name="android:textCursorDrawable">@null</item> -->
    <!-- <item name="android:textColorHighlight">@color/search_view_selected_text</item> -->
</style>
</resources>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:com.example.actionbartheme="http://schemas.android.com/apk/res-auto" >  

<item android:id="@+id/search"
      android:title="@string/search_title"
      android:icon="@drawable/search_buttonn" 
     com.example.actionbartheme:showAsAction="ifRoom|collapseActionView"   
                 com.example.actionbartheme:actionViewClass="android.support.v7.widget.SearchView"/>
@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);
}
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppnewTheme" >
public boolean onCreateOptionsMenu(Menu menu) {
........

        // Set the search plate color
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        View view = searchView.findViewById(linlayId);
        Drawable drawColor = getResources().getDrawable(R.drawable.searchcolor);
        view.setBackground( drawColor );
........
    }
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
      <shape >
          <solid android:color="#ffffff" />
      </shape>
  </item>

  <!-- main color -->
  <item android:bottom="1.5dp"
      android:left="1.5dp"
      android:right="1.5dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>

  <!-- draw another block to cut-off the left and right bars -->
  <item android:bottom="18.0dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>
</layer-list>
View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
    View searchPlate = svSearch. findViewById(androidx.appcompat.R.id.search_plate);
    if (searchPlate != null) {
        AutoCompleteTextView searchText = searchPlate.findViewById(androidx.appcompat.R.id.search_src_text);
        if (searchText != null){
            searchText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.edittext_text_size));
            searchText.setMaxLines(1);
            searchText.setSingleLine(true);
            searchText.setTextColor(getResources().getColor(R.color.etTextColor));
            searchText.setHintTextColor(getResources().getColor(R.color.etHintColor));
            searchText.setBackground(null);
        }
    }
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <item name="searchViewStyle">@style/SearchView.ActionBar</item>
</style>

<style name="SearchView.ActionBar" parent="Widget.AppCompat.SearchView.ActionBar">
      <item name="queryBackground">@drawable/drw_search_view_bg</item>
      <item name="searchHintIcon">@null</item>
      <item name="submitBackground">@null</item>
      <item name="closeIcon">@drawable/vd_cancel</item>
      <item name="searchIcon">@drawable/vd_search</item>
</style>
ImageView searchIconView = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);
ImageView searchIconView = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
    searchIconView.setImageResource(R.drawable.yourIcon);