在做项目的时候,很多时候我们都要用到文字和图片一起显示,一般设置TextView的DrawableLeft、DrawableRight、DrawableTop、DrawableBottom就行了。但是有一种情况是当TextView的熟悉是fill_parent或者使用权重的时候并且设置了起Gravity的ceter的时候,Drawable图片是无法一起居中的,为了解决其,我们一般再套一层布局,然后设置TextView的熟悉是wrap_content,但是有时候嵌套过多的布局的时候,有可能发生StackOverFlow,所以必须要优化,下面说一下其中的一个解决方案。先上图
这个解决方案很粗糙,局限性很大,文字不能换行,换行之后就不准了,下面是源码:
- package com.example.testandroid;
-
- import java.lang.ref.WeakReference;
-
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.widget.TextView;
-
- public class DrawableTextView extends TextView {
-
- private WeakReference<Bitmap> normalReference;
- private WeakReference<Bitmap> pressReference;
- private WeakReference<Bitmap> showReference;
-
- private int normalColor = Color.WHITE, pressColor = Color.WHITE;
-
- private String text;
- private int textWidth = 0;
- private int textHeight = 0;
-
- public DrawableTextView(Context context) {
- super(context);
- }
-
- public DrawableTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public DrawableTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- initText();
- }
-
- private void initText() {
- text = super.getText().toString();
- initVariable();
- }
-
-
-
-
- private void initVariable() {
- textWidth = (int) (getPaint().measureText(text));
- final Rect rect = new Rect();
- getPaint().getTextBounds(text, 0, 1, rect);
- textHeight = rect.height();
- }
-
-
-
-
-
- public void setText(String text) {
- this.text = text;
- initVariable();
- invalidate();
- }
-
-
-
-
- public String getText() {
- return text;
- }
-
-
-
-
-
-
-
-
- public void setDrawableLeftId(final int normalDrawableId, final int pressDrawableId) {
- normalReference = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getResources(), normalDrawableId));
- if (pressDrawableId != -1) {
- pressReference = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getResources(), pressDrawableId));
- }
- showReference = normalReference;
- invalidate();
- }
-
-
-
-
-
-
-
-
- public void setTextColor(final int normalColor, final int pressColor) {
- this.normalColor = normalColor;
- this.pressColor = pressColor;
- getPaint().setColor(normalColor);
- initVariable();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (showReference != null && showReference.get() != null) {
- final int bitmapWidth = showReference.get().getWidth();
- final int bitmapHeight = showReference.get().getHeight();
- final int viewHeight = getHeight();
- final int drawablePadding = getCompoundDrawablePadding();
- final int start = (getWidth() - (bitmapWidth + drawablePadding + textWidth)) >> 1;
- canvas.drawBitmap(showReference.get(), start, (viewHeight >> 1) - (bitmapHeight >> 1), getPaint());
-
-
-
-
-
- canvas.drawText(text, start + drawablePadding + bitmapWidth, (viewHeight >> 1) + (textHeight >> 1), getPaint());
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- if (pressReference != null && pressReference.get() != null) {
- showReference = pressReference;
- }
- getPaint().setColor(pressColor);
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- if (normalReference != null && normalReference.get() != null) {
- showReference = normalReference;
- }
- getPaint().setColor(normalColor);
- }
- invalidate();
- return super.onTouchEvent(event);
- }
-
- }
xml布局:
- <com.example.testandroid.DrawableTextView
- android:id="@+id/my_textview"
- android:layout_width="fill_parent"
- android:layout_marginTop="20dp"
- android:background="@drawable/text_selector"
- android:drawablePadding="8dp"
- android:textColor="@color/standard_orange"
- android:layout_height="wrap_content"
- android:padding="15dp"
- android:textSize="16sp"
- android:text="有Drawable的TextView" />
调用代码:
- DrawableTextView drawableTextView = (DrawableTextView) getView().findViewById(R.id.my_textview);
- drawableTextView.setDrawableLeftId(R.drawable.bg_btn_delete_normal, R.drawable.bg_btn_delete_pressed);
- drawableTextView.setTextColor(getResources().getColor(R.color.standard_orange), getResources().getColor(R.color.standard_white));
- drawableTextView.setText("我在动态修改Text啦");
其实还有更加方便的方法,下面朋友借鉴某个网友的代码(地址我就不知道了):
- @Override
- protected void onDraw(Canvas canvas) {
- Drawable[] drawables = getCompoundDrawables();
- if (drawables != null) {
- Drawable drawableLeft = drawables[0];
- if (drawableLeft != null) {
- final float textWidth = getPaint().measureText(getText().toString());
- final int drawablePadding = getCompoundDrawablePadding();
- final int drawableWidth = drawableLeft.getIntrinsicWidth();
- final float bodyWidth = textWidth + drawableWidth + drawablePadding;
- canvas.translate((getWidth() - bodyWidth) / 2, 0);
- }
- }
- super.onDraw(canvas);
- }
xml布局:
- <com.example.testandroid.DrawableTextView
- android:id="@+id/my_textview"
- android:layout_width="fill_parent"
- android:layout_marginTop="20dp"
- android:background="@drawable/text_selector"
- android:drawablePadding="8dp"
- android:drawableLeft="@drawable/clear_edittext_selector"
- android:textColor="@color/text_color_selector"
- android:layout_height="wrap_content"
- android:padding="15dp"
- android:textSize="16sp"
- android:text="有Drawable的TextView" />
嗯,自己写这个东西,也学到了一些东西,大家有什么更好的方法,大家可以讨论一下。
另外的解决思路:
http://blog.csdn.net/catoop/article/details/23947345
TextView的drawableLeft、drawableRight和drawableTop是一个常用、好用的属性,可以在文本的上下左右放置一个图片,而不使用更加复杂布局就能达到,我也常常喜欢用RadioButton的这几个属性实现很多效果,但是苦于不支持让drawbleLeft与文本一起居中,设置gravity为center也无济于事,终于有空研究了一下,这里与大家一起分享。
布局XML
- <com.assistant.expand.customview.DrawableCenterButton
- android:gravity="left|center_vertical"
- android:drawableLeft="@drawable/icon_erweima"
- android:drawablePadding="5dp"
- android:id="@+id/btn_scale"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/transparent"
- android:singleLine="true"
- android:text="扫描二维码签到"
- android:textColor="@color/color_button2"
- android:textSize="17sp" />
-
-
-
-
-
- public class DrawableCenterTextView extends TextView {
-
- public DrawableCenterTextView(Context context, AttributeSet attrs,
- int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public DrawableCenterTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public DrawableCenterTextView(Context context) {
- super(context);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- Drawable[] drawables = getCompoundDrawables();
- if (drawables != null) {
- Drawable drawableLeft = drawables[0];
- if (drawableLeft != null) {
- float textWidth = getPaint().measureText(getText().toString());
- int drawablePadding = getCompoundDrawablePadding();
- int drawableWidth = 0;
- drawableWidth = drawableLeft.getIntrinsicWidth();
- float bodyWidth = textWidth + drawableWidth + drawablePadding;
- canvas.translate((getWidth() - bodyWidth) / 2, 0);
- }
- }
- super.onDraw(canvas);
- }
- }
下面是用Button的Right 例子
-
-
-
-
-
- public class DrawableCenterButton extends Button {
-
- public DrawableCenterButton(Context context) {
- super(context);
-
- }
-
- public DrawableCenterButton(Context context, AttributeSet attrs,
- int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public DrawableCenterButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
-
- @Override
- protected void onDraw(Canvas canvas) {
- Drawable[] drawables = getCompoundDrawables();
- if (drawables != null) {
- Drawable drawableLeft = drawables[2];
- if (drawableLeft != null) {
-
- float textWidth = getPaint().measureText(getText().toString());
- int drawablePadding = getCompoundDrawablePadding();
- int drawableWidth = 0;
- drawableWidth = drawableLeft.getIntrinsicWidth();
- float bodyWidth = textWidth + drawableWidth + drawablePadding;
- setPadding(0, 0, (int)(getWidth() - bodyWidth), 0);
- canvas.translate((getWidth() - bodyWidth) / 2, 0);
- }
- }
- super.onDraw(canvas);
- }
- }