1.自定义View分类
视图View主要分为两类:
单一视图 即一个View,如TextView 不包含子View
视图组 即多个View组成的ViewGroup,如LinearLayout 包含子View
View类是Android中各种组件的基类,如View是ViewGroup基类
View表现为显示在屏幕上的各种视图
Android中的UI组件都由View、ViewGroup组成。
View的构造函数:共有4个,具体如下:
自定义View必须重写至少一个构造函数:
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);
}
上述就是对自定义View的一些简单的讲解
2.时钟案例
思路:先通过重写onDraw方法用paint和canvas来画上一个圆,并且用划线的方式来进行画表盘,再用划线的方式来画出时钟的时针分针秒针,然后用calendar方法来获取到当前时间,最后创建一个子线程让它的指针动起来。当然,这是一种方法,还有一种更加简单的方法,就是将一张时钟的图放在画布上,直接让时针分针秒针动起来就行了,具体代码演示如下:
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setAntiAlias(true);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 4, paint);
}
这一部分我们不难看出,这里就是用到的自己画的方法,用paint来确定颜色和设置抗锯齿,再用到canvas将圆给画出来,四个参数,前两个是圆心的位置,第三个是半径的大小,最后一个是paint对象;
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.timg);
RectF rectF=new RectF(0,getHeight()/2-getWidth()/2,getWidth(),getHeight()/2+getWidth()/2);
canvas.drawBitmap(bitmap,null,rectF,paint);
而这个呢则是直接将图片放到画布上用,用到了RecF这个类来,将Bitmap通过BitmapFactory.decodeResource放进去;
canvas.save();
canvas.rotate(minute * 6, getWidth() / 2, getHeight() / 2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 50, paint);
canvas.restore();
这段则是画指针的方法,三个针都是这样的方法,只是粗细长度自己去调整就行了。其中rotate方法中有三个参数,一个是旋转的角度,而后面两个则是围绕哪个点旋转这个点的坐标,这样我们就能很容易看懂了,而长度的话则是通过改动drawLine中的参数,这个中的参数前面四个是起始点和终止点的坐标
注意:在这个里面的坐标和我们数学所学到的是不同的,它是越往下和越往右越大!
public void refresh(int h, int m, int s) {
this.hour = h;
this.minute = m;
this.seconds = s;
invalidate();//会再次调用onDraw方法
}
再然后就是这个refresh方法,他能够起到的作用是将Activity中的参数得到,并且再次调用onDraw方法来得到效果
public class CircleActivity 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(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circle);
myView=findViewById(R.id.myview);
Calendar calendar=Calendar.getInstance();
hour=calendar.get(Calendar.HOUR_OF_DAY);
Toast.makeText(this, hour+"", Toast.LENGTH_SHORT).show();
minute=calendar.get(Calendar.MINUTE);
seconds=calendar.get(Calendar.SECOND);
// myView.refresh(hour,minute,seconds);
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();
}
}
这一段代码我们就不难看出是将其放在一个子线程中让指针转动,但是子线程又不能进行更新UI操作,所以再通过Handler来联系起来
3.圆形ImageView
如需了解请点击此处
https://www.jianshu.com/p/6beca370fd50