自定义View
程序员文章站
2022-05-30 20:19:11
...
1.自定义View分类
2.时钟案例
3.圆形ImageView
View分类
ImageView
- ImageButton
- QuickContactBadge
- AppCompatImageView
TextView - EditText
- Button
- RadioButton
- ToggleButton
- CheckBox
- Switch
- TextClock
- Chronometer
- RowHeaderView
ViewGroup
- LinearLayout
- RelativeLayout
- ViewPager
- ListView
- AbsoulteLayout
- FrameLayout
- GridLayout
TextureView
ViewStub
Tabltem
Space
时钟案例
onDraw方法
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.watch);
RectF rectF = new RectF(getWidth() / 4+20, getHeight() / 2 - getWidth() / 4+25, getWidth() / 4 * 3-25, getHeight() /2 + getHeight() / 8);
canvas.drawBitmap(bitmap, null, rectF, paint);
表盘背景
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.watch);
RectF rectF = new RectF(getWidth() / 4+20, getHeight() / 2 - getWidth() / 4+25, getWidth() / 4 * 3-25, getHeight() /2 + getHeight() / 8);
canvas.drawBitmap(bitmap, null, rectF, paint);
时针
canvas.save();
canvas.rotate(hours*30+minute*30/60,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getHeight() / 8 + 55, paint);
canvas.restore();
分针
canvas.save();
canvas.rotate(minute*6,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2 + 12, getHeight() / 2 - getHeight() / 8 + 40, paint);
canvas.restore();
秒针
canvas.save();
canvas.rotate(second*6,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(1);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2 + 15, getHeight() / 2 - getHeight() / 8 + 20, paint);
canvas.restore();
完整代码
package com.example.a17708.pratice;
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;
public class MyView extends View {
private int hours=20;
private int minute=20;
private int second=0;
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.setColor(Color.RED);
paint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.watch);
RectF rectF = new RectF(getWidth() / 4+20, getHeight() / 2 - getWidth() / 4+25, getWidth() / 4 * 3-25, getHeight() /2 + getHeight() / 8);
canvas.drawBitmap(bitmap, null, rectF, paint);
//画直线(时针)
canvas.save();
canvas.rotate(hours*30+minute*30/60,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getHeight() / 8 + 55, paint);
canvas.restore();
//画直线(分针)
canvas.save();
canvas.rotate(minute*6,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2 + 12, getHeight() / 2 - getHeight() / 8 + 40, paint);
canvas.restore();
//画直线(秒针)
canvas.save();
canvas.rotate(second*6,getWidth()/2,getHeight()/2);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(1);
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2 + 15, getHeight() / 2 - getHeight() / 8 + 20, paint);
canvas.restore();
for(int i=0;i<=60;i++){
canvas.save();
canvas.rotate(6*i,getWidth()/2,getHeight()/2);
paint.setStrokeWidth(2);
if(i%5==0){
paint.setStrokeWidth(8);
canvas.drawLine(getWidth() / 2, getHeight() / 2 - getHeight() / 8 + 20, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 35, paint);
} else {
paint.setStrokeWidth(4);
canvas.drawLine(getWidth() / 2, getHeight() / 2 - getHeight() / 8 + 20, getWidth() / 2, getHeight() / 2 - getWidth() / 4+40, paint);
}
canvas.restore();
}
}
public void refresh(int h, int m, int s) {
this.hours = h;
this.minute = m;
this.second = s;
invalidate();//再次触发onDraw方法
}
}
package com.example.a17708.pratice;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.Calendar;
public class MyViewActivity extends AppCompatActivity {
private MyView myView;
private int hours;
private int minute;
private int second;
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_my_view);
myView = findViewById(R.id.my_view);
Calendar calendar = Calendar.getInstance();
hours = calendar.get(Calendar.HOUR_OF_DAY);
minute = calendar.get(Calendar.MINUTE);
second = calendar.get(Calendar.SECOND);
myView.refresh(hours, minute, second);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
second++;
if (second == 60) {
second = 0;
minute++;
}
try {
Message message = handler.obtainMessage();
message.what = hours;
message.arg1 = minute;
message.arg2 = second;
handler.sendMessage(message);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
圆形ImageView
package com.example.a17708.pratice;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
@SuppressLint("AppCompatCustomView")
public class MyImageView extends ImageView {
private Paint mPaint; //画笔
private int mRadius; //圆形图片的半径
private float mScale; //图片的缩放比例
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = size / 2;
setMeasuredDimension(size, size);
}
@Override
protected void onDraw(Canvas canvas) {
mPaint = new Paint();
Bitmap bitmap = drawableToBitmap(getDrawable());
//初始化BitmapShader,传入bitmap对象
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//计算缩放比例
mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());
Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
bitmapShader.setLocalMatrix(matrix);
mPaint.setShader(bitmapShader);
//画圆形,指定好中心点坐标、半径、画笔
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
}
//写一个drawble转BitMap的方法
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
}