实例介绍
核心代码:
public class RevealLayout extends LinearLayout implements Runnable{
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float mCenterX,mCenterY;
private int[] mLocation = new int[2];
private int INVALIDATE_DURATION = 40;
private int mTargetHeight,mTargetWidth;
private int mRevealRadius = 0,mRevealRadiusGap,mMaxRadius;
private int mMinBetweenWidthAndHeight,mMaxBetweenWidthAndHeight;
private boolean mIsPressed;
private boolean mShouldDoAnimation;
private View mTargetView;
private DispatchUpTouchEventRunnable mDispatchUpTouchEventRunnable = new DispatchUpTouchEventRunnable();
public RevealLayout(Context context) {
super(context);
init();
}
public RevealLayout(Context context, AttributeSet attrs){
super(context,attrs);
init();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RevealLayout(Context context, AttributeSet attrs, int defStyleAttr){
super(context,attrs,defStyleAttr);
init();
}
public void init(){
setWillNotDraw(false);
mPaint.setColor(getResources().getColor(R.color.reveal_color));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
this.getLocationOnScreen(mLocation);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if(mTargetView == null || !mShouldDoAnimation || mTargetWidth <= 0)
return;
if(mRevealRadius > mMinBetweenWidthAndHeight / 2)
mRevealRadius = mRevealRadiusGap * 4;
else
mRevealRadius = mRevealRadiusGap;
int[] location = new int[2];
this.getLocationOnScreen(mLocation);
mTargetView.getLocationOnScreen(location);
int top = location[1] - mLocation[1];
int left = location[0] - mLocation[0];
int right = left mTargetView.getMeasuredWidth();
int bottom = top mTargetView.getMeasuredHeight();
canvas.save();
canvas.clipRect(left, top, right, bottom);
canvas.drawCircle(mCenterX, mCenterY, mRevealRadius, mPaint);
canvas.restore();
if(mRevealRadius <= mMaxRadius)
postInvalidateDelayed(INVALIDATE_DURATION, left, top, right, bottom);
else if(!mIsPressed){
mShouldDoAnimation = false;
postInvalidateDelayed(INVALIDATE_DURATION, left, top, right, bottom);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
View targetView = getTargetView(this,x,y);
if(targetView != null && targetView.isEnabled()){
mTargetView = targetView;
initParametersForChild(event,targetView);
postInvalidateDelayed(INVALIDATE_DURATION);
}
break;
case MotionEvent.ACTION_UP:
mIsPressed = false;
postInvalidateDelayed(INVALIDATE_DURATION);
mDispatchUpTouchEventRunnable.event = event;
postDelayed(mDispatchUpTouchEventRunnable, 40);
break;
case MotionEvent.ACTION_CANCEL:
mIsPressed = false;
postInvalidateDelayed(INVALIDATE_DURATION);
break;
}
return super.dispatchTouchEvent(event);
}
public View getTargetView(View view,int x,int y){
View target = null;
ArrayList<View> views = view.getTouchables();
for(View child : views)
if(isTouchPointInView(child,x,y)){
target = child;
break;
}
return target;
}
public boolean isTouchPointInView(View child,int x,int y){
int[] location = new int[2];
child.getLocationOnScreen(location);
int top = location[1];
int left = location[0];
int right = left child.getMeasuredWidth();
int bottom = top child.getMeasuredHeight();
if(child.isClickable() && y>=top && y<= bottom && x >= left && x<= right)
return true;
else
return false;
}
public void initParametersForChild(MotionEvent event,View view){
mCenterX = event.getX();
mCenterY = event.getY();
mTargetWidth = view.getMeasuredWidth();
mTargetHeight = view.getMeasuredHeight();
mMinBetweenWidthAndHeight = Math.min(mTargetWidth, mTargetHeight);
mMaxBetweenWidthAndHeight = Math.max(mTargetWidth, mTargetHeight);
mRevealRadius = 0;
mRevealRadiusGap = mMinBetweenWidthAndHeight / 8;
mIsPressed = true;
mShouldDoAnimation = true;
int[] location = new int[2];
view.getLocationOnScreen(location);
int left = location[0] - mLocation[0];
int mTransformedCenterX = (int)mCenterX - left;
mMaxRadius = Math.max(mTransformedCenterX, mTargetWidth - mTransformedCenterX);
}
@Override
public void run() {
super.performClick();
}
@Override
public boolean performClick() {
postDelayed(this,40);
return true;
}
private class DispatchUpTouchEventRunnable implements Runnable{
public MotionEvent event;
@Override
public void run() {
if(mTargetView.isEnabled() && mTargetView.isClickable())
return;
if(isTouchPointInView(mTargetView, (int)event.getRawX(), (int)event.getRawX()))
mTargetView.performClick();
}
}
}
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论