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

标签 android statelist

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

对象(及其图像图标)来自一些动态来源。我的直觉是为每个项目创建一个 StateListDrawable,它将有两种状态:按下或不按下。对于 GridView 项目 View ,我会使用一个 Button,它可以容纳一个 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;
    }

}

现在的问题是,当我触摸一个网格项目时,图标会像我预期的那样“移动”,但是当我的手指抬起离开该项目时,它不会恢复其原始位置.

我的问题是:如何以编程方式创建一个 StateListDrawable 等价于从 XML 资源膨胀的一个,例如

<?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>

?

最佳答案

如果您的可绘制对象只是位图,您可以通过编程方式绘制它们,现在它应该有所帮助,但是我想知道这里 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));

关于Android:如何以编程方式创建 StateListDrawable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6501716/

相关文章:

java - 根据位置或项目在 ListView 中添加 View 时出错

android - 无法生成签名的APK。重复的条目:DragAndDropPermissionsCompat.class

java - 为什么从后台删除应用程序后前台服务不工作?

android - 接收广播时出错 Intent act=android.net.wifi.p2p.THIS_DEVICE_CHANGED

c# - 是否有类或库来获取给定国家/地区的州列表?

java - 颜色状态列表不适用于 recyclerview textview

java - 将单个 JSON 元素解析为数组

javascript - 链接状态列表 将 HTML 下拉到特定页面

android - 如何拥有可点击和可检查的 TextView