android关于TextView的drawableLeft,drawableTop,drawableRight,drawableRight的drawable大小及位置问题

经常在项目中我们会看到一个按钮采用图片及文字结合的方式来显示界面,我们如何设计布局了?

第一种方法:使用一个ViewGroup,在ViewGroup中添加一个ImageView和一个TextView组合来达到这种效果。

第二种方式使用Textview的drawableLeft,drawableTop,drawableRight,drawableRight来达到这种效果,但是这又有一个问题,就是不能指定drawable的大小和位置。

系统默认是显示图片的加载大小,可在TextView源码中的

public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left,
        @Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) {

    if (left != null) {
        left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight());
    }
    if (right != null) {
        right.setBounds(0, 0, right.getIntrinsicWidth(), right.getIntrinsicHeight());
    }
    if (top != null) {
        top.setBounds(0, 0, top.getIntrinsicWidth(), top.getIntrinsicHeight());
    }
    if (bottom != null) {
        bottom.setBounds(0, 0, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight());
    }
    setCompoundDrawables(left, top, right, bottom);
}
这个方法中看到,这个方法在其构造函数中调用。

最后是把这4个变量存在其内部类Drawables中,api23之前是存在Drawables中的4个成员变量中,之后是存在其mShowing中。

在api23的源码中,Textview的ondraw()方法中可以看到,

if (dr.mShowing[Drawables.LEFT] != null) {
    canvas.save();
    canvas.translate(scrollX + mPaddingLeft + leftOffset,
                     scrollY + compoundPaddingTop +
                     (vspace - dr.mDrawableHeightLeft) / 2);
    dr.mShowing[Drawables.LEFT].draw(canvas);
    canvas.restore();
}
所以我们通过反射可以,改变Drawable中的mBounds变量,以left为例:

try {
    Class<?>  calss = Class.forName("android.widget.TextView");
    Field draw = calss.getDeclaredField("mDrawables");
    draw.setAccessible(true);
    Object obj=draw.get(mbtn);
    if(obj != null){
        calss = obj.getClass();
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            draw = calss.getDeclaredField("mShowing");
            draw.setAccessible(true);
            Object   song = draw.get(obj);
            if(song != null){
                Object[] objs = (Object[]) song;
                if(objs[1] != null){
                    Drawable top = (Drawable) objs[1];
                    top.setBounds(0,0,50,50);
                }
            }
        }else{
            draw = calss.getDeclaredField("mDrawableTop");
            draw.setAccessible(true);
            Object   song = draw.get(obj);
            if(song != null){
                Drawable top = (Drawable) song;
                top.setBounds(0,0,50,50);
            }
        }
    }
    draw = calss.getDeclaredField("mDrawableWidthTop");
    draw.setAccessible(true);
    draw.set(obj,50);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
最后还要反射Drawables的mDrawableWidthTop变量来让图片居中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值