您的位置:首页 > 移动开发 > Android开发

Android 自定义View (二) 进阶

2015-09-01 10:19 561 查看
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125

继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义View (一),如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。

自定义View显示一张图片,下面包含图片的文本介绍,类似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。

还记得上一篇讲的4个步骤么:

1、自定义View的属性

2、在View的构造方法中获得我们自定义的属性

[ 3、重写onMesure ]

4、重写onDraw

直接切入正题:

1、在res/values/attr.xml

[html] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>  

<resources>  

  

    <attr name="titleText" format="string" />  

    <attr name="titleTextSize" format="dimension" />  

    <attr name="titleTextColor" format="color" />  

    <attr name="image" format="reference" />  

    <attr name="imageScaleType">  

        <enum name="fillXY" value="0" />  

        <enum name="center" value="1" />  

    </attr>  

  

    <declare-styleable name="CustomImageView">  

        <attr name="titleText" />  

        <attr name="titleTextSize" />  

        <attr name="titleTextColor" />  

        <attr name="image" />  

        <attr name="imageScaleType" />  

    </declare-styleable>  

  

</resources>  

2、在构造中获得我们的自定义属性:

[java] view
plaincopy





/** 

     * 初始化所特有自定义类型 

     *  

     * @param context 

     * @param attrs 

     * @param defStyle 

     */  

    public CustomImageView(Context context, AttributeSet attrs, int defStyle)  

    {  

        super(context, attrs, defStyle);  

  

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);  

  

        int n = a.getIndexCount();  

  

        for (int i = 0; i < n; i++)  

        {  

            int attr = a.getIndex(i);  

  

            switch (attr)  

            {  

            case R.styleable.CustomImageView_image:  

                mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));  

                break;  

            case R.styleable.CustomImageView_imageScaleType:  

                mImageScale = a.getInt(attr, 0);  

                break;  

            case R.styleable.CustomImageView_titleText:  

                mTitle = a.getString(attr);  

                break;  

            case R.styleable.CustomImageView_titleTextColor:  

                mTextColor = a.getColor(attr, Color.BLACK);  

                break;  

            case R.styleable.CustomImageView_titleTextSize:  

                mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,  

                        16, getResources().getDisplayMetrics()));  

                break;  

  

            }  

        }  

        a.recycle();  

        rect = new Rect();  

        mPaint = new Paint();  

        mTextBound = new Rect();  

        mPaint.setTextSize(mTextSize);  

        // 计算了描绘字体需要的范围  

        mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound);  

  

    }  

3、重写onMeasure

[java] view
plaincopy





@Override  

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

{  

    // super.onMeasure(widthMeasureSpec, heightMeasureSpec);  

  

    /** 

     * 设置宽度 

     */  

    int specMode = MeasureSpec.getMode(widthMeasureSpec);  

    int specSize = MeasureSpec.getSize(widthMeasureSpec);  

  

    if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  

    {  

        Log.e("xxx", "EXACTLY");  

        mWidth = specSize;  

    } else  

    {  

        // 由图片决定的宽  

        int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();  

        // 由字体决定的宽  

        int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();  

  

        if (specMode == MeasureSpec.AT_MOST)// wrap_content  

        {  

            int desire = Math.max(desireByImg, desireByTitle);  

            mWidth = Math.min(desire, specSize);  

            Log.e("xxx", "AT_MOST");  

        }

else

{

mWidth  
= specSize

}
 

    }  

  

    /*** 

     * 设置高度 

     */  

  

    specMode = MeasureSpec.getMode(heightMeasureSpec);  

    specSize = MeasureSpec.getSize(heightMeasureSpec);  

    if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  

    {  

        mHeight = specSize;  

    } else  

    {  

        int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();  

        if (specMode == MeasureSpec.AT_MOST)// wrap_content  

        {  

            mHeight = Math.min(desire, specSize);  

        } 

else

{

mHeight  = specSize;



    }  

    setMeasuredDimension(mWidth, mHeight);  

  

}  

4、重写onDraw

[java] view
plaincopy





@Override  

    protected void onDraw(Canvas canvas)  

    {  

        // super.onDraw(canvas);  

        /** 

         * 边框 

         */  

        mPaint.setStrokeWidth(4);  

        mPaint.setStyle(Paint.Style.STROKE);  

        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);  

        }  

  

    }  

代码,结合注释和第一篇View的使用,应该可以看懂,不明白的留言。下面我们引入我们的自定义View:

[html] view
plaincopy





<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

    xmlns:tools="http://schemas.android.com/tools"  

    xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.customview02"  

    android:layout_width="match_parent"  

    android:layout_height="match_parent"  

    android:orientation="vertical" >  

  

    <com.zhy.customview02.view.CustomImageView  

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content"  

        android:layout_margin="10dp"  

        android:padding="10dp"  

        zhy:image="@drawable/ic_launcher"  

        zhy:imageScaleType="center"  

        zhy:titleText="hello andorid ! "  

        zhy:titleTextColor="#ff0000"  

        zhy:titleTextSize="30sp" />  

  

    <com.zhy.customview02.view.CustomImageView  

        android:layout_width="100dp"  

        android:layout_height="wrap_content"  

        android:layout_margin="10dp"  

        android:padding="10dp"  

        zhy:image="@drawable/ic_launcher"  

        zhy:imageScaleType="center"  

        zhy:titleText="helloworldwelcome"  

        zhy:titleTextColor="#00ff00"  

        zhy:titleTextSize="20sp" />  

  

    <com.zhy.customview02.view.CustomImageView  

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content"  

        android:layout_margin="10dp"  

        android:padding="10dp"  

        zhy:image="@drawable/lmj"  

        zhy:imageScaleType="center"  

        zhy:titleText="妹子~"  

        zhy:titleTextColor="#ff0000"  

        zhy:titleTextSize="12sp" />  

  

</LinearLayout>  

我特意让显示出现3中情况:

1、字体的宽度大于图片,且View宽度设置为wrap_content

2、View宽度设置为精确值,字体的长度大于此宽度

3、图片的宽度大于字体,且View宽度设置为wrap_content

看看显示效果:



怎么样,对于这三种情况所展示的效果都还不错吧。

好了,就到这里,各位看官,没事留个言,顶一个呗~


源码点击下载

版权声明:本文为博主原创文章,未经博主允许不得转载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android view