码迷,mamicode.com
首页 > 移动开发 > 详细

Android自定义控件---“取消”视图

时间:2016-04-22 18:46:38      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

一、前言
好久没更新博客了,最近一直在忙,找实习,整理毕业资料,找房子等等。现在大部分基本忙完了,这几天在公司写的一些自定义控件,打算发出来与大家分享。

首先看看最终的效果图

技术分享

这个自定义视图的应用场景,主要用于替代对话框左上角或者右上角的取消按钮。按照我以前的做法,都是设计师发给我一张图片,我自己创建一个ImageView,再把图片设置进去就结束了。如果有天产品经理看得不爽,想要圆形,或矩形,对角线想要XXX颜色。又得等设计师发图了(本人不太会PS啊)。所以为了避免麻烦,打算自己写一个。

二、自定义控件个人思路
创建了一个CustomCancelView类,直接继承View。重写里面的onMeasure和onDraw方法。

1、重写onMeasure方法,强制将视图设置为宽度和高度相等。在Xml文件中只写layout_width属性值就可以了,layout_height属性的值随便写。
@Override
 protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
}

2、接下来比较麻烦的就是重写onDraw方法。
在onDraw方法里面画一个圆形,矩形,圆矩形是不难的。
那么要思考的问题就是怎么画对角线,并且这个对角线的大小要随着该视图的大小改变而改变。

我以画一个圆形的左对角线为例子。
(1)首先我们假设这个矩形的黑色边框就是我们控件的视图边界,设它的宽度width和高度height为100(这个黑色边框我们不可见。)
技术分享

(2) 再画一个圆形,这个蓝色的圆形就是我们可见的视图。

技术分享

(3) 获取圆形的半径,半径为circleRadius=width/2。即半径50(图中的三条线为圆的半径)

技术分享

(4) 再画一条红色的垂直线,由于1,2,3边构成的三角形很明显就是一个等腰三角形嘛(哎,我数学不太好。),设1,2边为X,3边的值,我们知道是50(这是半径值啊)。根据勾股定理解出X的值约等于35。也就是1,2边的长度为35。
程序中的代码为int rectangleHalf=(int)Math.sqrt((circleRadius*circleRadius)/2);
技术分享

(5)接下来再计算图中绿色点的坐标,设坐标为(leftDiagonalStartX,leftDiagonalStartY)。
x=半径50-2边的值(35)=15
y=半径值50-1边的值(35)=15。
所以这个绿色点坐标为(15,15)
程序代码
leftDiagonalStartX = leftDiagonalStartY = circleRadius - rectangleHalf  
技术分享

(6)设这个右下角的绿色点坐标为(leftDiagonalEndX ,leftDiagonalEndY)。则
x=半径值50+5边的值(35)=85
y=半径值50+6边的值(35)=85。
所以这个绿色点坐标为(85,85)
程序代码
 leftDiagonalEndX = leftDiagonalEndY = circleRadius + rectangleHalf
技术分享

根据数学定义:两点确定一条直线。
最后调用canvas.drawLine()绘制这条左对角线出来

关于右对角线的绘制就不说了,基本思路和上面讲的差不多。

关于onDraw方法的核心代码如下
@Override
 protected void onDraw(Canvas canvas) {
    //计算圆的半径
    circleRadius = getWidth() / 2;

    ////绘制正方形/圆形/圆矩形(注意绘制此图形的目的是用来作为背景)。
    drawView(canvas , paintTemp) ;

    //得到圆内接矩形的长度的一半
    int rectangleHalf = (int) Math. sqrt(( circleRadius * circleRadius ) / 2) ;

    //左对角线的坐标
    int leftDiagonalStartX, leftDiagonalStartY , leftDiagonalEndX, leftDiagonalEndY;

    //计算左对角线的坐标(需要考虑paintWidth和diagonalLength对对角线的影响,觉得这两个参数影响代码阅读可以暂时去掉)
    leftDiagonalStartX = leftDiagonalStartY = circleRadius - rectangleHalf + paintWidth + diagonalLength ;
    leftDiagonalEndX = leftDiagonalEndY = circleRadius + rectangleHalf - paintWidth - diagonalLength;

    //绘制左对角线
    drawDiagonal(canvas , leftDiagonalStartX, leftDiagonalStartY, leftDiagonalEndX , leftDiagonalEndY, diagonalLeftColor , paintCapRound) ;

    //右对角线的坐标
    int rightDiagonalStartX, rightDiagonalStartY , rightDiagonalEndX, rightDigonalEndY;
    //计算右对角线的坐标(需要考虑paintWidth和diagonalLength对对角线的影响,觉得这两个参数影响代码阅读可以暂时去掉)
    rightDiagonalStartX = circleRadius + rectangleHalf - paintWidth - diagonalLength;
    rightDiagonalStartY = circleRadius - rectangleHalf + paintWidth + diagonalLength;
    rightDiagonalEndX = circleRadius - rectangleHalf + paintWidth + diagonalLength;
    rightDigonalEndY = circleRadius + rectangleHalf - paintWidth - diagonalLength;
    //绘制右对角线
    drawDiagonal(canvas , rightDiagonalStartX, rightDiagonalStartY, rightDiagonalEndX, rightDigonalEndY , diagonalRightColor, paintCapRound);

    //绘制正方形/圆形/圆矩形
    drawView(canvas , mPaint) ;
}

