完全自绘控件示例
2019-12-17 本文已影响0人
瑟闻风倾
1. 自定义控件
(1) eg1: 自定义控件 MyMessageView。实现未读消息效果,每点击自定义控件一次,未读消息数加1。
package comi.example.liy.view;
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.Rect;
import android.util.AttributeSet;
import android.view.View;
import comi.example.liy.mytestdemo.R;
/**
* Created by liy on 2019-12-17 16:42
*/
public class MyMessageView extends View implements View.OnClickListener{
private Paint paint;//画笔
private Rect rect;//用于获取文字的宽和高
private int count = 0;//消息未读数量
private String messageCount="";
public MyMessageView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);//创建画笔
rect = new Rect();
//本控件的点击事件
setOnClickListener(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画图片
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.weixin);
canvas.drawBitmap(bitmap, -20,-20, paint);
if (count != 0){
//绘制圆
paint.setColor(Color.RED);
canvas.drawCircle(115, 18, 18, paint);//画圆
//绘制文本
paint.setColor(Color.WHITE);
paint.setTextSize(20);
String message = messageCount;
paint.getTextBounds(message,0,message.length(),rect);
float messageWidth = rect.width();
float messageHeight = rect.height();
canvas.drawText(message,115 - messageWidth / 2,18 + messageHeight / 2,paint);//绘制字符串
}
}
@Override
public void onClick(View v) {
count++;
if (count >= 100){
messageCount = "99+";
}else {
messageCount = String.valueOf(count);
}
invalidate();//重绘
}
}
(2) eg2: 自定义控件 MyVerificationCodeView。实现验证码效果,每点击自定义控件一次,就重新生成随机验证码并显示出来。
package comi.example.liy.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
/**
* Created by liy on 2019-12-16 15:14
* 自定义View组件:主要在于重写View组件的onDraw(Canvase)方法
* drawRect 绘制矩形
* drawCircle 绘制圆形
* drawOval 绘制椭圆
* drawPath 绘制任意多边形
* drawLine 绘制直线
* drawPoin 绘制点
*/
public class MyVerificationCodeView extends View implements View.OnClickListener {
private Paint paint;//画笔
private Rect rect;//用于获取文字的宽和高
private String verificationCode = "0987";//验证码
public MyVerificationCodeView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);//创建画笔
rect = new Rect();
//本控件的点击事件
setOnClickListener(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制矩形
paint.setColor(Color.GRAY);//颜色
paint.setStyle(Paint.Style.FILL);//设置填满
canvas.drawRect(0,0,getWidth(),getHeight(),paint);//画矩形
//绘制字符串
paint.setColor(Color.WHITE);
paint.setTextSize(50);
String text = verificationCode;
paint.getTextBounds(text,0,text.length(),rect);//获取文本的宽和高
float textWidth = rect.width();
float textHeight = rect.height();
canvas.drawText(text,getWidth() / 2 - textWidth / 2,getHeight() / 2 + textHeight / 2,paint);//绘制字符串
}
@Override
public void onClick(View v) {
verificationCode = getRandomText();
invalidate();//重绘
}
private String getRandomText()
{
Random random = new Random();
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 4)
{
int randomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = new StringBuffer();
for (Integer i : set)
{
sb.append("" + i);
}
return sb.toString();
}
}
2. 使用自定义控件
(1) 在activity_main.xml中使用自定义控件
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<comi.example.liy.view.MyMessageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="20dp"/>
<comi.example.liy.view.MyVerificationCodeView
android:id="@+id/counter_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="20dp" />
</LinearLayout>
(2) MainActivity.java
package comi.example.liy.mytestdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
(3) 运行效果
运行-点击控件.png
3. 总结
自绘控件步骤:
- 自定义视图类:
继承自 View
并重写 View 的构造方法。- 绘图:重写
onDraw
方法中完成绘图。参考:Android利用canvas画各种图形。- 用户交互:重写
点击
或触摸
事件来实现用户交互。