android自定义view 的进阶之路——(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33776306/article/details/52289342

           开发中不免会遇到android自带UI控件无法满足需求的情况,这时候就需要我们来自定义一个view。对于我这个不专业的新手来说还是有一定的挑战性的,所以看了很多人写的博客,自己也尝试着写了一个比较简单的自定义view.

       参考博客:http://blog.csdn.net/lmj623565791/article/details/24252901

       自定义view总的来说就是自定义属性,重写构造方法。在构造方法中获得我们自定义的属性值,重写onMesure和onDraw方法。

     首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

<span style="font-size:18px;color:#009900;"><span style="font-size:14px;color:#009900;"><?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- format的作用就是定义属性 大概有这几种类型(1. reference:参考某一资源ID,2color:颜色值,3boolean:布尔值,
    4,dimension:尺寸值,5. float:浮点值,6. integer:整型值,7.string:字符串,8. fraction:百分数,9. enum:枚举值  ,
    10. flag:位或运算) 定义属性时可以指定多种类型值,中间用"|"隔开。 这里我 定义了字体,字体颜色,字体大小3个属性 
    -->
   <attr name="titleText" format="string" />  
    <attr name="titleTextColor" format="color" />  
    <attr name="titleTextSize" format="dimension" />  
  
    <declare-styleable name="CustomTitleView">  
        <attr name="titleText" />  
        <attr name="titleTextColor" />  
        <attr name="titleTextSize" />  
    </declare-styleable>  
</resources></span></span>
      然后自定义一个view,重写构造方法

<span style="font-size:14px;color:#009900;background-color: rgb(255, 255, 255);"><span </span>
<span style="font-size:14px;color:#009900;background-color: rgb(255, 255, 255);">style="font-size:14px;color:#009900;">package com.example.viewtext;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

public class CustomTitleView extends View {

	/** 
     * 文本 
     */  
    private String mTitleText;  
    /** 
     * 文本的颜色 
     */  
    private int mTitleTextColor;  
    /** 
     * 文本的大小 
     */  
    private int mTitleTextSize;  
  
    /** 
     * 绘制时控制文本绘制的范围 
     */  
    private Rect mBound;  //绘制矩形
//    Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色 样式等绘制信息,指定了如何绘制文本和图形,
//    画笔对象有很多设置方法大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。      
    private Paint mPaint;  
 
 
  
    public CustomTitleView(Context context, AttributeSet attrs)  
    {  
        this(context, attrs, 0);  
    }  
  
    public CustomTitleView(Context context)  
    {  
        this(context, null);  
    }  
  
    /** 
     * 获得我自定义的样式属性 
     *  
     * @param context 
     * @param attrs 
     * @param defStyle 
     */  
    public CustomTitleView(Context context, AttributeSet attrs, int defStyle)  
    {  
        super(context, attrs, defStyle);  
        /** 
         * 获得我们所定义的自定义样式属性 
         */  
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);  
        int n = a.getIndexCount();  
        for (int i = 0; i < n; i++)  
        {  
            int attr = a.getIndex(i);  
            switch (attr)  
            {  
            case R.styleable.CustomTitleView_titleText:  
                mTitleText = a.getString(attr);  
                break;  
            case R.styleable.CustomTitleView_titleTextColor:  
                // 默认颜色设置为黑色  
                mTitleTextColor = a.getColor(attr, Color.BLACK);  
                break;  
            case R.styleable.CustomTitleView_titleTextSize:  
                // 默认设置为16sp,TypeValue也可以把sp转化为px  
                mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(  
                        TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));  
                break;  
  
            }  
  
        }  
        a.recycle();  
  
        /** 
         * 获得绘制文本的宽和高 
         */  
        mPaint = new Paint();  
        mPaint.setTextSize(mTitleTextSize);  
        // mPaint.setColor(mTitleTextColor);  
        mBound = new Rect();  
        mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);  
        //给此view添加点击事件
        this.setOnClickListener(new OnClickListener()  
        {  

            @Override  
            public void onClick(View v)  
            {  
                mTitleText = randomText();  
                postInvalidate();  
            }  

        });  
    }  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
    {  
    	int widthMode = MeasureSpec.getMode(widthMeasureSpec);  
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);  
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);  
        int width;  
        int height ;  
        if (widthMode == MeasureSpec.EXACTLY)  
        {  
            width = widthSize;  
        } else  
        {  
            mPaint.setTextSize(mTitleTextSize);  
            mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);  
            float textWidth = mBound.width();  
            int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());  
            width = desired;  
        }  
      
        if (heightMode == MeasureSpec.EXACTLY)  
        {  
            height = heightSize;  
        } else  
        {  
            mPaint.setTextSize(mTitleTextSize);  
            mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);  
            float textHeight = mBound.height();  
            int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());  
            height = desired;  
        }  
          
          
      
        setMeasuredDimension(width, height);      }  
  
    @Override  
    protected void onDraw(Canvas canvas)  
    {  
        mPaint.setColor(Color.YELLOW);  
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);  
  
        mPaint.setColor(mTitleTextColor);  
        canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);  
    }  
    //获取随机数
    private String randomText()  
    {  
        Random random = new Random();  
        Set<Integer> set = new HashSet<Integer>();  
        while (set.size() < 4)  
        {  
            int randomInt = random.nextInt(10);  
            set.add(randomInt);  
        }  
        StringBuffer sb = new StringBuffer();  
        for (Integer i : set)  
        {  
            sb.append("" + i);  
        }  
  
        return sb.toString();  
    }  
}
</span></span>

    最后,布局中调用自定义的view, 一定要引入我们的命名空间(   xmlns:custom="http://schemas.android.com/apk/res/com.example.viewtext"  com.example.viewtext是自定义view所在的包名。

<span style="font-size:18px;color:#009900;"><span style="font-size:14px;color:#009900;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.example.viewtext"  
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    tools:context="com.example.viewtext.MainActivity" >

    <com.example.viewtext.CustomTitleView  
        android:layout_width="200dp"  
        android:layout_height="100dp"  
        custom:titleText="0000"  
        custom:titleTextColor="#ff0000"  
        android:layout_centerInParent="true"  
        custom:titleTextSize="40sp" />  

</RelativeLayout></span></span>
最后运行的效果图:




猜你喜欢

转载自blog.csdn.net/qq_33776306/article/details/52289342