自定义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();
}
}
这样就可以做到时钟转动,结果截图附上一张