Android アクションバーの searchview ウィジェットにある drawable を変更しようとしています。
現在はこんな感じです:
しかし、青い背景の描画可能部分を赤色に変更する必要があります。
独自の検索ウィジェットを作成する以外にいろいろ試しましたが、何も機能しないようです。
これを変更するための正しい方向を誰か教えてくれませんか?
ベストアンサー1
はじめに
SearchView
残念ながら、XMLのテーマ、スタイル、継承を使用してテキストフィールドのスタイルを設定する方法はありません。ActionBarドロップダウンのアイテムの背景を操作できます。 それの訳はselectableItemBackground
スタイル設定可能としてリストされているではありR.stylable
ますが、searchViewTextField
(私たちが興味を持っているテーマ属性) はそうではありません。したがって、XML リソース内から簡単にアクセスすることはできません (エラーが発生しますNo resource found that matches the given name: attr 'android:searchViewTextField'
)。
コードから SearchView テキストフィールドの背景を設定する
したがって、テキスト フィールドの背景を適切に置き換える唯一の方法SearchView
は、その内部にアクセスし、背景が設定されているビューにアクセスしてsearchViewTextField
、独自の背景を設定することです。
注記:android:id/search_plate
以下のソリューションは、内の要素の id ( )のみに依存するSearchView
ため、子のトラバーサル (searchView.getChildAt(0)
内の適切なビューを取得するために を使用するなどSearchView
) よりも SDK バージョンに依存しませんが、万能ではありません。特に、あるメーカーが の内部を再実装することを決定しSearchView
、上記の id を持つ要素が存在しない場合、コードは機能しません。
SDKでは、テキストフィールドの背景はSearchView
次のように宣言されます。ナインパッチなので、同じようにやってみましょう。オリジナルのpng画像描画可能-MDPIディレクトリのAndroid Gitリポジトリ2つの画像が必要です。1つはテキストフィールドが選択されたときの状態(テキストフィールド検索_選択された_ホロライト.9.png)とそうでない場所(名前が付けられている)のテキストフィールド検索デフォルト_ホロライト.9.png)。
残念ながら、カスタマイズしたい画像だけをローカルにコピーする必要があります。集中した状態。これはtextfield_search_default_holo_light
、R.描画可能@android:drawable/textfield_search_default_holo_light
したがって、ローカルの描画可能オブジェクトを参照する代わりに、以下に示すセレクターで使用できる を通じて簡単にアクセスすることはできません。
注記:私は使っていたホロライトテーマをベースとして使用できますが、ホロダーク実際には違いはないようです選択された状態9パッチ間ライトそして暗いテーマ。ただし、9パッチには違いがありますデフォルト状態(見るライト対暗い)。したがって、9パッチのローカルコピーを作成する必要はないでしょう。選択された状態、 両方のための暗いそしてライトテーマ(両方を処理し、両方を次のように同じ外観にしたいと仮定します)ホロテーマ)。ローカルコピーを1つ作成して、セレクター描画可能両方のテーマについて。
次に、ダウンロードした9つのパッチを必要に応じて編集する必要があります(青色を赤色に変更するなど)。ファイルを確認するには、9パッチツールを描く編集後に正しく定義されているかどうかを確認します。
私は以下の方法でファイルを編集しましたギンプ1ピクセルの鉛筆ツール(かなり簡単)で作成できますが、おそらく独自のツールを使用することになるでしょう。これが私がカスタマイズした9パッチです。集中状態:
注記:わかりやすくするために、画像のみを使用しています。MDPI密度。作成する必要があります9パッチ複数の画面密度に対応し、どのデバイスでも最高の結果を得たい場合は、ホロ SearchView
見つけることができるMDPI、高解像度そして翻訳元描画可能。
ここで、ビューの状態に基づいて適切な画像が表示されるように、描画可能なセレクターを作成する必要があります。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 コンストラクタレイアウトを膨らませる行を見つけることができます:
inflater.inflate(R.layout.search_view, this, true);
これで、SearchView
レイアウトが という名前のファイルにあることがわかりましたres/layout/search_view.xml
。検索ビュー.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/テーマ.xmlSearchView
デフォルトでは、 に関連する属性のグループがあります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.スタイル可能ですが、残念ながらそうではありません。比較のために他のテーマ両方に存在する属性テーマ.xmlそしてR.属性のようにテキストの外観または選択可能な項目の背景が(および)searchViewTextField
に存在する場合、XML でアプリケーション全体のテーマを定義するときに、単純に drawable セレクターを使用できます。例: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
。ただし、それがどのように見えるかはまだわかりません。簡単に言うと、デフォルトのテーマの値として使用される描画可能オブジェクトを検索します。テキストフィールド_検索ビュー_holo_dark.xmlそしてテキストフィールド_検索ビュー_ホロ_ライト.xmlコンテンツを見ると、ドローアブルはselector
ビューステートに基づいて他の2つのドローアブル(後で9パッチになる)を参照していることがわかります。Androidの(ほぼ)すべてのバージョンの集約された9パッチドローアブルは、androiddrawables.com
カスタマイズ
私たちは青い線を認識しています9パッチのうちの1つなので、ローカル コピーを作成し、必要に応じて色を変更します。