当前位置:首页 » 《资源分享》 » 正文

Android——自定义View_FranzLiszt的博客

15 人参与  2021年10月01日 13:03  分类 : 《资源分享》  评论

点击全文阅读


自定义View

  • 画一个实心圆
    • 效果图
    • 创建attrs.xml文件
    • 初始化样式属性
    • 支持Padding属性
    • 支持wrap_content属性
    • 布局文件中的应用
  • 画一个带外圆环的圆
    • 效果图
    • 创建attrs.xml文件
    • 初始化样式属性
    • 内圆与外圆环的绘制
    • 布局文件中的应用
  • 画一个外圆环可根据数值变动的圆
    • 效果图
    • 创建attrs.xml文件
    • 初始化样式属性
    • 绘制View
    • 提供方法修改样式
    • 布局文件中的应用

画一个实心圆

效果图

在这里插入图片描述

创建attrs.xml文件

在value文件夹下创建一个名为attrs.xml文件,为圆设置一个背景颜色的属性,代码如下:

<declare-styleable name="CircleView_Solid">
        <attr name="CircleColor_Solid" format="color"/>
</declare-styleable>

初始化样式属性

为圆设置颜色属性,并设置抗锯齿

private void InitAttrs(Context context , AttributeSet attrs){
        TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Solid,0,0 );
        mCircleBGColor = array.getColor( R.styleable.CircleView_Solid_CircleColor_Solid,0xFFFFFFFF );
    }
    
    private void InitVar(){
        mCirclePaint = new Paint(  );
        mCirclePaint.setAntiAlias( true );
        mCirclePaint.setColor( mCircleBGColor );
    }

支持Padding属性

由于直接继承view,不再onDraw()中进行处理,是无法直接使用Padding属性,代码如下:

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)) / 2 +PaddingLeft;
        int Height = (getHeight() -(PaddingTop+PaddingBottom))/2+PaddingTop;
        int Radius = Math.min( Width,Height )/2;
        canvas.drawCircle( Width,Height,Radius,mCirclePaint );
    }

支持wrap_content属性

若不在onMeasure()对wrap_content进行处理,效果很可能达不到预期效果,如果控件使用wrap_content属性,那么他的Measure specification mode就为At_Most,而它的宽高就等于specSize,这种情况下specSize是就相当于父容器当前剩余的大小,代码如下:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure( widthMeasureSpec, heightMeasureSpec );
        int Width = 500;
        int Height = 500;
        int WidthMode = MeasureSpec.getMode( widthMeasureSpec );
        int WidthSize = MeasureSpec.getSize( widthMeasureSpec );
        int HeightMode = MeasureSpec.getMode( heightMeasureSpec );
        int HeightSize = MeasureSpec.getSize( heightMeasureSpec );
        if (WidthMode == MeasureSpec.AT_MOST && HeightMode == MeasureSpec.AT_MOST){
            setMeasuredDimension( Math.min( Width,HeightSize ),Math.min( Height ,HeightSize) );
        } else if (WidthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension( Math.min( Width,HeightSize ),HeightSize );
        }else if (HeightMode == MeasureSpec.AT_MOST){
            setMeasuredDimension( WidthSize,Math.min( Height ,HeightSize) );
        }
    }

布局文件中的应用

<com.franzliszt.customcircleview.CircleView_Solid
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:CircleColor_Solid="@color/colorRed"
    android:padding="10dp"/>

画一个带外圆环的圆

效果图

在这里插入图片描述

创建attrs.xml文件

 <declare-styleable name="CircleView_Text">
<!--        内圆颜色-->
        <attr name="CircleColor" format="color"/>
<!--        外圆环颜色-->
        <attr name="RingColor" format="color"/>
<!--        圆的半径-->
        <attr name="Radius" format="dimension"/>
<!--        外圆环的宽度-->
        <attr name="StrokeWidth" format="dimension"/>
    </declare-styleable>

初始化样式属性

 private void InitAttrs(Context context , AttributeSet attrs){
        TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Text,0,0 );
        CircleColor = array.getColor( R.styleable.CircleView_Text_CircleColor,0xFFFFFFFF );
        RingColor = array.getColor( R.styleable.CircleView_Text_RingColor,0xFFFFFFFF );
        mRadius = array.getDimension( R.styleable.CircleView_Text_Radius,80 );
        mStrokeWidth = array.getDimension( R.styleable.CircleView_Text_StrokeWidth,10 );

        mRingRadius = mRadius + mStrokeWidth / 2;
    }
    
    private void InitVar(){
        //内圆
        //设置颜色
        CirclePaint.setColor( CircleColor );
        //设置填充方式
        CirclePaint.setStyle( Paint.Style.FILL );
        //设置抗锯齿
        CirclePaint.setAntiAlias( true );
        //外圆环
        RingPaint.setColor( RingColor );
        RingPaint.setStyle( Paint.Style.STROKE );
        RingPaint.setAntiAlias( true );
        RingPaint.setStrokeWidth( mStrokeWidth );
    }

内圆与外圆环的绘制

protected void onDraw(Canvas canvas) {
        super.onDraw( canvas );
        mCenterX = getWidth()/2;
        mCenterY = getHeight()/2;
        canvas.drawCircle( mCenterX,mCenterY,mRadius,CirclePaint );

        RectF rect = new RectF(  );
        rect.left = mCenterX - mRingRadius;
        rect.right = 2 * mRingRadius + (mCenterX - mRingRadius);
        rect.top = mCenterY - mRingRadius;
        rect.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
       canvas.drawArc( rect,0,360,false,RingPaint );
    }

