自定義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的各種屬性也可以照用,爽。