38

いくつかのオブジェクトを表示する GridView があり、視覚的に各オブジェクトにはイメージ アイコンとテキスト ラベルがあります。また、クリックしたときに画像アイコンに「プッシュアンドポップ」効果を持たせたいです。つまり、押すと画像が右下方向に少し移動し、離すと元の位置に戻ります。

オブジェクト (およびそのイメージ アイコン) は、いくつかの動的ソースからのものです。私の直感では、アイテムごとに StateListDrawable を作成します。これには、押されたかどうかという 2 つの状態があります。GridView アイテム ビューの場合、Drawable とラベルに対応できるボタンを使用して、私の要件を完全に満たします。

元のオブジェクトをラップするアイテム クラスを定義しました。

public class GridItem<T> {

    public static final int ICON_OFFSET = 4;

    private StateListDrawable mIcon;
    private String mLabel;
    private T mObject;

    public Drawable getIcon() {
        return mIcon;
    }

    public void setIcon(Drawable d) {
        if (null == d) {
            mIcon = null;
        }else if(d instanceof StateListDrawable) {
            mIcon = (StateListDrawable) d;
        } else {
            InsetDrawable d1 = new InsetDrawable(d, 0, 0, ICON_OFFSET, ICON_OFFSET);
            InsetDrawable d2 = new InsetDrawable(d, ICON_OFFSET, ICON_OFFSET, 0, 0);
            mIcon = new StateListDrawable();
            mIcon.addState(new int[] { android.R.attr.state_pressed }, d2);
            mIcon.addState(StateSet.WILD_CARD, d1);
            //This won't help either: mIcon.addState(new int[]{}, d1);
        }
    }

    public String getLabel() {
        return mLabel;
    }

    public void setLabel(String l) {
        mLabel = l;
    }

    public T getObject() {
        return mObject;
    }

    public void setObject(T o) {
        mObject = o;
    }

}

問題は、グリッド アイテムに触れると、アイコンが予想どおりに「移動」することですが、アイテムから指を離しても元の位置に戻らないことです。

私の質問は、次のような XML リソースから膨張したものと同等の StateListDrawable をプログラムで作成する方法です。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@drawable/image_pressed" />  
    <item android:drawable="@drawable/image_normal" />
</selector>

?

4

3 に答える 3

42

ドローアブルが単なるビットマップである場合、プログラムで描画できますが、今のところは役立つはずですが、InsetDrawableここでの使用の問題は何でしょうか。基本的に、BitmapDrawablesプログラムで描画された準備済みのものを使用します。ビットマップを受け入れるようにメソッドを変更する必要がありますb

        Bitmap bc1 = Bitmap.createBitmap(b.getWidth() + ICON_OFFSET, b.getHeight() + ICON_OFFSET, Bitmap.Config.ARGB_8888);
        Canvas c1 = new Canvas(bc1);
        c1.drawBitmap(b, 0, 0, null);
        Bitmap bc2 = Bitmap.createBitmap(b.getWidth() + ICON_OFFSET, b.getHeight() + ICON_OFFSET, Bitmap.Config.ARGB_8888);
        Canvas c2 = new Canvas(bc2);
        c2.drawBitmap(b, ICON_OFFSET, ICON_OFFSET, null);

        mIcon = new StateListDrawable();
        mIcon.addState(new int[] { android.R.attr.state_pressed },  new BitmapDrawable(bc2));
        mIcon.addState(StateSet.WILD_CARD, new BitmapDrawable(bc1));
于 2011-06-28T06:18:58.533 に答える
13

答えはすでに受け入れられていることがわかります。通常の状態と押された状態のユーザーからボタンの色を動的に割り当てたい場合は、共有しています。次に、この関数を呼び出すことができます:

public static StateListDrawable convertColorIntoBitmap(String pressedColor, String normalColor){


        /*Creating bitmap for color which will be used at pressed state*/
        Rect rectPressed = new Rect(0, 0, 1, 1);

        Bitmap imagePressed = Bitmap.createBitmap(rectPressed.width(), rectPressed.height(), Config.ARGB_8888);
        Canvas canvas = new Canvas(imagePressed);       
        int colorPressed = Color.parseColor(pressedColor);
        Paint paintPressed = new Paint();
        paintPressed.setColor(colorPressed);
        canvas.drawRect(rectPressed, paintPressed);
        RectF bounds = new RectF();
        bounds.round(rectPressed);

        /*Creating bitmap for color which will be used at normal state*/
        Rect rectNormal = new Rect(0, 0, 1, 1);     
        Bitmap imageNormal = Bitmap.createBitmap(rectNormal.width(), rectNormal.height(), Config.ARGB_8888);
        Canvas canvasNormal = new Canvas(imageNormal);
        int colorNormal = Color.parseColor(normalColor);
        Paint paintNormal = new Paint();
        paintNormal.setColor(colorNormal);
        canvasNormal.drawRect(rectNormal, paintNormal);


        /*Now assigning states to StateListDrawable*/
        StateListDrawable stateListDrawable= new StateListDrawable();
        stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new BitmapDrawable(imagePressed));
        stateListDrawable.addState(StateSet.WILD_CARD, new BitmapDrawable(imageNormal));

        return stateListDrawable;

    }

必要なのは、以下のようにテキストビューまたはボタンの背景として設定することだけです:

 if(android.os.Build.VERSION.SDK_INT>=16){
        yourbutton.setBackground(convertColorIntoBitmap("#CEF6CE00","#4C9D32"));        

            }else{

yourbutton.setBackgroundDrawable(convertColorIntoBitmap("#CEF6CE00","#4C9D32"));
    }

ここで、色を動的に渡すために必要なすべてを確認できます。これで完了です。これが誰かの助けになることを願っています:)ここでも要点を見つけることができます:)

于 2014-05-22T04:58:31.753 に答える
4

以前の回答を見てきましたが、を使用してはるかに短くて優れたソリューションを思いつきましたColorDrawable

/**
     * Get {@link StateListDrawable} given the {@code normalColor} and {@code pressedColor}
     * for dynamic button coloring
     *
     * @param normalColor  The color in normal state.
     * @param pressedColor The color in pressed state.
     * @return
     */
    public static StateListDrawable getStateListDrawable(int normalColor, int pressedColor) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(pressedColor));
        stateListDrawable.addState(StateSet.WILD_CARD, new ColorDrawable(normalColor));
        return stateListDrawable;
    }

これは、解決された色を整数として受け入れColorDrawable、それらを に追加するために使用しStateListDrawableます。

drawable を取得したら、次のように簡単に使用できます。

if (android.os.Build.VERSION.SDK_INT >= 16) {
            mButton.setBackground(Utils.getStateListDrawable(ResourceUtils.getColor(R.color.white),
                    ResourceUtils.getColor(R.color.pomegranate)));
        } else {
            mButton.setBackgroundDrawable(Utils.getStateListDrawable(ResourceUtils.getColor(R.color.white),
                    ResourceUtils.getColor(R.color.pomegranate)));
        }
于 2016-09-16T11:27:53.887 に答える