Android自定义View实现QQ气泡效果

本文详细介绍了如何在Android中自定义View实现QQ气泡效果,包括气泡的绘制、属性动画、贝塞尔曲线绘制、触摸事件处理,以及粘性拖拽和爆炸效果。通过对View的构造、属性定义和读取、初始化、状态定义等步骤的解析,展示了完整的实现过程。
摘要由CSDN通过智能技术生成

QQ气泡效果分析

QQ气泡 = 红色圆 + 消息数字 + 拖拽粘性效果 + 回弹效果 + 跟随移动 + 爆炸效果。
不得不说在这么个小小的UI小球上实现了这么多的效果,QQ是真的很有心呐~

根据我们上边拆分出来的公式,我们分别看看每一个效果需要如何去实现:
红色圆:canvas.drawCircle
消息数字:canvas.drawText
拖拽粘性效果:canvas.drawPath、 (两条二阶)贝塞尔曲线
回弹效果:属性动画
跟随移动:OnTouchEvent处理MotionEvent.ACTION_MOVE事件
爆炸效果:属性动画

首先我们来看一下最终的效果:
QQ气泡效果

View自定义属性

为了提高自定义View的灵活性,我们需要提供几种自定义属性给外部来设置,有如下属性:
气泡半径:bubble_radius
气泡颜色:bubble_color
气泡消息数字:bubble_text
气泡消息数字字体大小:bubble_textSize
气泡消息数字颜色:bubble_textColor

属性定义

在res -> values下添加如下attrs.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="DragBubbleView">
        <attr name="bubble_radius" format="dimension"/>
        <attr name="bubble_color" format="color"/>
        <attr name="bubble_text" format="string"/>
        <attr name="bubble_textSize" format="dimension"/>
        <attr name="bubble_textColor" format="color"/>
    </declare-styleable>
</resources>

属性读取

我们在View构造函数中读取自定义属性

DragBubbleView.java

public class DragBubbleView extends View {
   

	/**
     * 气泡半径
     */
    private float mBubbleRadius; 
    /**
     * 气泡颜色
     */
    private int mBubbleColor;   
    /**
     * 气泡消息文字
     */
    private String mTextStr;    
    /**
     * 气泡消息文字大小
     */
    private float mTextSize;
	/**
     * 气泡文字颜色
     */
    private int mTextColor;
    
	public DragBubbleView(Context context) {
   
        this(context, null);
    }

    public DragBubbleView(Context context, AttributeSet attrs) {
   
        this(context, attrs, 0);
    }

	public DragBubbleView(Context context, AttributeSet attrs, int defStyleAttr) {
   
		super(context, attrs, defStyleAttr);
		// 读取属性值
		readAttributes(context, attrs, defStyleAttr);
		// 初始化
        init();
	}

	private void readAttributes(Context context, AttributeSet attrs, int defStyleAttr){
   
        // 获取自定义属性数组
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DragBubbleView, defStyleAttr, 0);
        // 获取气泡半径
        mBubbleRadius = array.getDimension(R.styleable.DragBubbleView_bubble_radius, mBubbleRadius);
        // 气泡颜色,默认红色
        mBubbleColor = array.getColor(R.styleable.DragBubbleView_bubble_color, Color.RED);
        // 消息数字
        mTextStr = array.getString(R.styleable.DragBubbleView_bubble_text);
        // 字体大小
        mTextSize = array.getDimension(R.styleable.DragBubbleView_bubble_textSize, mTextSize);
        // 消息数字颜色
        mTextColor = array.getColor(R.styleable.DragBubbleView_bubble_textColor, Color.WHITE);
        // 回收属性数组
        array.recycle();
    }
	
	private void init() {
   
		//...
	}
}

初始化

接下来需要根据自定义属性值初始化数据,这里需要注意的是,我们是需要绘制两个气泡来完成我们想要的效果:一个是固定在初始位置,在粘性拖拽时大小随粘性距离的增大而减小;另一个是大小不变,位置始终跟随点击位置移动的圆。

初始化两个圆的大小及画笔

DragBubbleView.java

public class DragBubbleView extends View {
   

	//...
	
	/**
     * 不动气泡的半径
     */
    private float mBubFixedRadius;
    /**
     * 可动气泡的半径
     */
    private float mBubMovableRadius;
    /**
     * 气泡相连状态最大圆心距离
     */
    private float mMaxDist;
    /**
     * 手指触摸偏移量
     */
    private static float MOVE_OFFSET;
    /**
     * 气泡的画笔
     */
    private Paint mBubblePaint;
    /**
     * 贝塞尔曲线path
     */
    private Path mBezierPath;
    /**
     * 绘制文本的画笔
     */
    private Paint mTextPaint;
    /**
     * 文本绘制区域
     */
    private Rect mTextRect;
     /**
     * 爆炸图片的画笔
     */
    private Paint mBurstPaint;
    /**
     * 爆炸绘制区域
     */
    private Rect mBurstRect;
    /**
     * 气泡爆炸的bitmap数组
     */
    private Bitmap[] mBurstBitmapsArray;
    /**
     * 气泡爆炸的图片id数组
     */
    private int[] mBurstDrawablesArray = {
   
            R.mipmap.burst_1,
            R.mipmap.burst_2,
            R.mipmap.burst_3,
            R.mipmap.burst_4,
            R.mipmap.burst_5
    };
    
	private void init() {
   
		// 两个圆初始半径一致
        mBubFixedRadius = mBubbleRadius;
        mBubMovableRadius = mBubFixedRadius;
        
        // 设置粘性拖拽最大距离
        mMaxDist = 8 * mBubbleRadius;
        // 该值是为了增大气泡对触摸事件的识别范围
        MOVE_OFFSET = mMaxDist / 4;
        
        // 初始化气泡画笔
        // 设置抗锯齿
        mBubblePaint = new Paint(Pain
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值