Android 自己画View -- drawable.draw 以及 drawText

转载自http://blog.csdn.net/chen930724/article/details/49913969
今天遇到一个要自己画View的问题,  其实可以通过多个View 组合来实现, 但是不是太好, 于是就自己画了
效果图如下:


其实可以一个ImageView  在加TextView TranslationY来解决
用translation来解决的画, 需要自己设置 minHeight, 防止 移动的过程中 TextView被移到外面去了看不见

ok 下面来说说, 自己画的画 该怎么解决,
很明显, 需要画一个图片 和一个 Text
1. 画图 Drawable.draw(canvas);
     需要注意的是,  我们的设计给了两个状态的图,  一个是按压状态下的一个是正常状态下得.
     所以我们在获取Drawable 的是时候 转成BitMapDrawable 再来获取bitmap 是不可取的.
     其实drawable 它本身有一个 draw 方法, 只要我们调用 setBounds 设置范围, 在调用draw 方法就可以直接画了
2. 画 Text 
void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) 
x 代表  左上角顶点位置 x坐标
y 代表的是 基准线的位置,  注意这不是左上角顶点y坐标
所以在 drawText的时候需要注意 位置的问题

ok 下面直接上代码: 
[java]  view plain  copy
  1. public class ImgWithNumTipsView extends View {  
  2.     public static final String TAG = "IconImgWithTipNumView";  
  3.   
  4.     public ImgWithNumTipsView(Context context, AttributeSet attrs) {  
  5.         super(context, attrs);  
  6.         initAttr(attrs);  
  7.         initView();  
  8.     }  
  9.   
  10.     public ImgWithNumTipsView(Context context, AttributeSet attrs, int defStyleAttr) {  
  11.         super(context, attrs, defStyleAttr);  
  12.         initAttr(attrs);  
  13.         initView();  
  14.     }  
  15.   
  16.     private int mTipsTextColor;  
  17.     private int mImgScrId;  
  18.     private int mTipsNum;  
  19.     private int mTipsTextSize;  
  20.     private int textMarginLeftSize;  
  21.   
  22.     private Drawable mDrawable;  
  23.     private Paint mTxtPain;  
  24.     private String mTipsString;  
  25.   
  26.     private void initAttr(AttributeSet attrs) {  
  27.         TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ImageNumTipsView);  
  28.         mTipsTextColor = typedArray.getColor(R.styleable.ImageNumTipsView_numTipsTextColor, 0XFFFFFFFF);  
  29.         mImgScrId = typedArray.getResourceId(R.styleable.ImageNumTipsView_imgSrc, -1);  
  30.   
  31.         int defaultTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 11, getResources().getDisplayMetrics());  
  32.         int defaultMarginLeftSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());  
  33.   
  34.         mTipsTextSize = typedArray.getDimensionPixelSize(R.styleable.ImageNumTipsView_numTipsTextSize, defaultTextSize);  
  35.         textMarginLeftSize = typedArray.getDimensionPixelSize(R.styleable.ImageNumTipsView_numTipsTextMarginLeft, defaultMarginLeftSize);  
  36.   
  37.         mTipsNum = typedArray.getInt(R.styleable.ImageNumTipsView_numTipsText, 10);  
  38.         mTipsString = mTipsNum + "";  
  39.   
  40.         if (mImgScrId == -1) {  
  41.             throw new RuntimeException("ImgScrId is error");  
  42.         }  
  43.     }  
  44.   
  45.     private void initView() {  
  46.         mTxtPain = new Paint();  
  47.         mTxtPain.setColor(mTipsTextColor);  
  48.         mTxtPain.setFlags(Paint.ANTI_ALIAS_FLAG);  
  49.         mTxtPain.setTextSize(mTipsTextSize);  
  50.         setDrawable(getResources().getDrawable(mImgScrId));  
  51.     }  
  52.   
  53.     @Override  
  54.     protected void onDraw(Canvas canvas) {  
  55.         super.onDraw(canvas);  
  56.         mDrawable.draw(canvas);  
  57.   
  58.         int textLeft = mDrawable.getIntrinsicWidth() + textMarginLeftSize;  
  59.         int textTop = 0;  
  60.         int textRight = textLeft + getStringWidth(mTipsString);  
  61.         int textBottom = getStringHeight();  
  62.   
  63.         Rect textRect = new Rect(textLeft, textTop, textRight, textBottom);  
  64.         Paint.FontMetricsInt fontMetrics = mTxtPain.getFontMetricsInt();  
  65.         int baseline = (textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2;  
  66.   
  67.         canvas.drawText(mTipsString, textLeft, baseline, mTxtPain);  
  68.     }  
  69.   
  70.     private int getStringWidth(String str) {  
  71.         return (int) mTxtPain.measureText(str);  
  72.     }  
  73.   
  74.     private int getStringHeight() {  
  75.         Paint.FontMetrics fr = mTxtPain.getFontMetrics();  
  76.         return (int) Math.ceil(fr.descent - fr.top) + 2;  //ceil() 函数向上舍入为最接近的整数。  
  77.     }  
  78.   
  79.     @Override  
  80.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  81.         int widthSize = getStringWidth(mTipsString) + mDrawable.getIntrinsicWidth() + textMarginLeftSize;  
  82.         int heightSize = getStringHeight() / 2 + mDrawable.getIntrinsicWidth();  
  83.   
  84.         widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);  
  85.         heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);  
  86.         setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);  
  87.     }  
  88.   
  89.     public int getTipsNum() {  
  90.         return mTipsNum;  
  91.     }  
  92.   
  93.     public void setTipsNum(int tipsNum) {  
  94.         mTipsNum = tipsNum;  
  95.         if (mTipsNum < 999) {  
  96.             mTipsString = "" + tipsNum;  
  97.         } else {  
  98.             mTipsString = "999+";  
  99.         }  
  100.         requestLayout();  
  101.     }  
  102.   
  103.     public void setTipsText(String text) {  
  104.         mTipsString = text;  
  105.         requestLayout();  
  106.         requestLayout();  
  107.     }  
  108.   
  109.     public void setTipsTextColor(int color) {  
  110.         mTipsTextColor = color;  
  111.         mTxtPain.setColor(color);  
  112.         invalidate();  
  113.     }  
  114.   
  115.     /** 
  116.      * @param sizePx 像素为单位 
  117.      */  
  118.     public void setTipsTextSize(int sizePx) {  
  119.         mTipsTextSize = sizePx;  
  120.         mTxtPain.setTextSize(sizePx);  
  121.         requestLayout();  
  122.     }  
  123.   
  124.     public void setDrawable(Drawable drawable) {  
  125.         mDrawable = drawable;  
  126.         Rect drawableRect = new Rect(0, getStringHeight() / 2, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight() + getStringHeight() / 2);  
  127.         mDrawable.setBounds(drawableRect);  
  128.         requestLayout();  
  129.     }  
  130.   
  131. }  

一些总结:
mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight() 可以获得 drawable的真实高度
mTxtPain.measureText(str); 可以获取 画出来的 字符串的宽度

Paint.FontMetrics fr = mTxtPain.getFontMetrics();
Math.ceil(fr.descent - fr.top) + 2;  //可以获得 话来着的Text 所占的高度

invalidate(); 会重画, 但是不会重新布局, 不会重新测量
requestLayout(); 会重新布局, 重新测量

普通图片的drawable 可以强转成 bitmapDrawable 
selector 的drawable不可以, 他不是 bitmapDrawable

mTxtPain.setFlags(Paint.ANTI_ALIAS_FLAG);// 设置抗锯齿
mTxtPain.setTextSize(mTipsTextSize);// 这里设置的 像素大小, 不是 sp

关于 DrawText 的一些文章:
Drawable、Bitmap、Canvas和Paint的关系以及部分使用方法

Android Canvas drawText相关:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值