首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:如何以编程方式创建StateListDrawable

Android:如何以编程方式创建StateListDrawable
EN

Stack Overflow用户
提问于 2011-06-28 12:55:00
回答 3查看 33.6K关注 0票数 38

我有一个GridView来显示一些对象,视觉上每个对象都有一个图像图标和一个文本标签。我也希望图像图标在点击时有一些“推送和弹出”的效果,也就是说,当按下时,图像会向右下角方向移动一小段距离,当释放时,图像会回到原来的位置。

这些对象(以及它们的图像图标)来自一些动态源。我的直觉是为每个项目创建一个StateListDrawable,它将有两种状态:按下或未按下。对于GridView项目视图,我将使用一个按钮,它可以容纳一个可绘制的和一个标签,它完全满足了我的需求。

我定义了一个item类来包装原始对象:

代码语言:javascript
复制
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。

代码语言:javascript
复制
<?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>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-28 14:18:59

如果你的绘图工具只是位图,你可以通过编程来绘制它们,现在它应该会有帮助,但是我想知道在这里使用InsetDrawable有什么问题,基本上是使用编程绘制的准备好的BitmapDrawables,你需要修改你的方法来接受位图b

代码语言:javascript
复制
        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));
票数 42
EN

Stack Overflow用户

发布于 2014-05-22 12:58:32

我可以看到答案已经被接受了。我正在分享,如果你想从用户的按钮动态分配正常以及按下状态的颜色。然后你可以直接调用这个函数:

代码语言:javascript
复制
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;

    }

现在你需要做的就是将它设置为你的文本视图或者按钮背景,如下所示:

代码语言:javascript
复制
 if(android.os.Build.VERSION.SDK_INT>=16){
        yourbutton.setBackground(convertColorIntoBitmap("#CEF6CE00","#4C9D32"));        

            }else{

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

在这里,您可以看到动态传递颜色所需的所有内容,我们就完成了。希望这篇文章能对某些人有所帮助:)你也能找到它的要点here :)

票数 13
EN

Stack Overflow用户

发布于 2016-09-16 19:27:54

我已经看到了前面的答案,但我提出了一个使用ColorDrawable的更短、更好的解决方案。

代码语言:javascript
复制
/**
     * 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中。

一旦你有了可抽屉,你就可以像这样简单地使用它,

代码语言:javascript
复制
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)));
        }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6501716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档