自定义view

自定义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>

画出来的结果如图
这里写图片描述
然后我们要让它动起来

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();
    }
}

这样就可以做到时钟转动,结果截图附上一张
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值