欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义view

程序员文章站 2022-05-30 20:34:05
...

自定义view的分类

自绘控件和重写控件

自绘控件:类继承view,实现listener接口
重写控件:重写构造方法,重写OnDraw方法,canvas,paint,invalidate方法刷新

时钟案列

下面,我们来写一个例子以便让大家更理解
首先我们重写写一个view,将钟表画出来

package com.example.asus.weatherapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by asus on 2018/6/15.
 */

public class MyView extends View {

    private int hour=20;
    private int minute=20;
    private int seconds=10;

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

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint=new Paint();
        paint.setAntiAlias(true);


        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.timg);
        RectF rectF=new RectF(getWidth()/4,getHeight()/2-getWidth()/4,getWidth()/4*3,getHeight()/2+getWidth()/4);
        canvas.drawBitmap(bitmap,null,rectF,paint);

        paint.setColor(Color.BLACK);

        //时针
        canvas.save();
        paint.setStrokeWidth(10);
        canvas.rotate(hour*30+minute*30/60,getWidth()/2,getHeight()/2);
        canvas.drawLine(getWidth()/2,getHeight()/2,getWidth()/2,getHeight()/2-getWidth()/4+160,paint);
        canvas.restore();

        //分针
        canvas.save();
        paint.setStrokeWidth(8);
        canvas.rotate(minute*6,getWidth()/2,getHeight()/2);
        canvas.drawLine(getWidth()/2,getHeight()/2,getWidth()/2,getHeight()/2-getWidth()/4+130,paint);
        canvas.restore();

        //秒针
        canvas.save();
        paint.setStrokeWidth(6);
        canvas.rotate(6*seconds,getWidth()/2,getHeight()/2);
        canvas.drawLine(getWidth()/2,getHeight()/2,getWidth()/2,getHeight()/2-getWidth()/4+100,paint);
        canvas.restore();

        for (int i=1;i<=60;i++){
            canvas.save();
            canvas.rotate(6*i,getWidth()/2,getHeight()/2);
            if (i%5==0){
                paint.setStrokeWidth(6);
                canvas.drawLine(getWidth()/2,getHeight()/2-getWidth()/4+5,getWidth()/2,getHeight()/2-getWidth()/4+30,paint);
            }else {
                paint.setStrokeWidth(2);
                canvas.drawLine(getWidth()/2,getHeight()/2-getWidth()/4+5,getWidth()/2,getHeight()/2-getWidth()/4+20,paint);
            }
            canvas.restore();
        }

    }

    public void refresh(int h,int m,int s){
        this.hour=h;
        this.minute=m;
        this.seconds=s;
        invalidate();
    }
}

然后我们在布局中调用

<?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"
    tools:context="com.example.asus.weatherapplication.MainActivity">

    <com.example.asus.weatherapplication.MyView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/myview"/>

</LinearLayout>

画出来的结果如图
自定义view
然后我们要让它动起来

package com.example.asus.weatherapplication;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity {

    private MyView myView;
    private int hour;
    private int minute;
    private int seconds;

    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            myView.refresh(msg.what,msg.arg1,msg.arg2);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myView= (MyView) findViewById(R.id.myview);

        Calendar calendar=Calendar.getInstance();
        hour=calendar.get(Calendar.HOUR_OF_DAY);
        minute=calendar.get(Calendar.MINUTE);
        seconds=calendar.get(Calendar.SECOND);

        myView.invalidate();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    seconds++;
                    if (seconds==60){
                        seconds=0;
                        minute++;
                    }
                    Message message=handler.obtainMessage();
                    message.what=hour;
                    message.arg1=minute;
                    message.arg2=seconds;
                    handler.sendMessage(message);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

这样就可以做到时钟转动,结果截图附上一张
自定义view