Androidアクションバーのsearchviewウィジェットにあるドローアブルを変更しようとしています。
現在、次のようになっています。
しかし、描画可能な青い背景を赤い色に変更する必要があります。
自分の検索ウィジェットをロールする以外に多くのことを試しましたが、何も機能しないようです。
誰かが私をこれを変える正しい方向に向けることができますか?
Androidアクションバーのsearchviewウィジェットにあるドローアブルを変更しようとしています。
現在、次のようになっています。
しかし、描画可能な青い背景を赤い色に変更する必要があります。
自分の検索ウィジェットをロールする以外に多くのことを試しましたが、何も機能しないようです。
誰かが私をこれを変える正しい方向に向けることができますか?
残念ながら、ActionBarドロップダウンの項目の背景で行うことができるようSearchView
に、XMLのテーマ、スタイル、および継承を使用してテキストフィールドのスタイルを設定する方法はありません。これは、がスタイル可能としてリストされているのに対し、(関心のあるテーマ属性)はそうではないためです。したがって、XMLリソース内から簡単にアクセスすることはできません(エラーが発生します)。selectableItemBackground
R.stylable
searchViewTextField
No resource found that matches the given name: attr 'android:searchViewTextField'
したがって、テキストフィールドの背景を適切に置き換える唯一の方法は、SearchView
テキストフィールドの内部に入り、背景が設定されているビューへのアクセスを取得しsearchViewTextField
、独自に設定することです。
注:android:id/search_plate
以下の解決策は、内の要素のid()のみに依存するSearchView
ため、子トラバーサルよりもSDKバージョンに依存しません(たとえばsearchView.getChildAt(0)
、内の正しいビューに到達するために使用しますSearchView
)が、防弾ではありません。特に、一部のメーカーがの内部を再実装することを決定しSearchView
、上記のIDを持つ要素が存在しない場合、コードは機能しません。
SDKでは、のテキストフィールドの背景は9つのパッチSearchView
で宣言されるため、同じ方法で行います。オリジナルのpng画像は、 Androidgitリポジトリのdrawable-mdpiディレクトリにあります。2つの画像に興味があります。1つはテキストフィールドが選択されたときの状態(textfield_search_selected_holo_light.9.pngという名前)と、選択されていない場所(textfield_search_default_holo_light.9.pngという名前)です。
残念ながら、フォーカスされた状態のみをカスタマイズする場合でも、両方の画像のローカルコピーを作成する必要があります。これは、 R.drawabletextfield_search_default_holo_light
に存在しないためです。したがって、ローカルのドローアブルを参照する代わりに、以下に示すセレクターで使用できる、を介して簡単にアクセスすることはできません。@android:drawable/textfield_search_default_holo_light
注:ベースとしてHolo Lightテーマを使用していましたが、 HoloDarkでも同じことができます。ライトテーマとダークテーマの間で、選択された状態9パッチに実際の違いはないようです。ただし、デフォルト状態の9パッチには違いがあります(ライトとダークを参照)。したがって、おそらく、ダークテーマとライトテーマの両方について、選択した状態の9パッチのローカルコピーを作成する必要はありません(両方を処理し、両方をホロテーマと同じように見せたいと仮定します)。ローカルコピーを1つ作成して、両方のテーマで描画可能なセレクター。
次に、ダウンロードした9つのパッチを必要に応じて編集する必要があります(つまり、青い色を赤い色に変更します)。描画9パッチツールを使用してファイルを調べ、編集後にファイルが正しく定義されているかどうかを確認できます。
私は1ピクセルの鉛筆ツール(非常に簡単)でGIMPを使用してファイルを編集しましたが、おそらく独自のツールを使用するでしょう。これがフォーカスされた状態のためにカスタマイズされた9パッチです:
注:簡単にするために、 mdpi密度の画像のみを使用しました。どのデバイスでも最高の結果が必要な場合は、複数の画面密度に対して9つのパッチを作成する必要があります。Holo の画像はSearchView
、mdpi、hdpi、xhdpiのドローアブルにあります。
次に、ビューの状態に基づいて適切な画像が表示されるように、描画可能なセレクターを作成する必要があります。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
-そのIDは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
レイアウトがどのように見えるかを確認しました。SearchView contructorで、レイアウトを膨らませる線を見つけることができます。
inflater.inflate(R.layout.search_view, this, true);
SearchView
これで、レイアウトが。という名前のファイルにあることがわかりましres/layout/search_view.xml
た。search_view.xmlを調べると、内部にある内部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
属性がどのように設定されているかを確認するために、 res / values/themes.xmlを調査します。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
です。Theme.Light
値についてもそのファイルに設定されています。
さて、この属性にR.styleableを介してアクセスできれば素晴らしいのですが、残念ながらそうではありません。比較のために、textAppearanceやselectableItemBackgroundなど、 themes.xmlとR.attrの両方に存在する他のテーマ属性を参照してください。(および)に存在する場合は、アプリケーション全体のテーマをXMLで定義するときに、ドローアブルセレクターを使用するだけで済みます。例えば:searchViewTextField
R.attr
R.stylable
<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_plate
これで、コードを介してアクセスする必要があることがわかりました。しかし、それがどのように見えるべきかはまだわかりません。つまり、デフォルトのテーマで値として使用されるドローアブルを検索します:textfield_searchview_holo_dark.xmlおよびtextfield_searchview_holo_light.xml。コンテンツを見ると、ドローアブルはselector
、ビューの状態に基づいて、他の2つのドローアブル(後で9パッチになる)を参照していることがわかります。androiddrawables.comで、(ほぼ)すべてのバージョンのAndroidから集約された9パッチのドローアブルを見つけることができます。
9つのパッチの1つで青い線を認識しているので、そのローカルコピーを作成し、必要に応じて色を変更します。
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);
}
メソッドは次のonCreateOptionsMenu
とおりである必要があります。
@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);
}
検索項目がmenu_search
コースから外れている場所
そしてここにありますsearchviewredversion
(これはxhdpiバージョンです):http://img836.imageshack.us/img836/5964/searchviewredversion.png
上記のソリューションはActionBarSherlock4.2では機能しないため、Android2.xとの下位互換性はありません。ActionBarSherlock4.2でSearchViewの背景とヒントテキストを設定する作業コードは次のとおりです。
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));
}
私もこれを行うのに疲れていて、v7を使用しています。searchPlate
経由を取得しようとするとアプリケーションがクラッシュしたので、次のgetIdentifier()
ようにしました。
View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
アップデート
AndroidXを使用している場合は、次のように実行できます
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);
}
}
私も同じ問題に直面しました。appcompatv7ライブラリを使用し、カスタムスタイルを定義しました。ドローアブルフォルダに、次のようなbottom_border.xmlファイルを配置します。
<?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>
値フォルダーstyles_myactionbartheme.xml:
<?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>
メニューを表示するためのcustommenu.xmlファイルを定義しました。
<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"/>
アクティビティは、ActivityではなくActionBarActivityを拡張する必要があります。
@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" >
詳細については、こちらをご覧ください:
こちらhttp://www.jayway.com/2014/06/02/android-theming-the-actionbar/
まず、search_widget_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>
このドローアブルは、検索ウィジェットの背景として使用されます。あなたが求めていたので色を赤に設定しましたが、@colorタグで定義された任意の色に設定できます。シェイプタグに定義された属性を使用してさらに変更することもできます(角を丸くしたり、背景を楕円形にしたりするなど)。
次のステップは、検索ウィジェットの背景をこれに設定することです。これは、次の方法で実行できます。
public boolean onCreateOptionsMenu(Menu menu) {
SearchView searchView = (SearchView)menu.findItem(R.id.my_search_view).getActionView();
Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
searchView.setBackground(d);
...
}
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 );
........
}
これはsearchablecolor.xmlファイルです
<?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>
私はそれについてたくさん掘り下げていました、そして最終的に私はこの解決策を見つけました、そしてそれは私のために働きます!
あなたはこれを使うことができます
appcompatを使用する場合は、次のことを試してください。
ImageView searchIconView = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);
androidxを使用する場合は、これを試してください。
ImageView searchIconView = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);
デフォルトのserchviewアイコンが変更されます。
それが役に立てば幸い!
この投稿の最後に、これがxamarinフォームに適用される画像で説明しました。でもAndroidのsearchviewのソースコードに基づいているので理解できると思います
このようにSearchviewを膨らませている場合は、「getMenuInflater()。inflate(R.menu.search_menu、menu);」です。次に、以下のようにstyle.xmlを介してこの検索ビューをカスタマイズできます。
<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>