android 子定义View(2)

onMeasure中获取自定义View的mode 和width, height,

// TODO 测量
int mode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);

通过MeasureSpec的三个mode类型, 而进行width和height的设置,

  如果是EXACTLY 测量的数据就是自定义view的高度, 在不居中 layout_width或layout_height

的取值为一个定值,

  如果是AT_MOST : 竟可能的大, 也就是Wrap_content, 自定义View测量的高和宽就是

内容的高度和宽度。

====》 获取了测量值mWidth和mHeight;

OnDraw()

  首先画外边框rect,

  之花边框,设置style为stroke =-=> mPaint.setStyle(Paint.Style.STROKE).只是

画一个边框线。

     /**
         * 边框
         */
        mPaint.setStrokeWidth(4);
        mPaint.setStyle(Paint.Style.STROKE);//设置绘画的图像样式,是否填充, Stroke 一个边框, Fill填充
        mPaint.setColor(Color.CYAN);
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

根据测量的高度和宽度以及自定义布局中设置的padding

    android:padding="10dp"

设置边框的四个方位距离父布局的间隔:

       rect.left = getPaddingLeft();
        rect.right = mWidth - getPaddingRight();
        rect.top = getPaddingTop();
        rect.bottom = mHeight - getPaddingBottom();

然后开始画文本

  设置画笔的样式

  并根据文本的宽度与测量的宽度对比, 是否完全显示文本, 还是显示成xxx...

  

      mPaint.setColor(mTextColor);
        mPaint.setStyle(Style.FILL);
        /**
         * 当前设置的宽度小于字体需要的宽度,将字体改为xxx...
         */
        if (mTextBound.width() > mWidth)
        {//测量的宽度大于文本的宽度, 将高位xxxx...    //这种情况,一般是 layout_width是一个定值
            TextPaint paint = new TextPaint(mPaint);
            String msg = TextUtils.ellipsize(mTitle, paint, (float) mWidth - getPaddingLeft() - getPaddingRight(),
                    TextUtils.TruncateAt.END).toString();
            canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint);

        } else
        {
            //正常情况,将字体居中
            canvas.drawText(mTitle, mWidth / 2 - mTextBound.width() * 1.0f / 2, mHeight - getPaddingBottom(), mPaint);
        }

最重要的是

    //取消使用掉的部分, 也就是文本部分, 剩下的显示图片
    rect.bottom -= mTextBound.height();

package com.zhy.customview02.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.zhy.customview02.R;

public class MyImageView extends View {
    /**
     * 控件的宽
     */
    private int mWidth;
    /**
     * 控件的高
     */
    private int mHeight;
    /**
     * 控件中的图片
     */
    private Bitmap mImage;
    /**
     * 图片的缩放模式
     */
    private int mImageScale;
    private static final int IMAGE_SCALE_FITXY = 0;
    private static final int IMAGE_SCALE_CENTER = 1;
    /**
     * 图片的介绍
     */
    private String mTitle;
    /**
     * 字体的颜色
     */
    private int mTextColor;
    /**
     * 字体的大小
     */
    private int mTextSize;

    private Paint mPaint;
    /**
     * 对文本的约束
     */
    private Rect mTextBound;
    /**
     * 控制整体布局
     */
    private Rect rect;

