web-dev-qa-db-ja.com

プログラムでセレクター画像を置き換えます

セレクターに設定された描画可能な画像リソースを持つImageViewがあります。プログラムでセレクタにアクセスし、強調表示された状態と強調表示されていない状態の画像を変更するにはどうすればよいですか?

セレクターのコードは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:id="@+id/iconSelector">
  <!-- pressed -->
  <item Android:state_pressed="true" Android:drawable="@drawable/btn_icon_hl" />
  <!-- focused -->
  <item Android:state_focused="true" Android:drawable="@drawable/btn_icon_hl" />
  <!-- default -->
  <item Android:drawable="@drawable/btn_icon" />
</selector>

btn_icon_hlbtn_iconを他の画像に置き換えたい。

115
dropsOfJupiter

私が見つけることができた限り(自分で似たようなことをやろうとしました)、StateListDrawableがすでに定義された後に単一の状態を変更する方法はありません。ただし、コードを使用して新しいものを定義できます。

StateListDrawable states = new StateListDrawable();
states.addState(new int[] {Android.R.attr.state_pressed},
    getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {Android.R.attr.state_focused},
    getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
    getResources().getDrawable(R.drawable.normal));
imageView.setImageDrawable(states);

そして、それらのうちの2つを手元に置いておくか、必要に応じて別のものを作成することができます。

244
kcoppock

私は同じ問題を抱えていたので、さらに一歩進んで解決しました。ただし、唯一の問題は、xmlでNavStateListDrawableを指定できないため、コードを使用してUI要素の背景を設定する必要があることです。次に、メインのドロアブルのレベルが変更されるたびに、子レベルリストのレベルも更新されるように、onStateChangeメソッドをオーバーライドする必要があります。

NavStateListDrawableを作成するときは、表示するアイコンのレベルを渡す必要があります。

public class NavStateListDrawable extends StateListDrawable {

    private int level;

    public NavStateListDrawable(Context context, int level) {

        this.level = level;
        //int stateChecked = Android.R.attr.state_checked;
        int stateFocused = Android.R.attr.state_focused;
        int statePressed = Android.R.attr.state_pressed;
        int stateSelected = Android.R.attr.state_selected;

        addState(new int[]{ stateSelected      }, context.getResources().getDrawable(R.drawable.nav_btn_pressed));
        addState(new int[]{ statePressed      }, context.getResources().getDrawable(R.drawable.nav_btn_selected));
        addState(new int[]{ stateFocused      }, context.getResources().getDrawable(R.drawable.nav_btn_focused));

        addState(new int[]{-stateFocused, -statePressed, -stateSelected}, context.getResources().getDrawable(R.drawable.nav_btn_default));


    }

    @Override
    protected boolean onStateChange(int[] stateSet) {

        boolean nowstate = super.onStateChange(stateSet);

        try{
            LayerDrawable defaultDrawable = (LayerDrawable)this.getCurrent();


            LevelListDrawable bar2 =  (LevelListDrawable)defaultDrawable.findDrawableByLayerId(R.id.nav_icons);
            bar2.setLevel(level);
        }catch(Exception exception)
        {

        }

        return nowstate;
    }
}

さまざまなナビゲーションボタンの描画可能な状態のすべてについて、次のようなものがあります。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

   <item Android:drawable="@drawable/top_bar_default" >

   </item>

    <item Android:id="@+id/nav_icons" Android:bottom="0dip">
        <level-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
            <item Android:maxLevel="0" >
                <bitmap
                    Android:src="@drawable/top_bar_icon_back"
                    Android:gravity="center" />
            </item>
            <item Android:maxLevel="1" >
                <bitmap
                    Android:src="@drawable/top_bar_icon_nav"
                    Android:gravity="center" />
            </item>
            <item Android:maxLevel="2" >
                <bitmap
                    Android:src="@drawable/top_bar_icon_settings"
                    Android:gravity="center" />
            </item>
            <item Android:maxLevel="3" >
                <bitmap
                    Android:src="@drawable/top_bar_icon_search"
                    Android:gravity="center" />
            </item>
        </level-list>

    </item>

</layer-list>

これを質問と回答として投稿するつもりでしたが、あなたがまさに質問をしているのを見て、ここに行きます。これにより、多くのxmlファイル定義が大幅に節約されます。私は約50〜100個のxml定義から約4個になりました!。

6
Emile