/**
* 绘制视图
*
* @param canvas
 * @param paint
 */
public void drawView(Canvas canvas , Paint paint) {
    if (cancelViewType == SQUARE) {
        canvas.drawRect(paintWidth , paintWidth, getWidth() - paintWidth, getHeight() - paintWidth, paint) ;
    } else if (cancelViewType == CIRCLE) {
        canvas.drawCircle(circleRadius , circleRadius, circleRadius - paintWidth , paint);
    } else if (cancelViewType == ROUNDED_RECTANGLE) {
        canvas.drawRoundRect(new RectF(paintWidth, paintWidth, getWidth() - paintWidth, getHeight() - paintWidth), roundDegree, roundDegree , paint);
    } else {
        Log.e( "------------->", "视图类型错误!" );
    }
}


/**
* 绘制对角线
*
* @param canvas
 * @param diagonalStartX
 * @param diagonalStartY
 * @param diagonalEndX
 * @param diagonalEndY
 */
public void drawDiagonal(Canvas canvas , int diagonalStartX, int diagonalStartY, int diagonalEndX, int diagonalEndY , int diagonalColor, boolean paintCapRound) {
    Paint diagonalPaint = new Paint();
    diagonalPaint.setAntiAlias( true);
    diagonalPaint.setColor(diagonalColor) ;
    diagonalPaint.setStrokeWidth( diagonalPaintWidth);
    diagonalPaint.setStyle(Paint.Style. STROKE);
    if (paintCapRound ) {
        //设置画笔的半圆风格
        diagonalPaint.setStrokeCap(Paint.Cap. ROUND);
    } else {
        //设置画笔默认值
        diagonalPaint.setStrokeCap(Paint.Cap. SQUARE);
    }
    //绘制对角线
    canvas.drawLine(diagonalStartX , diagonalStartY, diagonalEndX, diagonalEndY , diagonalPaint);
}

(7)XML文件布局
注意在XML文件一定要添加这句xmlns:app="http://schemas.android.com/apk/res-auto"(其中xmlns:=xxx这里的名字可以自定义)
<? xml version="1.0" encoding= "utf-8"?>
<LinearLayout xmlns: android="http://schemas.android.com/apk/res/android"
    xmlns: app="http://schemas.android.com/apk/res-auto"
    xmlns: tools="http://schemas.android.com/tools"
    android :layout_width="match_parent"
    android :layout_height="match_parent"
    android :background="#d4d4d4"
    android :orientation="vertical">

    <TextView
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :padding="10dp"
        android :text="正方形,圆形,圆矩形"
        android :textColor="#000000"
        android :textSize="16dp" />

    <LinearLayout
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :orientation="horizontal">

        <per.edward.ui.CustomCancelView
            android :id="@+id/cancel_one"
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp" />

        <per.edward.ui.CustomCancelView
            android :id="@+id/cancel_two"
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Type="circle" />

        <per.edward.ui.CustomCancelView
            android :id="@+id/cancel_three"
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Round_Degree="35"
            app :CC_Type="rounded_rectangle" />
    </LinearLayout>

    <TextView
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :padding="10dp"
        android :text="正方形(改变了边框的颜色),圆形(改变了背景颜色),圆矩形(改变了对角线的颜色)"
        android :textColor="#000000"
        android :textSize="16dp" />

    <LinearLayout
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :orientation="horizontal">

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Stroke_Width="3dp"
            app :CC_Stroke_Width_Color="#31b2f7" />

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Background="#7ccf66"
            app :CC_Type="circle" />

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Diagonal_Left_Color="#3af700"
            app :CC_Diagonal_Right_Color="#fff200"
            app :CC_Round_Degree="35"
            app :CC_Type="rounded_rectangle" />
    </LinearLayout>

    <TextView
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :padding="10dp"
        android :text="正方形(边框和背景设置为透明),圆形(对角线变宽了,并且对角线末端为圆角),圆矩形(对角线的末端为矩形)"
        android :textColor="#000000"
        android :textSize="16dp" />

    <LinearLayout
        android :layout_width="match_parent"
        android :layout_height="wrap_content"
        android :orientation="horizontal">

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Background="#00000000"
            app :CC_Diagonal_Length ="10dp"
            app :CC_Stroke_Width_Color="#00000000" />

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Background="#e079ead7"
            app :CC_Diagonal_Length ="10dp"
            app :CC_Diagonal_Paint_Width="10dp"
            app :CC_Type="circle" />

        <per.edward.ui.CustomCancelView
            android :layout_width="80dp"
            android :layout_height="80dp"
            android :layout_margin="10dp"
            app :CC_Diagonal_Left_Color="#596dd1"
            app :CC_Diagonal_Length ="10dp"
            app :CC_Diagonal_Paint_Width="10dp"
            app :CC_Diagonal_Right_Color="#bd79c4"
            app :CC_Paint_Cap_Round="false"
            app :CC_Round_Degree="35"
            app :CC_Type="rounded_rectangle" />
    </LinearLayout>
</LinearLayout>

三、结束
分享写完,我搬砖去了。






Android自定义控件---“取消”视图

标签:

原文地址:http://blog.csdn.net/u012814441/article/details/51220396

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!