自定義TextView可控制Drawable大小
小知識,大挑戰!本文正在參與「程序員必備小知識」創作活動
本文已參與 「掘力星計劃」 ,贏取創作大禮包,挑戰創作激勵金。
一般來説,我們在實際開發場景中都會碰到這種情況
一般來説我們會如下進行佈局
但是要知道,ViewGroup也就是我們根佈局,會對子View進行測量,每多一個View就會導致多測量一個View,而且我們設置點擊也不好進行操作.當然如果你説再包一層那我確實沒話説
所以我們需要一個更簡潔更方便的方法來解決這種讓人抓狂的問題
恰巧TextView就為我們提供了一個方式.
我們可以通過DrawableTop,DrawableBottom.DrawableLeft,DrawableRight為Textview的Drawable設置位置. 但是新的問題出現了,Drawable的大小我們無法在Xml裏進行控制,在不同的手機上他展示的效果很可能會不一致,甚至導致你的佈局出現錯亂.
當然你可以通過以下方式設置
如果你是獨立開發,無所謂,如果是協同開發,你這麼寫會死人的.
這個時候就需要我們對TextView進行自定義了.
```` /* * 可自定義Drawable的TextView * strokeWidth 可設置字體粗細 中粗建議0.3f 默認不加粗 / public class DrawableTextView extends androidx.appcompat.widget.AppCompatTextView {
private final int DRAWABLE_LEFT = 0;
private final int DRAWABLE_TOP = 1;
private final int DRAWABLE_RIGHT = 2;
private final int DRAWABLE_BOTTOM = 3;
private final int leftDrawableWidth;
private final int leftDrawableHeight;
private final int rightDrawableWidth;
private final int rightDrawableHeight;
private final int topDrawableWidth;
private final int topDrawableHeight;
private final int bottomDrawableWidth;
private final int bottomDrawableHeight;
private final float strokeWidth;
private int leftWidth, rightWidth;//左右圖片寬度
private DrawableListener.DrawableRightListener drawableRightListener;
private DrawableListener.DrawableLeftListener drawableLeftListener;
private DrawableListener.DrawableTopListener drawableTopListener;
private DrawableListener.DrawableBottomListener drawableBottomListener;
private Context context;
public DrawableTextView(Context context) {
this(context, null);
init(context);
}
public DrawableTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init(context);
}
public DrawableTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DrawableTextView, defStyleAttr, 0);
leftDrawableHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_leftDrawableHeight,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
leftDrawableWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_leftDrawableWidth,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
rightDrawableHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_rightDrawableHeight,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
rightDrawableWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_rightDrawableWidth,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
topDrawableHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_topDrawableHeight,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
topDrawableWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_topDrawableWidth,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
bottomDrawableHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_bottomDrawableHeight,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
bottomDrawableWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_bottomDrawableWidth,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, -1, getResources().getDisplayMetrics()));
strokeWidth = typedArray.getFloat(R.styleable.DrawableTextView_StrokeWidth, 0);
typedArray.recycle();
init(context);
}
private void init(Context context) {
//自定義加粗程度 建議0.3f
if (strokeWidth != 0) {
TextPaint paint = getPaint();
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
}
drawable();
}
private void drawable() {
Drawable[] drawables = getCompoundDrawables();
for (int i = 0; i < drawables.length; i++) {
setDrawableSize(drawables[i], i);
}
//放置圖片
setCompoundDrawables(drawables[DRAWABLE_LEFT], drawables[DRAWABLE_TOP], drawables[DRAWABLE_RIGHT], drawables[DRAWABLE_BOTTOM]);
}
//設置drawableRight 圖片的點擊監聽
public void setDrawableRightListener(DrawableListener.DrawableRightListener drawableRightListener) {
this.drawableRightListener = drawableRightListener;
}
public void setDrawableLeftListener(DrawableListener.DrawableLeftListener drawableLeftListener) {
this.drawableLeftListener = drawableLeftListener;
}
public void setDrawableTopListener(DrawableListener.DrawableTopListener drawableTopListener) {
this.drawableTopListener = drawableTopListener;
}
public void setDrawableBottomListener(DrawableListener.DrawableBottomListener drawableBottomListener) {
this.drawableBottomListener = drawableBottomListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
if (drawableRightListener != null) {
Drawable drawableRight = getCompoundDrawables()[DRAWABLE_RIGHT];
if (drawableRight != null && event.getRawX() >= (getRight() - drawableRight.getBounds().width())
&& event.getRawX() < getRight()) {
drawableRightListener.drawableRightListener(this);
return true;
}
}
if (drawableLeftListener != null) {
Drawable drawableLeft = getCompoundDrawables()[DRAWABLE_LEFT];
if (drawableLeft != null && event.getRawX() <= (getLeft() + drawableLeft.getBounds().width())
&& event.getRawX() > getLeft()) {
drawableLeftListener.drawableLeftListener(this);
return true;
}
}
if (drawableTopListener != null) {
Drawable drawableTop = getCompoundDrawables()[DRAWABLE_TOP];
if (drawableTop != null && event.getRawY() <= (getTop() + drawableTop.getBounds().height())
&& event.getRawY() > getTop()) {
drawableTopListener.drawableTopListener(this);
return true;
}
}
if (drawableBottomListener != null) {
Drawable drawableBottom = getCompoundDrawables()[DRAWABLE_BOTTOM];
if (drawableBottom != null && event.getRawY() >= (getBottom() - drawableBottom.getBounds().height())
&& event.getRawY() < getBottom()) {
drawableBottomListener.drawableBottomListener(this);
return true;
}
}
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
//設置圖片的高度和寬度
private void setDrawableSize(Drawable drawable, int index) {
if (drawable == null) {
return;
}
//左上右下
int width = 0, height = 0;
switch (index) {
case DRAWABLE_LEFT:
width = leftDrawableWidth;
height = leftDrawableHeight;
break;
case DRAWABLE_TOP:
width = topDrawableWidth;
height = topDrawableWidth;
break;
case DRAWABLE_RIGHT:
width = rightDrawableWidth;
height = rightDrawableWidth;
break;
case DRAWABLE_BOTTOM:
width = bottomDrawableWidth;
height = bottomDrawableHeight;
break;
}
//如果沒有設置圖片的高度和寬度具使用默認的圖片高度和寬度
if (width < 0) {
width = drawable.getIntrinsicWidth();
}
if (height < 0) {
height = drawable.getIntrinsicHeight();
}
if (index == 0) {
leftWidth = width;
} else if (index == 2) {
rightWidth = width;
}
drawable.setBounds(0, 0, width, height);
}
}
```
必要的註釋,我已經寫在代碼裏了.裏面其實我做了一些自己的常用的封裝..
`
- 對於Drawable的點擊監聽,因為有時候實際的業務場景很複雜,陰間的產品需求可能會讓你只能對Drawable點擊觸發事件
- 設置字體的粗細程度,Textview我們雖然可以設置是否粗細,但是官方提供的API設置的太粗了,你仔細看藍湖上的字體粗細,有很大差別.
以下是使用方式
上面可以看到我的StrokeWidth是3,這個我給予的是float,你按照自己的感覺設置即可.
監聽要設置你Drawable位置的監聽,如果你的xml是DrawableLeft,在Activity裏你設置的DrawableTop點擊事件他是不會生效的.
為了方便大家複製下面是attrs裏的配置
````
其實上面的封裝沒有什麼高深的東西,都是一些基礎,不過一些涉及的東西比較亂而已,大家不用太注意細節,只要能解決項目中的實際問題即可.
- 學習Android的第十七天
- 這是一個吸貓文章的標題,甚至可以有兩行這麼多哦
- 學習Android的第四天
- 學習Android的第一天
- 含有邊框的TextView-Android
- 電池-Android
- 倒計時封裝-Android
- 標題和狀態欄滑動漸變(2)-Android
- 標題和狀態欄滑動漸變(1)-Android
- 關於選項卡三方庫FlycoTabLayout的使用及修改
- 關於第三方庫SmartTabLayout的一點小修改
- 關於遞歸反轉鏈表的思路
- 搜索歷史記錄的實現-Android
- 感覺讓人耳目一新的動畫庫Lottie
- Android-關於設備唯一ID的奇技淫巧
- 稍微巧妙的雙模塊聯動-ViewPager
- 動畫庫NineOldAndroids實戰自定義懸浮窗
- 關於項目中圓角及特殊圓角的實際使用問題
- 自定義TextView可控制Drawable大小