1. 程式人生 > >自定義TextView實現設定drawable圖片大小

自定義TextView實現設定drawable圖片大小

這裡寫圖片描述

在開發專案的過程中有到過很多難題,例如途中的左側個人中心欄中的四個圖示,該如何實現呢?

大概有兩種方式解決
方法1:一個LinearLayout裡面放一個ImageView和一個TextView
方法2:一個TextView然後設定drawableLeft

下面的是問題:
方法1:巨麻煩!要寫三個控制元件,還要巢狀。要是一行多幾個這樣的控制元件,一整個頁面得巢狀多少層啊?太麻煩了。。。

方法2:這個不錯,直接設定drawableLeft(四個方向都行)搞定。但是,這個drawable的大小是不能夠通過程式碼設定大小的!而且在程式碼裡也沒提供重新設定這個圖片的方式,只能在xml佈局檔案中。是個坑!也走不通!

這次就和各位老司機分享一個最簡單的自定義View,一起走向繁榮富強!

Come on baby ,按照自定義View的四大步驟走起!

自定義View的步驟:

1、自定義View的屬性
2、在View的構造方法中獲得我們自定義的屬性
3、重寫onMesure
4、重寫onDraw

這次的自定義View繼承於TextView,不用重新計算寬高,因為TextView 會幫我們計算,這就是繼承自帶控制元件的好處。

開始了:

 1、自定義View的屬性 

按照需求,屬性有:drawable,drawable寬度,drawable高度,drawable位置
在 /value/attrs.xml 中這麼寫:

這裡寫圖片描述

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="MoreTextView">
        <attr name="drawable_src" format="reference"/>
        <attr name="imageHight" format="dimension"/>
        <attr name="imageWidth" format="dimension"/>
        <attr
name="imageLocation">
<enum name="left" value="0"/> <enum name="top" value="1"/> <enum name="right" value="2"/> <enum name="bottom" value="3"/> </attr> </declare-styleable> </resources>

2.在View的構造方法中獲得我們自定義的屬性

public class MoreTextView extends TextView {
    public static final int LEFT = 0, TOP = 1, RIGHT = 2, BOTTOM = 3;
    private int mHight, mWidth, mLocation;
    private Bitmap mImage;


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

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

    public MoreTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MoreTextView, defStyleAttr, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {

                case R.styleable.MoreTextView_imageWidth:
                    mWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 0, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.MoreTextView_imageHight:
                    mHight = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 0, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.MoreTextView_drawable_src:
                    mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
                    break;
                case R.styleable.MoreTextView_imageLocation:
                    mLocation = a.getInt(attr, LEFT);
                    break;
            }
        }
        a.recycle();

        drawPicture();//設定圖片方法


    }
}

為什麼開始就說這是一個很簡單的自定義View呢?因為這裡不用重寫onDraw方法,因為這裡沒有什麼需要繪製的。

核心方法:

textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
//引數分表代表左,上,右,下。使用drawable,不設定就設定null

下面是設定drawable的程式碼:

 private void drawPicture() {
        if (mImage != null) {
            Drawable mDrawable;
            if (mHight != 0 && mWidth != 0) {
                mDrawable = new BitmapDrawable(getResources(), getRealBitmap(mImage));
            } else {
                mDrawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(mImage, mImage.getWidth(), mImage.getHeight(), true));
            }
            switch (mLocation) {
                case LEFT:
                    this.setCompoundDrawablesWithIntrinsicBounds(mDrawable, null,
                            null, null);
                    break;
                case TOP:
                    this.setCompoundDrawablesWithIntrinsicBounds(null, mDrawable,
                            null, null);
                    break;
                case RIGHT:
                    this.setCompoundDrawablesWithIntrinsicBounds(null, null,
                            mDrawable, null);
                    break;
                case BOTTOM:
                    this.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
                            mDrawable);
                    break;
            }

        }


    }

    private Bitmap getRealBitmap(Bitmap image) {
       //根據需要Drawable原來的大小和目標寬高進行裁剪(縮放)
        int width = image.getWidth();// 獲得圖片的寬高
        int height = image.getHeight();
        // 取得想要縮放的matrix引數
        float scaleWidth = (float) mWidth / width;
        float scaleHeight = (float) mHight / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 返回新的Bitmap
        return Bitmap.createBitmap(image, 0, 0, width, height, matrix, true);

    }

這樣下來獲取到的的Drawable才是完整的,按照我們想要的大小縮放後的Drawable

  <com.example.captain_shan.myapplication.views.MoreTextView
        android:id="@+id/moreTextview"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/volume"
        android:text="這是一條巴哥犬"
        android:textColor="#ee00ee"
        custom:imageLocation="top"
        android:drawablePadding="5dp"
        custom:imageHight="20dp"
        custom:imageWidth="20dp"
        android:background="#eeeeee"
        custom:drawable_src="@drawable/dog"
        android:layout_width="50dp"
        android:layout_height="50dp"/>

記得根部局要獲得自定義的空間哦(空間名稱隨你起),壓脈帶。。。。

這裡寫圖片描述

是不是很簡單呢?而且TextView的各種屬性也可以照用,爽。