自定义View

自定义View之前要掌握的东西
一、Android绘图三大API 1.Canvas类
(1)功能:Canvas代表了"依附"于指定View的画布,通过Canvas类的成员方法能够实现绘制各种图形。绘制一个图形由四部分组成:Bitmap、Canvas、Path/Rect/text等、Paint,其中Bitmap为绘制图形存放的像素位图,Canvas用于提供绘制图像方法、Paint为画笔、Path/Rect/text等分别为绘制图形的(轨迹/矩形/文本)
(2)构造方法 Canvas() :构造空的canvas对象 Canvas(Bitmap bitmap) :构造一个Canvas对象,并指定其bitmap
(3)常用方法
boolean clipRegion(Region region):剪切指定区域
void drawBitmap(Bitmap bitmap, float left, float top, Paint paint):在指定点(x,y)使用指定的画笔paint绘制位图
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint):在指定点(x,y)绘制从源位图中"挖取"的一块
void drawCircle(float cx, float cy, float radius, Paint paint):绘制原点为(cx,cy),半径为radius的圆
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint):绘制一条起点为(startX,startY),终点为(stopX,stopY)直线
void drawLines(float[] pts, int offset, int count, Paint paint):绘制多条直线,其中pts为一个浮点型数组提供绘制一条直接所需的数据(4个/条),count为绘制直线的条数
void drawOval(RectF oval, Paint paint):绘制一个椭圆,oval为绘制椭圆的矩形边界
void drawPath(Path path, Paint paint):沿着路径path绘制图形
void drawPoint(float x, float y, Paint paint):绘制一个点(x,y)
void drawPoints(float[] pts, int offset, int count, Paint paint):绘制pts数组中的多个点(2个值/点)
void drawRect(float left, float top, float right, float bottom, Paint paint):绘制一个矩形,其参数为距离屏幕边界的距离(边界为0)
void drawRoundRect(RectF rect, float rx, float ry, Paint paint):使用指定的画笔绘制圆角矩形,其中rect为矩形边界、rx/ry分别为以矩形顶点为(0,0)相对位置圆的x半径、y半径
void drawText(String text, float x, float y, Paint paint):以(x,y)为原点,使用指定画笔绘制文本
void drawTextOnPath(String text, Path path, float x, float y, Paint paint):以(x,y)为原点,使用指定的画笔沿着指定路径绘制文本
int getHeight():返回当前图层的高度
int getWidth():返回当前绘图层的宽度
void rotate(float degrees):对Canvas执行旋转变换;
void setBitmap(Bitmap bitmap):指定Canvas(画布)的位图Bitmap
void translate(float dx, float dy):相对于当前位置移动Canvas。向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动)
void skew(float sx,float sy):对Canvas执行倾斜变换

2.Paint类


(1)功能:Paint代表了Canvas上的画笔,Paint类主要用于设置绘制风格,包括画笔的颜色、画笔笔触粗细、填充风格等。
(2)构造方法 Paint() :使用默认设置构造一个Paint对象 Paint(int flags) :使用指定flags构造一个Paint对象 Paint(Paint paint) :使用已有画笔的设置构造一个新的Paint对象
(3)常用方法
void reset():恢复画笔到默认配置
void setARGB(int a, int r, int g, int b):设置画笔透明度和颜色,其参数分别代表透明度、红色、绿色、蓝色
void setAlpha(int a):设置画笔的透明度
void setAntiAlias(boolean aa):设置是否抗锯齿
void setColor(int color):设置画笔的颜色
void setFlags(int flags):设置画笔的flags(HINTING_OFF、HINTING_ON等)
void setHinting(int mode):设置画笔的提示模式
PathEffect setPathEffect(PathEffect effect):设置绘制路径时的路径效果(ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect)
Rasterizer setRasterizer(Rasterizer rasterizer)
Shader setShader(Shader shader):设置画笔的填充效果(BitmapShader, ComposeShader, LinearGradient, RadialGradient, SweepGradient)
void setShadowLayer(float radius, float dx, float dy, int color):设置阴影效果
void setStrokeJoin(Paint.Join join):设置画笔转弯处的连接风格(BEVEL-直线、MITER -锐角、ROUND-圆弧 )
void setStrokeWidth(float width):设置画笔宽度
void setStyle(Paint.Style style):设置Paint的填充风格(FILL-、FILL_AND_STROKE、STROKE )
void setTextAlign(Paint.Align align):设置绘制文本时的文字对齐方式(CENTER -居中、LEFT-靠左、RIGHT -靠右:以(x,y)为中心)
void setTextSize(float textSize):设置绘制文本的文字大小
3.Path类
(1)功能:Android提供的Path类预先在View上将N个点连成一条"路径",然后调用Canvas的drawPath(path,paint)方法即可沿着路径绘制图形。另外,Android还提供了PathEffect来定义绘制路径图形效果,其包含ComposePathEffect、CornerPathEffect、DashPathEffect、DiscretePathEffect、PathDashPathEffect、SumPathEffect六种效果
(2)构造方法 Path():构造一个Path对象 Path(Path src) :从另一个Path对象构造一个新的Path对象
(3)常用方法
boolean isEmpty():判定Path对象是否为空(即不包含直线或曲线),如果为空返回true
void lineTo(float x, float y):增加一条从上一点到当前点(x,y)的直线
void moveTo(float x, float y):设置下一个轮廓的开始点(x,y)
void rLineTo(float dx, float dy):以坐标为参照增加一条从上一点到当前点(x,y)的直线
void rMoveTo(float dx, float dy):以坐标为参照设置下一个轮廓的开始点(x,y)
void reset():删除Path对象的所有直线和曲线
void set(Path src):将当前Path对象的内容替换为对象src所包含的内容
void setFillType(Path.FillType ft):设置路径的填充类型
void setLastPoint(float dx, float dy):设置路径的最后一个点的坐标为(x,y)
void transform(Matrix matrix):通过matrix转换该路径中的点
void 
close() :释放资源


