Android技术知识Android开发Android

完全自绘控件示例

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画各种图形
  • 用户交互:重写点击触摸事件来实现用户交互。

拓展Android自定义View的实现

上一篇下一篇

猜你喜欢

热点阅读