自定义带图片的TextView,(setcompounddrawables 不显示)

今天在做一个界面的时候,碰到了一个需求是要在一个文字旁边放一个小图标,
在这里插入图片描述
本来想用一个TextView和一个ImageView横向布局然后作为一个整体来做,但是我发现有很多地方有着这样的小按钮,(图片+文字的形式),所以本着怎么懒怎么写的原则,就想找有没有更简洁一点的办法,比如能不能再TextView中添加一个图标呢,随便输入一个drawable以后,自动出现了很多如下属性:
在这里插入图片描述
一看这应该是添加图片的,再随便添加一个,发现真的把图片加上来了.但是我们又发现,添加图片的属性就那么四个drawableTop,drawableBottom,drawableLeft,drawableRight 意思分别是将图片添加到文字的上,下,左,右侧,这也挺方便的,而且也发现还能随着父元素的大小来设置图片的大小.但是发现里面有一个按钮是TextView中没有文字,只想加一个图标,就会发现用这几个方法以后,图标会在边框里面上下左右对齐,没办法居中.这还不是重点, 重点是我没办法设置图片的尺寸,可能我可以去设置父元素的padding,但是这时候会将文字一起压缩了.
这时候我又去苦苦寻找看看有没有办法设置这个图标自己的padding,发现里面有一个在这里插入图片描述
这个属性,当时以为是用来设置图标的padding的,最后试了一下,发现这个值只会影响图片和文字之间的距离,另外三边的padding则不会设置. 所以最后苦寻无果后,只能继续百度看看怎么设置TextView的图片,网上一大片都是说自定义TextView,那好吧,自定义一个TextView.
先将最后完成的代码交上,然后说一下在定义这个View中间发生的问题:
1.这是自定义view中需要自定义的属性文件:

<!--图片按钮-->
    <declare-styleable name="RichText">
        <attr name="drawableSrc" format="reference" />
        <attr name="drawableWidth" format="dimension" />
        <attr name="drawableHeight" format="dimension" />
        <attr name="drawableLocation">
            <enum name="left" value="1" />
            <enum name="top" value="2" />
            <enum name="right" value="3" />
            <enum name="bottom" value="4" />
        </attr>
    </declare-styleable>

2.继承自TextView

@SuppressLint("AppCompatCustomView")
public class RichText extends TextView {
    public static final int LEFT = 1, TOP = 2, RIGHT = 3, BOTTOM = 4;
    private int mHeight, mWidth;
    private Drawable mDrawable;
    private int mLocation;


    public RichText(Context context) {
        this(context, null);
    }

    public RichText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RichText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RichText, defStyleAttr, 0);
        mDrawable = array.getDrawable(R.styleable.RichText_drawableSrc);
        mWidth = array.getDimensionPixelSize(R.styleable.RichText_drawableWidth, 0);
        mHeight = array.getDimensionPixelSize(R.styleable.RichText_drawableHeight, 0);
        mLocation = array.getIndex(R.styleable.RichText_drawableLocation);
        array.recycle();
        drawDrawable();
    }


    public void drawDrawable() {
        if (mDrawable != null) {
            Bitmap bitmap = ((BitmapDrawable) mDrawable).getBitmap();
            Drawable drawable;
            if (mWidth != 0 && mHeight != 0) {
                drawable = new BitmapDrawable(getResources(), ImageUtils.getBitmap(bitmap, mWidth, mHeight));
            } else {
                drawable = new BitmapDrawable(getResources(),
                        Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(),
                                bitmap.getHeight(), true));
            }
            //在代码中设置组件的drawable的时候如果单纯的使用setCompoundDrawables是不会有效果的,
            // 因为没有指定drawable的大小,即Bound,具体代码如下:
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            switch (mLocation) {
                case LEFT:
                    Log.i("TAG", "添加在左边");
                    setCompoundDrawables(drawable, null, null, null);
                    break;
                case TOP:
                    Log.i("TAG", "添加在顶部");
                    setCompoundDrawables(null, drawable, null, null);
                    break;
                case RIGHT:
                    Log.i("TAG", "添加在右侧");
                    setCompoundDrawables(null, null, drawable, null);
                    break;
                case BOTTOM:
                    Log.i("TAG", "添加在底部");
                    setCompoundDrawables(null, null, null, drawable);
                    break;
            }
        }
    }
    
}