1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
3、重写onMesure
4、重写onDraw

1、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
format是值该属性的取值类型:
      reference    :     资源id
      color           :     颜色值
      boolean      :     布尔值
     dimension    :       尺寸值
     float             :     浮点值
     integer         :     整形值
     string           :     字符串
     fraction        :     百分数
     enum           :     枚举值
     flag              :     位或运算

<? xml version= "1.0"  encoding= "utf-8" ?>
<resources>
    <!--圆-->
    <attr  name= "rotateBack"  format= "color" />
    <declare-styleable  name= "RotateView" >
        <attr  name= "rotateBack"  />
    </declare-styleable>
</resources>


//这是是获取值的
public RotateView(Context context AttributeSet attrs , int defStyleAttr) {
    super(context attrs defStyleAttr) ;
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs R.styleable. RotateView ,defStyleAttr , 0) ;
    int n  = a.getIndexCount() ;
    for ( int i =  i < n  i++ )
    {
      int attr = a.getIndex(i) ;
        switch (attr){
            case R.styleable. RotateView_rotateBack:
                rotateBack = a.getColor(attr ,Color. BLUE) ;
                Log. d( TAG  , "颜色值---------->"+ rotateBack) ;
                break;
        }
    }
    a.recycle() ;
    init() ;
}

初始PaInt
  /**
     * 初始化
     */
    public void  init(){
        mPaint new Paint() ;
        //样式填充分3种  Paint.Style.FILL    :填充内部 Paint.Style.FILL_AND_STROKE  :填充内部和描边 Paint.Style.STROKE  :仅描边
        mPaint.setStyle(Paint.Style. FILL) ;
        //颜色
        mPaint.setColor( rotateBack) ;
        //锯齿功能
        mPaint.setAntiAlias( true) ;
        //画笔宽度
        mPaint.setStrokeWidth( 4) ;
        //设置阴影
//        mPaint.setShadowLayer(160,305,305,Color.GREEN);
        mWidth 200 ;
        mHigth 200 ;
            rotate( true) ;
    }


mPaint.setStyle(Paint.Style. FILL) ;
Paint.Style.FILL    :填充内部
Paint.Style.FILL_AND_STROKE  :填充内部和描边
Paint.Style.STROKE  :仅描边



<? xml version= "1.0"  encoding= "utf-8" ?>
<LinearLayout  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :layout_width= "match_parent"
    android :gravity= "center"
    android :layout_height= "match_parent"
    xmlns: custom = "http://schemas.android.com/apk/res-auto"
    android :weightSum= "1" >

    <com.example.jiangtao.testevent.custom_view.CustomTitleView
        android :layout_width= "wrap_content"
        android :layout_height= "wrap_content"
        custom :titleText =  "2342"
        android :layout_gravity= "center"
        android :id= "@+id/custom_title_view"
        android :padding= "20dp"
        custom :mTitleTextColor= "#000000"
        android :layout_centerInParent= "true"
        custom :titleTextSize= "50sp"
          />