布局文件中的应用

 <com.franzliszt.customcircleview.CircleView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:Radius="40dp"
        app:StrokeWidth="10dp"
        app:CircleColor="@color/colorBlack"
        app:RingColor="@color/colorRed"/>

画一个外圆环可根据数值变动的圆

效果图

在这里插入图片描述

创建attrs.xml文件

<declare-styleable name="CircleView_Progress">
        <!--        内圆颜色-->
        <attr name="CircleProgressColor" format="color"/>
        <!--        外圆环颜色-->
        <attr name="RingProgressColor" format="color"/>
        <!--        外圆环覆盖部分颜色-->
        <attr name="RingBgProgressColor" format="color"/>
        <!--        文字颜色-->
        <attr name="TextProgressColor" format="color"/>
        <!--        圆的半径-->
        <attr name="RadiusProgress" format="dimension"/>
        <!--        外圆环的宽度-->
        <attr name="StrokeWidthProgress" format="dimension"/>
        <attr name="CurrentProgress" format="float"/>
    </declare-styleable>

初始化样式属性

private void InitAttrs(Context context , AttributeSet attrs){
        TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Progress,0,0 );
        CircleColor = array.getColor( R.styleable.CircleView_Progress_CircleProgressColor,0xFFFFFFFF );
        RingColor = array.getColor( R.styleable.CircleView_Progress_RingProgressColor,0xFFFFFFFF );
        RingBgColor = array.getColor( R.styleable.CircleView_Progress_RingBgProgressColor,0xFFFFFFFF );
        TextColor = array.getColor( R.styleable.CircleView_Progress_TextProgressColor, 0xFFFFFFFF);
        mRadius = array.getDimension( R.styleable.CircleView_Progress_RadiusProgress,80 );
        mStrokeWidth = array.getDimension( R.styleable.CircleView_Progress_StrokeWidthProgress,10 );
        mCurrentProgress = array.getFloat( R.styleable.CircleView_Progress_CurrentProgress,10 );
        mRingRadius = mRadius + mStrokeWidth / 2;
    }
    private void InitVar(){
        //内圆
        //设置颜色
        CirclePaint.setColor( CircleColor );
        //设置填充方式
        CirclePaint.setStyle( Paint.Style.FILL );
        //设置抗锯齿
        CirclePaint.setAntiAlias( true );
        //外圆环
        RingPaint.setColor( RingColor );
        RingPaint.setStyle( Paint.Style.STROKE );
        RingPaint.setAntiAlias( true );
        RingPaint.setStrokeWidth( mStrokeWidth );

        //外圆环覆盖部分
        RingBgPaint.setColor( RingBgColor );
        RingBgPaint.setStyle( Paint.Style.STROKE );
        RingBgPaint.setAntiAlias( true );
        RingBgPaint.setStrokeWidth( mStrokeWidth );

        //中间文字
        TextPaint.setStyle( Paint.Style.FILL );
        TextPaint.setAntiAlias( true );
        TextPaint.setColor( TextColor );
        TextPaint.setTextSize( mRadius/2 );
        //文字的高度
        Paint.FontMetrics fontMetrics = TextPaint.getFontMetrics();
        mTextHeight = (int)Math.ceil( fontMetrics.descent - fontMetrics.ascent );
    }

绘制View

 protected void onDraw(Canvas canvas) {
        super.onDraw( canvas );
        mCenterX = getWidth()/2;
        mCenterY = getHeight()/2;
        canvas.drawCircle( mCenterX,mCenterY,mRadius,CirclePaint );

        RectF rect = new RectF(  );
        rect.left = mCenterX - mRingRadius;
        rect.right = 2 * mRingRadius + (mCenterX - mRingRadius);
        rect.top = mCenterY - mRingRadius;
        rect.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
        canvas.drawArc( rect,0,360,false,RingPaint );
        //当mCurrentProgress大于0时,外圆环覆盖部分显示
        if (mCurrentProgress > 0){
            RectF rect_progress = new RectF(  );
            rect_progress.left = mCenterX - mRingRadius;
            rect_progress.right = 2 * mRingRadius + (mCenterX - mRingRadius);
            rect_progress.top = mCenterY - mRingRadius;
            rect_progress.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
            //例如外圆环数值为35,即35/100*360,获得外圆环覆盖部分
            canvas.drawArc( rect,-90,(float) (mCurrentProgress / mTotalProgress)*360,false,RingBgPaint );
        }
        //文字部分
        String text = mCurrentProgress+"%";
        //文字部分的宽度
        mTextWidth = TextPaint.measureText( text,0,text.length() );
        canvas.drawText( text,mCenterX - mTextWidth / 2, mCenterY + mTextHeight / 4,TextPaint );
    }

提供方法修改样式

   public void setProgress(double progress){
        mCurrentProgress = progress;
        postInvalidate();
    }
    public void setRingBgColor(int Color){
        RingBgColor = Color;
        postInvalidate();
    }
    public void setTextColor(int Color){
        TextColor = Color;
        postInvalidate();
    }

布局文件中的应用

 <com.franzliszt.customcircleview.CircleView_ProgressBar
        android:id="@+id/Progress"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="50dp"
        app:Radius="100dp"
        app:StrokeWidth="10dp"
        app:CircleColor="@color/colorWhite"
        app:RingColor="@color/colorGrey"
        app:RingProgressColor="@color/colorRed"
        app:TextProgressColor="@color/colorPrimary"
        app:CurrentProgress="59"
        />

点击全文阅读


本文链接:http://zhangshiyu.com/post/29115.html

圆环  属性  文件  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1