    public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray taArray = context.obtainStyledAttributes
                (attrs, R.styleable.CustomImageView, defStyleAttr, 0);
        initView(taArray);
    }
    public MyImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyImageView(Context context) {
        this(context, null);
    }

    /**
     * 初始化样式属性
     */
    public void  initView(TypedArray taArray) {
        int n = taArray.getIndexCount();
        for (int i = 0; i < n; i++) {
            //获取样式中的属性值
            int attr = taArray.getIndex(i);
            switch (attr)
            {
            case R.styleable.CustomImageView_image:
                mImage = BitmapFactory.decodeResource(getResources(), taArray.getResourceId(attr, 0));
                break;
            case R.styleable.CustomImageView_imageScaleType:
                mImageScale = taArray.getInt(attr, 0);
                break;
            case R.styleable.CustomImageView_titleText:
                mTitle = taArray.getString(attr);
                break;
            case R.styleable.CustomImageView_titleTextColor:
                mTextColor = taArray.getColor(attr, Color.BLACK);
                break;
            case R.styleable.CustomImageView_titleTextSize:
                mTextSize = taArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                        16, getResources().getDisplayMetrics()));
                break;

            }

        }
        taArray.recycle();

        //对布局和获取的初始化
        mPaint = new Paint();
        rect = new Rect();
        mTextBound = new Rect();
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(Color.BLUE);
        //计算文本描绘的区域
        mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO 测量
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        if(mode == MeasureSpec.EXACTLY){
            mWidth = width;
        }else{
            //文本的宽度
            int textWidth = getPaddingLeft() + getPaddingRight() +mTextBound.width();
            //图片的宽度
            int imageWidth = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
            if(mode == MeasureSpec.AT_MOST){
                int desire = Math.max(textWidth, imageWidth);
                mWidth = Math.min(desire, width);
            }

        }

        // TODO 测量
        int heightMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightsize = MeasureSpec.getSize(widthMeasureSpec);
        if(heightMode == MeasureSpec.EXACTLY){
            mHeight = heightsize;
        }else{
            //文本的宽度
            int textHeight= getPaddingLeft() + getPaddingRight() +mTextBound.width();
            //图片的宽度
            int imageHeight = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
            if(mode == MeasureSpec.AT_MOST){
                int desire = Math.max(textHeight, imageHeight);
                mHeight = Math.min(desire, heightsize);
            }

        }
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //    super.onDraw(canvas);
        /**
         * 边框
         */
        mPaint.setStrokeWidth(4);
        mPaint.setStyle(Paint.Style.STROKE);//设置绘画的图像样式,是否填充, Stroke 一个边框, Fill填充
        mPaint.setColor(Color.CYAN);
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

        rect.left = getPaddingLeft();
        rect.right = mWidth - getPaddingRight();
        rect.top = getPaddingTop();
        rect.bottom = mHeight - getPaddingBottom();

        mPaint.setColor(mTextColor);
        mPaint.setStyle(Style.FILL);
        /**
         * 设置文字, 当设置宽度小于字体需要的宽度, 将字体改为xxx....
         */
        if(mTextBound.width() > mWidth) {
            TextPaint paint = new TextPaint(mPaint);
            String msg  = TextUtils.ellipsize(mTitle, paint,
                    (float)mWidth - getPaddingLeft()- getPaddingRight(),
                    TextUtils.TruncateAt.END).toString();
            canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint);
        }else {//正常情况, 字体居中
            canvas.drawText(mTitle, mWidth/2 - mTextBound.width()*1.0f/2,
                                    mHeight - getPaddingBottom(), mPaint);

        }

        //取消使用掉的部分
        rect.bottom -= mTextBound.height();
        if(mImageScale == IMAGE_SCALE_FITXY) {
            canvas.drawBitmap(mImage, null, rect, mPaint);
        }else{//居中
            //计算居中的矩形范围
            rect.left = mWidth / 2 - mImage.getWidth() / 2;
            rect.right = mWidth / 2 + mImage.getWidth() / 2;
            rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2;
            rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2;
            canvas.drawBitmap(mImage, null, rect, mPaint);
        }

        /*

        //取消使用掉的快
        rect.bottom -= mTextBound.height();

        if (mImageScale == IMAGE_SCALE_FITXY){
            canvas.drawBitmap(mImage, null, rect, mPaint);
        } else{
            //计算居中的矩形范围
            rect.left = mWidth / 2 - mImage.getWidth() / 2;
            rect.right = mWidth / 2 + mImage.getWidth() / 2;
            rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2;
            rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2;

            canvas.drawBitmap(mImage, null, rect, mPaint);
        }
*/

    }

}
时间: 2024-10-11 11:23:33

android 子定义View(2)的相关文章

Android 自己定义View (二) 进阶

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自己定义View之旅.前面已经介绍过一个自己定义View的基础的样例,Android 自己定义View (一),假设你还对自己定义View不了解能够去看看.今天给大家带来一个略微复杂点的样例. 自己定义View显示一张图片,以下包括图片的文本介绍,类似相片介绍什么的,只是不重要,主要是学习自己定义View的使用方法么. 还记得上一篇讲的4个步骤么: 1.自己定