3.布局文件:

<com.example.loomc.myapplication.weight.RichText
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/radio_button"
                    android:gravity="center"
                    android:paddingBottom="2dp"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    android:paddingTop="2dp"
                    android:textSize="@dimen/font_size1"
                    app:drawableHeight="20dp"
                    app:drawableLocation="left"
                    app:drawableSrc="@mipmap/icon_male"
                    app:drawableWidth="20dp" />

上面三个就是自定义这个图片TextView用到的
下面就来说一下中间遇到的问题.之前在没有解决问题之前,我定义的View的图片是怎么都没有显示出来的.

问题1.当时自定义的TextView的类名叫做ImageTextView
但是,属性文件中declare-styleable name=“RichText”
name属性设置为RichText跟类名不一样,最后出现的情况就是在布局文件去获取属性的时候,IDE就是没办法自动弹出我定义的这个类View的属性名,而且又在命名空间这里卡了好久,因为他老是提示我用view: 这个标签,但是我在前面定义的view好像自定义属性都是用app:这个标签来调用的,最后各种百度,就是没找到,我也不知道是啥原因,强迫症的我就是想把这个问题解决掉,我就去看之前定义的view跟我这个定义的view有什么区别,最后不懈努力加上灵光一闪,把这个declare-styleable name=“RichText” 中的name参数改成自定义View的类名一样的名字,发现果然就可以让IDE自动的显示出来,就是类似下图中的提示方式,之前是怎么都没有这几个属性的.而且打日志的时候mWidth,mDrawable等值都是获取不到的,所以这里肯定是获取自定义属性的时候出了问题,没有获取到.
在这里插入图片描述
解决完这个问题后,图片还是没有显示.继续

问题2.自定义View中,我用的也是很传统的三个构造函数内部调用,的方式,然后view的初始化或者显示的任务都放在最后一个构造函数中.
貌似这里也没有啥问题,然后我用Log.i()打日志的方式,查看这时候mWidth这些值都是有的,mDrawable也获取到了,说明图片是设置进来了,但是为啥显示不了.弄了一个下午,快绝望了,
在这里插入图片描述
在这里插入图片描述
程序到这里的时候,drawable是获取到了而且尺寸也都有,我就想呀,这图片都有,再怎么,你也要在界面显示一点点出来呀,可是毛都没有,后面就只剩一个方法了,
在这里插入图片描述
可这个方法是Android自己的,出问题也不可能是那里面出问题了吧,所以我一直就没去调查那个方法,一直在看我前面是不是出了什么问题,最后到了这里没办法,只好来看看这个方法是干嘛的,其实这个方法前面我也了解了,就是在周围添加图片的功能,方法四个参数分别是左上右下.后来就百度了一下
“setcompounddrawables 不显示” 发现网上很多这个问题,我一下惊喜了,心里有预感就是这里出问题了,说不定是我哪里没有配置,所以才会导致这个方法没起作用(当然肯定不是这个方法有问题了,这还是有自知之明的).找了几个终于找到关键点了,也是我在代码中注释好的那句话:“在代码中设置组件的drawable的时候如果单纯的使用setCompoundDrawables是不会有效果的
所以在调用setcompounddrawables ()这个方法之前加了一句drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
这个方法就是对drawable进行设置宽高,心里想这下百分之九十应该是可以看到我的图标出来了,打开视图一看,果然出来了,所以就来这里把这个问题记录了一下

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值