您的位置:首页 > 其它

自定义按钮实现水波点击效果

2017-09-29 22:16 405 查看

1运行效果



2自定义布局

public class RevealLayout extends LinearLayout implements Runnable {

private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

private int[] mLocationInScreen = new int[2];

private float mCenterX;
private float mCenterY;

private int mTargetWidth;
private int mTargetHeight;

private int mMaxBetweenWidthAndHeight;
private int mMinBetweenWidthAndHeight;

private int mMaxRevealRadius;

private int mRevealRadiusGap;

private int mRevealRadius = 0;

private boolean mShouldDoAnimation = false;
private boolean mIsPressed = false;

private View mTouchTarget;

private int INVALIDATE_DURATION = 40;

private DispatchUpTouchEventRunnable mDispatchUpTouchEventRunnable = new DispatchUpTouchEventRunnable();

public RevealLayout(Context context) {
super(context);
init();
}

public RevealLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public RevealLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init(){
setWillNotDraw(false);
mPaint.setColor(getResources().getColor(#1b000000));
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
this.getLocationOnScreen(mLocationInScreen);
}

private 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;
mShouldDoAnimation = true;
mIsPressed = true;
mRevealRadiusGap = mMinBetweenWidthAndHeight / 8;

int[] location = new int[2];
view.getLocationOnScreen(location);
int left = location[0] - mLocationInScreen[0];
int transformedCenterX = (int)mCenterY - left;
mMaxRevealRadius = Math.max(transformedCenterX,mTargetWidth - transformedCenterX);
}

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if(!mShouldDoAnimation || mTargetWidth <= 0 || mTouchTarget == null){
return;
}
if(mRevealRadius > mMinBetweenWidthAndHeight / 2){
mRevealRadius += mRevealRadiusGap * 4;
}else {
mRevealRadius += mRevealRadiusGap;
}
this.getLocationOnScreen(mLocationInScreen);
int[] location = new int[2];
mTouchTarget.getLocationOnScreen(location);
int left = location[0] - mLocationInScreen[0];
int top = location[1] - mLocationInScreen[1];
int right = left + mTouchTarget.getMeasuredWidth();
int bottom = top + mTouchTarget.getMeasuredHeight();

canvas.save();
canvas.clipRect(left,top,right,bottom);
canvas.drawCircle(mCenterX,mCenterY,mRevealRadius,mPaint);
canvas.restore();

if(mRevealRadius <= mMaxRevealRadius){
postInvalidateDelayed(INVALIDATE_DURATION,left,top,right,bottom);
}else if(!mIsPressed){
mShouldDoAnimation = false;
postInvalidateDelayed(INVALIDATE_DURATION,left,top,right,bottom);
}
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getRawX();
int y = (int) ev.getRawY();
int action = ev.getAction();
if(action == MotionEvent.ACTION_DOWN){
View touchTarget = getTouchTarget(this,x,y);
if(touchTarget != null && touchTarget.isClickable() && touchTarget.isEnabled()){
mTouchTarget = touchTarget;
initParametersForChild(ev,touchTarget);
postInvalidateDelayed(INVALIDATE_DURATION);
}
}else if (action == MotionEvent.ACTION_UP){
mIsPressed = false;
postInvalidateDelayed(INVALIDATE_DURATION);
mDispatchUpTouchEventRunnable.event = ev;
postDelayed(mDispatchUpTouchEventRunnable,40);
return true;
}else if (action == MotionEvent.ACTION_CANCEL){
mIsPressed = false;
postInvalidateDelayed(INVALIDATE_DURATION);
}
return super.dispatchTouchEvent(ev);
}

private View getTouchTarget(View view,int x, int y){
View target = null;
ArrayList<View> TouchableView = view.getTouchables();
for (View child : TouchableView){
if(isTouchPointInView(child,x,y)){
target = child;
break;
}
}
return target;
}

private boolean isTouchPointInView(View view, int x, int y){

int[] location = new int[2];
view.getLocationOnScreen(location);
int left = location[0];
int top = location[1];
int right = left + view.getMeasuredWidth();
int bottom = top + view.getMeasuredHeight();
if(view.isClickable() && y >= top && y <= bottom && x >= left && x <= right){
return true;
}
return false;
}

@Override
public boolean performClick() {
postDelayed(this,400);
return true;
}

@Override
public void run() {
super.performClick();
}
private class DispatchUpTouchEventRunnable implements Runnable{
public MotionEvent event;

@Override
public void run() {
if(mTouchTarget == null || !mTouchTarget.isEnabled()){
return;
}
if (isTouchPointInView(mTouchTarget,(int)event.getRawX(),(int)event.getRawY())){
mTouchTarget.performClick();
}
}
}
}


3布局activity_main

?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:background="#ffffff"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.my.waterbatton.ui.RevealLayout
android:id="@+id/layout1"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<Button
android:id="@+id/btn1"
style="@style/AppTheme.Button.Green"
android:enabled="true"
android:text="Button"
android:layout_width="match_parent"
/>
</com.my.waterbatton.ui.RevealLayout>
<com.my.waterbatton.ui.RevealLayout
android:id="@+id/layout2"
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:orientation="vertical"
android:layout_height="wrap_content">

<Button
android:id="@+id/button1"
style="@style/AppTheme.Button.Green"
android:layout_width="200dp"
android:enabled="true"
android:text="Button" />

<Button
android:id="@+id/button2"
style="@style/AppTheme.Button.Green"

b491
android:layout_margin="10dp"
android:enabled="true"
android:text="Button" />

<Button
android:id="@+id/button3"
style="@style/AppTheme.Button.Highlight"
android:layout_margin="10dp"
android:enabled="true"
android:text="Button" />

<Button
android:id="@+id/button4"
style="@style/AppTheme.Button.Highlight"
android:layout_height="100dp"
android:layout_margin="10dp"
android:enabled="true"
android:text="Button" />

</com.my.waterbatton.ui.RevealLayout>
</LinearLayout>


4 styles定义重复代码

<style name="AppTheme.Button">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">44dp</item>
<item name="android:textSize">18dp</item>
</style>

<style name="AppTheme.Button.Green">
<item name="android:background">#0ac39e</item>
<item name="android:textColor">#ffffff</item>
</style>

<style name="AppTheme.Button.Highlight">
<item name="android:background">#4185f2</item>
<item name="android:textColor">#ffffff</item>
</style>


源码下载

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  自定义 特殊按钮