Android 自己定义View学习(2)

上一篇学习了基本使用方法,今天学一下略微复杂一点的.先看一下效果图 为了完毕上面的效果还是要用到上一期开头的四步 1,属性应该要有颜色,要有速度 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="speed" format="integer" /> <attr name="circleColor&qu

手把手带你画一个 时尚仪表盘 Android 自己定义View

拿到美工效果图.咱们程序猿就得画得一模一样. 为了不被老板喷,仅仅能多练啊. 听说你认为前面几篇都so easy,那今天就带你做个相对照较复杂的. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50468674 注意:每一篇博客都是建立在之前博客的基础知识上的,假设你刚接触自己定义view.能够来说说自己定义view简单学习的方式这里看我曾经的文章.记录了我学习自己定义view的过程,并且前几篇博客或多或少犯了一些错误(反复绘制,o

Android自己定义View基础篇(三)之SwitchButton开关

自己定义View基础篇(二) 自己定义View基础篇(一) 自己定义View原理 我在解说之前,先来看看效果图,有图有真相:(转换gif图片效果太差) 那来看看真实图片: 假设你要更改样式,请改动例如以下图片: switch_ball switch_bg switch_black switch_bottom 我在这里就不反复解说View与ViewGroup的关系,View的绘制流程.假设你对自己定义View还不甚了解.请看上面几篇文章. 用法 xml文件: <com.github.ws.swit

Android 自己定义View (四) 视频音量调控

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个以下的效果,我看以下一哥们说要用12张图片,这尼玛逆天的麻烦,细致看了一下感觉自己定义控件木有问题,就花点时间写了一个. 好了,进入正题,继续我们的自己定义View四部曲. 1.先分许须要的属性,两个小块的颜色.一张中间的图片.间隙大小.一个多少个块块.分析完成,開始写attr.xml <?xml version="1.

Android自己定义View画图实现拖影动画

前几天在"Android画图之渐隐动画"一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙.我又改进了一下.这次效果好多了. 先看效果吧: 然后我们来说说主要的做法: 依据画笔宽度,计算每一条线段两个顶点相应的四个点,四点连线.包围线段,形成一个路径. 后一条线段的路径的前两个点,取(等于)前一条线段的后两点.这样就衔接起来了. 把Path的Style改动为FILL.效果是这种: 能够看到一个个四边形.连成了路径. 好啦.如今说说如何依据两点计算出包围它

Android自己定义View之仪表盘

新建项目,新建DashBoardView继承自View实现OnGlobalLayoutListener接口,并重写OnDraw方法. 使用OnGlobalLayoutListener接口须要重写onGlobalLayout方法.在这种方法中我们将获取View的宽高. 新建例如以下变量: private Context mContext; private Paint mCirclePaint,mDegreePaint,mHourPaint,mMinPaint; private int mViewW

Android画图系列(二)——自己定义View绘制基本图形

这个系列主要是介绍下Android自己定义View和Android画图机制.自己能力有限.假设在介绍过程中有什么错误.欢迎指正 前言 在上一篇Android画图系列(一)--自己定义View基础中我们了解自己定义View相关的基本知识.只是,这些东西依然还是理论,接下来我们就实际绘制一些东西 在本篇文章中,我们先了解下面Canvas,而且画一些主要的图形 Canvas简单介绍 Canvas我们能够称之为画布.能够在上面绘制各种东西.是安卓平台2D图形绘制的基础.非常强大. 一般来说,比較基础的东

Android 自己定义控件实现刮刮卡效果 真的就仅仅是刮刮卡么

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40162163 , 本文出自:[张鸿洋的博客] 非常久以前也过一个html5的刮刮卡效果~~上次看到有人写Android的刮刮卡效果~~于是乎产生了本篇博客~~此类样例也比較多了,大家能够百度看看~只是还是通过本样例,带大家发掘一下.里面隐含的知识~ 1.Xfermode以及PorterDuff 假设大家还记得,以前在博客:完美实现图片圆角和圆形 简介过圆角的实现原理也是基于这个