自定义可以设置drawable大小的TextView

本文得益于博主“Ruffian-痞子”的博文->Here,多谢大神分享。

一般当我们要实现文本旁边加一个图片的效果时(比如一般底部的导航栏都是这么个效果),经常会用一个TextView和一个ImageView组合来实现,当要改变状态时要显示不一样的背景或者颜色,同时Image也要变化。这样一来,效果是实现了,可是弊端在于,不只是xml端的代码很冗余(除了空间组合多,而且定义的用于状态切换的selector也多),而且代码端的更麻烦,你要在合适的时机去动态的改变,势必会频繁地setSelected()、setEnable(),想想就很乱。

所以,我们找到了drawableLeft、drawableRight、drawableTop、drawableBottom这几个属性,我们可以方便的在一个控件下实现图片为文本同时显示的效果,而且动态的改变变得更加简便和便于维护,可是并没有什么完美的东西,他的缺点就是,我们不能去改变他这个drawable的大小,所以当我们的drawable的宽度或者高度比TextView大的时候就会只显示一部分,我们能做的只有先把图片一开始就做成控件所能适应的大小,这样一来,UI会疯的大笑,因为在一切落实之前,布局可能会频繁的改动的。如果你说我可以把UI的图拿过来自己用某软件缩成我需要的,那么你只是把UI的工作量挪到了自己这边,似不似傻,我就这么傻过(那是我刚工作的时候,一切为别人考虑...)。关键是即便是这样你在程序中显示出来的图片和UI给你的相比是失真的,你会看到一片片的朦胧美,然后我当时就懵逼了...

现在对于这个问题我们有了可以说是完美的解决方法:自定义View!

首先,定义我们自己的属性

其次,写一个继承自TextView的View,实现他的构造方法

public class DrawableTextView extends TextView {

    public static final String TAG = Contacts.TAG ;

    public static final int LEFT=1,TOP=2,RIGHT=3,BOTTOM=4 ;

    private Drawable src ;
    private int drawablePosition ;
    private int drawableWidth ;
    private int drawableHeight ;
    private Bitmap mBitmap;

    public DrawableTextView(Context context) {
        super(context);
    }

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

    public DrawableTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DrawableTextView,defStyleAttr,0);
        //默认设置为“college”图片
        src = array.getDrawable(R.styleable.DrawableTextView_drawableSrc);
        Log.d(TAG, "DrawableTextView: "+src);
        //默认设置为左边
        drawablePosition = array.getInt(R.styleable.DrawableTextView_drawablePosition, LEFT);
        Log.d(TAG, "DrawableTextView: "+drawablePosition);
        //默认为20dp        drawableWidth = array.getDimensionPixelSize(R.styleable.DrawableTextView_drawableWidth,0);
        Log.d(TAG, "DrawableTextView: "+drawableWidth);
        //默认为20dp        drawableHeight = array.getDimensionPixelSize(R.styleable.DrawableTextView_drawableHeight,0);
        Log.d(TAG, "DrawableTextView: " + drawableHeight);

        array.recycle();
        drawDrawable();


    }


    private void drawDrawable() {
        if (src != null) {
            Bitmap bitmap = ((BitmapDrawable)src).getBitmap();
            Drawable drawable ;
            if (drawableWidth!=0&&drawableHeight!=0) {
                drawable = new BitmapDrawable(getResources(),getBitmap(bitmap,drawableWidth,drawableHeight));
            }else {
                drawable = new BitmapDrawable(getResources(),Bitmap.createScaledBitmap(bitmap,bitmap.getWidth(),bitmap.getHeight(),true));
            }
            switch (drawablePosition){
                case LEFT:
                    this.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null);
                    break;
                case TOP:
                    this.setCompoundDrawablesWithIntrinsicBounds(null,drawable,null,null);
                    break;
                case RIGHT:
                    this.setCompoundDrawablesWithIntrinsicBounds(null,null,drawable,null);
                    break;
                case BOTTOM:
                    this.setCompoundDrawablesWithIntrinsicBounds(null,null,null,drawable);
                    break;
            }
        }
    }


    public Bitmap getBitmap(Bitmap bitmap,int width,int height) {
        //实际的大小
        int totalWidth = bitmap.getWidth();
        int totalHeight = bitmap.getHeight();
//        int a = width;
//        int b = height;
        //计算缩放比例
        float scaleWidth = (float)width/totalWidth ;
        float scaleHeight = (float)height/totalHeight ;
        Matrix matrix = new Matrix();
        //提交缩放
        matrix.postScale(scaleWidth, scaleHeight);
        Log.d(TAG, ": " + totalWidth + ":" + totalHeight);

        //得到缩放后的图片
        Bitmap bitmapResult = Bitmap.createBitmap(bitmap,0,0,totalWidth,totalHeight,matrix,true);

        return bitmapResult ;
    }
}
大体就是getBitmap()方法是设置drawable的大小以适应我们在xml中设置好的大小,然后调用setCompoundDrawablesWithIntrinsicBounds()这个方法把设置好大小的drawable设置进去就ok了!

最后就是在xml中添加自定义View

<com.hardy.person.myself_view_test.views.DrawableTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="自定义TextView(可以设置嵌入的图片大小,意味着我们再也不用费劲的去用ImageViewTextView组合去显示了)"
    android:gravity="center_vertical"
    android:drawablePadding="10dp"
    app:drawablePosition="bottom"
    app:drawableWidth="30dp"
    app:drawableHeight="30dp"
    app:drawableSrc="@drawable/major"
    />

其中的drawableSrc取代了drawableLeft等属性来设置drawable资源,用drawablePosition来设置图片在文本的哪个方向上,drawableWidth和drawableHeight可以设置图片的大小从而来适应TextView的大小。

No...感觉被坑了,上面说的优点顿时就没了,不能设置成selector的样式,会出现android.graphics.drawable.StateListDrawable cannot be cast to android.graphics.drawable.BitmapDrawable的错误,而且如果在代码中动态改变drawable,只能通过setCompoundDrawablesWithIntrinsicBounds()方法,然后还要像前面说的那样裁剪,EXM?这样一来比组合实现复杂多了好吗!可见这个控件只能适合写死的情况下,而且我觉得写死的情况用它只是少定义两个控件,但是自定义它自己的代码也多了不少好吗!所以我也不见得有什么优点了。。。好失望,如果能设置selector就好了,日后期待自己能完善这个问题。



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值