</LinearLayout>


系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。

所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:


重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用

@Override
protected void  onMeasure( int widthMeasureSpec , int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec heightMeasureSpec) ;
    // 重写onMeasure的目的是处理warp_content模式
    // 获取宽度的模式
    int widthSpecMode = MeasureSpec. getMode(widthMeasureSpec) ;
    // 获取高度的模式
    int heightSpecMode = MeasureSpec. getMode(heightMeasureSpec) ;
    // 获取宽度的规格
    int widthSpecSize = MeasureSpec. getSize(widthMeasureSpec) ;
    // 获取高度的规格
    int heightSpecSize = MeasureSpec. getSize(heightMeasureSpec) ;

    // 如果宽高的模式都是warp_content,则使用默认的宽高值
    if (widthSpecMode == MeasureSpec. AT_MOST && heightSpecMode == MeasureSpec. AT_MOST) {
        setMeasuredDimension( mWidth mHigth) ;

    }
    // 如果只有宽度模式是warp_content,则设置宽度为默认值,高度为测量出的值
    else if (widthSpecMode == MeasureSpec. AT_MOST) {
        setMeasuredDimension( mWidth heightSpecSize) ;
    }
    // 如果只有高度模式是warp_content,则设置高度为默认值,宽度为测量出的值
    else if (heightSpecMode == MeasureSpec. AT_MOST) {
        setMeasuredDimension(widthSpecSize mHigth) ;
    }


}

从写onDraw()

  @TargetApi(Build.VERSION_CODES. LOLLIPOP)
    @Override
    protected void  onDraw(Canvas canvas) {
        super.onDraw(canvas) ;
        int paddingLeft = getPaddingLeft() ;
        int paddingRight = getPaddingRight() ;
        int paddingTop = getPaddingTop() ;
        int paddingBottom = getPaddingBottom() ;
        int width = getWidth() - paddingLeft - paddingRight ;
        int height = getHeight() - paddingBottom - paddingTop ;
        mPaint.setColor( rotateBack) ;
        //画布设置颜色
//       canvas.drawColor(Color.RED);

        //画圆(第一个参数是x点、 第二个是y点、  第三个半径  )
        radius = Math. min(width ,height)/ 2 ;
        canvas.drawCircle(paddingLeft+width/ 2 ,paddingTop+height/ 2 , radius , mPaint) ;

        //画线startX:起始端点的X坐标。startY:起始端点的Y坐标。stopX:终止端点的X坐标。stopY:终止端点的Y坐标
//        canvas.drawLine(0, 0, 100, 100,mPaint);

        //画多条直线 前两个表示的是直线起点的横纵坐标,后两个表示的是直线终点的横纵坐标。(两两为一个点)
//      float []pts={10,10,100,100,200,200,400,400};
//      canvas.drawLines(pts,mPaint);


        // 绘制圆角矩形
//        RectF re1 = new RectF(30,30, 200, 200);
//        canvas.drawRoundRect(re1, 30,30, mPaint);

        // 绘制椭圆
//        RectF re11 = new RectF(30,30,300, 200);
//        canvas.drawOval(re11, mPaint);
        //定义一个Path对象,封闭成一个三角形并根据Path对象绘制
//         Path path1 = new Path();
//         path1.moveTo(10, 340);
//         path1.lineTo(70, 340);
//         path1.lineTo(40, 290);
//         path1.close();
//         canvas.drawPath(path1, mPaint);

        // 根据Path绘制五角形
//         Path path2 = new Path();
//         path2.moveTo(26, 360);
//         path2.lineTo(54, 360);
//         path2.lineTo(70, 392);
//         path2.lineTo(40, 420);
//         path2.lineTo(10, 392);
//         path2.close();
//         canvas.drawPath(path2, mPaint);

        //c.绘制正方形
//        canvas.drawRect(170,80,230,140,mPaint);


    }


滚动
/**
 * 根据标签判断滚动
 *  @param  flag
  */
public void  rotate( boolean flag){
    if (flag== true){
        RotateAnimation ra =  new RotateAnimation( 0 360 ,
                Animation. RELATIVE_TO_SELF 0.5F ,
                Animation. RELATIVE_TO_SELF 0.5F) ;
        ra.setDuration( 1000) ;
        ra.setRepeatCount(- 1) ;
        this.startAnimation(ra) ;

    }
}


资料来源于网络希望对你有帮助,菜鸟一枚正在起飞中~~~~~~~~~



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值