自定义View应用

作者: 小慧sir | 来源:发表于2019-08-08 18:44 被阅读4次

1、values/attrs.xml

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

 <declare-styleable name="CustomView">

     <!--使用系统的宽高属性-->
     <attr name="android:layout_width"/>
     <attr name="android:layout_height"/>

     <!--自定义的-->
     <!--外环颜色-->
     <attr name="ringColor" format="color"/>
     <!--外环宽度-->
     <attr name="ringWidth" format="dimension"/>
     <!--内圆颜色-->
     <attr name="circleColor" format="color"/>
     <!--进度文本大小颜色-->
     <attr name="android:textSize"/>
     <attr name="android:textColor"/>
     <!--进度 扇形的扫过角度-->
     <attr name="sweepAngle" format="integer"/>
     <attr name="startAngle" format="integer"/>
 </declare-styleable>
</resources>

2、创建类CustomView(extends View)--自定义View

public class CustomView extends View {

    private float mHeight;
    private float mWidth;
    private int mRingColor;
    private float mRingWidth;
    private int mCircleColor;
    private float mTextSize;
    private int mTextColor;
    private int mStartAngle;
    private int mSweepAngle;
    private Paint mCirclePaint;
    private Paint mTextPaint;
    private float mDy;
    private String mProgress;
    private Paint mSweepPaint;
    private float mRadius;
    private float mCenterXY;
    private RectF mRectF;

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
//        ,R.styleable.MyProgressBar
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
        if (ta != null) {

            //获取属性
            mHeight = ta.getDimension(R.styleable.CustomView_android_layout_height, 200);
            mWidth = ta.getDimension(R.styleable.CustomView_android_layout_width, 200);
            mRingColor = ta.getColor(R.styleable.CustomView_ringColor, 0);
            mRingWidth = ta.getDimension(R.styleable.CustomView_ringWidth, 10);
            mCircleColor = ta.getColor(R.styleable.CustomView_circleColor, 0);
            mTextSize = ta.getDimension(R.styleable.CustomView_android_textSize, 16);
            mTextColor = ta.getColor(R.styleable.CustomView_android_textColor, 0);
            mStartAngle = ta.getInteger(R.styleable.CustomView_startAngle, -90);
            mSweepAngle = ta.getInteger(R.styleable.CustomView_sweepAngle, 0);

            //释放资源
            ta.recycle();
        }
//          mCirclePaint = new Paint();
//        mCirclePaint.setColor(mCircleColor);
//        mCirclePaint.setAntiAlias(true);
        mCirclePaint = new Paint();
        mCirclePaint.setColor(mCircleColor);
        mCirclePaint.setAntiAlias(true);

        mTextPaint = new Paint();
        mTextPaint.setColor(mTextColor);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);

        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float v1 = fontMetrics.descent - fontMetrics.ascent;
        mDy = v1 / 2 - fontMetrics.descent;

        float v = mSweepAngle * 1.0f / 360 * 100;
        mProgress = (int) v + " %";

        mSweepPaint = new Paint();
        mSweepPaint.setAntiAlias(true);
        mSweepPaint.setColor(mRingColor);
        mSweepPaint.setStrokeWidth(mRingWidth);
        mSweepPaint.setStyle(Paint.Style.STROKE);

    }

    /*
     * TODO
     * 测试
     * */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int max = (int) Math.max(mWidth, mHeight);
        setMeasuredDimension(max, max);
        //setMeasuredDimension((int) mWidth,(int)mHeight);
        mRadius = max * 1.0f / 4;
        mCenterXY = max * 1.0f / 2;

        float v = max * 0.9f;
        mRectF = new RectF(max * 0.1f, max * 0.1f, v, v);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //1.话里面的圆
        canvas.drawCircle(mCenterXY, mCenterXY, mRadius, mCirclePaint);
        //2.画文字
        canvas.drawText(mProgress, mCenterXY, mCenterXY + mDy, mTextPaint);

        //3.画进度,扇形
        canvas.drawArc(mRectF, mStartAngle, mSweepAngle, false, mSweepPaint);
    }

    /**
     * @param progress 0-100
     */
    public void setmProgress(int progress) {
        mSweepAngle = (int) (progress * 3.6f);
        mProgress = progress + " %";
//        invalidate();//只能在ui线程中调用
        postInvalidate();// 可以在非ui线程中调用

    }
}

3、activity_main.xml 中引用 CustomView

<?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:orientation="vertical"
    android:gravity="center"
    android:background="#0ff"
    android:layout_margin="50dp"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.a86066.appviewdemo.CustomView
        android:layout_gravity="center"
        android:id="@+id/myProgressBar"
        android:background="#55000000"
        app:circleColor="@color/colorAccent"
        app:ringColor="#ffd500"
        app:ringWidth="20dp"
        app:sweepAngle="89"
        app:startAngle="-90"
        android:text="@string/app_name"
        android:textSize="20sp"
        android:textColor="#ffffff"
        android:layout_width="300dp"
        android:layout_height="300dp" />
        <!--android:id="@+id/btn"-->
    <Button
        android:onClick="btn"
        android:text="开始"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

4、MainActivity 中

public class MainActivity extends AppCompatActivity {

    /**
     * AppViewdemo
     */
    private CustomView mMyProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView() {
        mMyProgressBar = (CustomView) findViewById(R.id.myProgressBar);
    }
    /*TODO
    Button
    * */
    public void btn(View view) {
        start();
    }

    private void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 100; i++) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    mMyProgressBar.setmProgress(i);
                }
            }
        }).start();
    }

效果图

...

相关文章

网友评论

    本文标题:自定义View应用

    本文链接:https://www.haomeiwen.com/subject/parfjctx.html