searchview ウィジェットの背景描画可能項目を変更する 質問する

searchview ウィジェットの背景描画可能項目を変更する 質問する

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_lightR.描画可能@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);
    }

}

最終的な効果

最終結果のスクリーンショットは次のとおりです。

ここに画像の説明を入力してください

どうしてこうなったのか

他のビューをカスタマイズするときにこのアプローチを使用できるように、私がどのようにしてこれにたどり着いたかについて言及する価値があると思います。

ビューレイアウトの確認

レイアウトがどのようになっているかを確認しましたSearchViewSearchView コンストラクタレイアウトを膨らませる行を見つけることができます:

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_darkTheme.Lightそのファイルにも設定されている

さて、この属性にアクセスできるとしたら素晴らしいでしょうR.スタイル可能ですが、残念ながらそうではありません。比較のために他のテーマ両方に存在する属性テーマ.xmlそしてR.属性のようにテキストの外観または選択可能な項目の背景が(および)searchViewTextFieldに存在する場合、XML でアプリケーション全体のテーマを定義するときに、単純に drawable セレクターを使用できます。例:R.attrR.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つなので、ローカル コピーを作成し、必要に応じて色を変更します。

おすすめ記事