自定义view,安卓自带的控件的功能效果不能满足需求
自定义view的分类:
自绘控件和重写控件
自绘控件:类继承view,实现listener接口,重写构造方法,重写OnDraw方法,canvas,paint,invalidate方法刷新,在activity的布局中引用
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by xiaozhen on 2018/6/15.
*/
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, 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.setColor(Color.GRAY);
paint.setAntiAlias(true);//设置抗锯齿
canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/4,paint);
}
}
在activity布局文件中调用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_my_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.xiaozhen.webapplication.MyViewActivity">
<com.example.xiaozhen.webapplication.MyView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2.时钟案例思路
1.得到当前的时分秒Calander对象的使用
2.秒钟一直在不停的走,所以这里要用到线程,又因为子线程不能做耗时操作,所以也要用到handler
将时分秒用画笔画出来,然后绘制时钟的刻度,这里要用到循环因为有60个刻度,下面是在MyviewJava文件中,画出时分秒,并且写一个refrash的方法
package com.example.xiaozhen.webapplication;
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.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by xiaozhen on 2018/6/15.
*/
public class MyView extends View {
private int Hour=80;
private int minute=60;
private int second=10;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, 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.setColor(Color.GRAY);
paint.setAntiAlias(true);//设置抗锯齿
// canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/4,paint);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.clock);
//有float类型的
RectF rectF = new RectF(getWidth() / 4, getHeight() / 2 - getWidth() / 4, getWidth() / 4 * 3, getHeight() / 2 + getWidth() / 4);
canvas.drawBitmap(bitmap, null, rectF, paint);
//时
canvas.save(); //位置不能换
canvas.rotate(Hour * 30 + minute * 30 / 60, getWidth() / 2, getHeight() / 2);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 170, paint);
canvas.restore();
//分
canvas.save();
canvas.rotate(6 * minute, getWidth() / 2, getHeight() / 2);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 150, paint);
canvas.restore();
//秒
canvas.save();
canvas.rotate(6 * second, 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+20, paint);
} else {
paint.setStrokeWidth(2);
canvas.drawLine(getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 5, getWidth() / 2, getHeight() / 2 - getWidth() / 4+10, paint);
}
canvas.restore();
}
//paint.setTextSize(30);
}
public void refrash(int h, int m, int s) {
this.Hour = h;
this.minute = m;
this.second = s;
invalidate();
}
}
接着在activity中用Calendar 得到当前时间
package com.example.xiaozhen.webapplication;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.util.Calendar;
public class MyViewActivity extends AppCompatActivity {
private MyView myView;
private int hour;
private int minute;
private int second;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//
myView.refrash(msg.what,msg.arg1,msg.arg2);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_view);
myView= (MyView) findViewById(R.id.myView);
//得到当前时间
Calendar calendar=Calendar.getInstance();
hour=calendar.get(Calendar.HOUR_OF_DAY);
minute=calendar.get(Calendar.MINUTE);
second=calendar.get(Calendar.SECOND);
myView.invalidate();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
second++;
if (second == 60) {
second = 0;
minute++;
}
Message message = handler.obtainMessage();
message.what = hour;
message.arg1 = minute;
message.arg2 = second;
handler.sendMessage(message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}