package com.netease.nim.uikit.common.ui.drop;
import android.content.Context;
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.ScrollView;
/**
* 未读数红点View(自绘红色的圆和数字)
* 触摸之产生DOWN/MOVE/UP事件(不允许父容器处理TouchEvent),回调给浮在上层的DropCover进行拖拽过程绘制。
* View启动过程:Constructors -> onAttachedToWindow -> onMeasure() -> onSizeChanged() -> onLayout() -> onDraw()
* <p>
* Created by huangjun on 2016/9/13.
*/
public class DropFake extends View {
/**
* 未读数红点检测触摸事件产生DOWN/MOVE/UP
*/
public interface ITouchListener {
void onDown();
void onMove(float curX, float curY);
void onUp();
}
private int radius; // 圆形半径
private float circleX; // 圆心x坐标
private float circleY; // 圆心y坐标
private String text; // 要显示的文本(数字)
private boolean firstInit = true; // params init once
private ITouchListener touchListener;
public DropFake(Context context, AttributeSet attrs) {
super(context, attrs);
DropManager.getInstance().initPaint();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (firstInit) {
firstInit = false;
radius = DropManager.CIRCLE_RADIUS; // 或者view.getWidth()/2
circleX = w / 2;
circleY = h / 2;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// circle
canvas.drawCircle(circleX, circleY, radius, DropManager.getInstance().getCirclePaint());
// text
if (!TextUtils.isEmpty(text)) {
canvas.drawText(text, circleX, circleY + DropManager.getInstance().getTextYOffset(),
DropManager.getInstance().getTextPaint());
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 如果未初始化 DropManager,则默认任何事件都不处理
if (!DropManager.getInstance().isEnable()) {
return super.onTouchEvent(event);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (DropManager.getInstance().isTouchable()) {
if (touchListener != null) {
DropManager.getInstance().setTouchable(false);
// 不允许父控件处理TouchEvent,当父控件为ListView这种本身可滑动的控件时必须要控制
disallowInterceptTouchEvent(true);
touchListener.onDown();
}
return true; // eat
}
return false;
case MotionEvent.ACTION_MOVE:
if (touchListener != null) {
// getRaw:获取手指当前所处的相对整个屏幕的坐标
touchListener.onMove(event.getRawX(), event.getRawY());
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (touchListener != null) {
// 将控制权还给父控件
disallowInterceptTouchEvent(false);
touchListener.onUp();
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
public void setText(String text) {
this.text = text;
invalidate();
}
public String getText() {
return text;
}
public void setTouchListener(ITouchListener listener) {
touchListener = listener;
}
private void disallowInterceptTouchEvent(boolean disable) {
ViewGroup parent = (ViewGroup) getParent();
parent.requestDisallowInterceptTouchEvent(disable);
while (true) {
if (parent == null) {
return;
}
if (parent instanceof RecyclerView || parent instanceof ListView || parent instanceof GridView ||
parent instanceof ScrollView) {
parent.requestDisallowInterceptTouchEvent(disable);
return;
}
ViewParent vp = parent.getParent();
if (vp instanceof ViewGroup) {
parent = (ViewGroup) parent.getParent();
} else {
return; // DecorView
}
}
}
}