Android悬浮贴边按钮实现(含动画效果)
16lz
2021-01-26
效果图
代码实现
package com.dingo.newexproration.ui;import android.animation.ObjectAnimator;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.support.v7.widget.AppCompatImageView;import android.util.AttributeSet;import android.view.MotionEvent;import com.dingo.newexproration.R;public class FloatButton extends AppCompatImageView { /** * View的宽高 */ private int width; private int height; /** * 触摸点相对于View的坐标 */ private float touchX; private float touchY; /** * x,y坐标的纠正值 * 考虑到一些异性屏和非标准的显示区域 */ int xCorrection = 0; int yCorrection = 0; public void setxCorrection(int xCorrection) { this.xCorrection = xCorrection; } public void setyCorrection(int yCorrection) { this.yCorrection = yCorrection; } /** * 屏幕的宽高,默认是1024 * 600的屏幕高宽 * 在使用该类的时候最好设置该值为正确的显示区域宽高 */ private int screenWidth = 1024; private int screenHeight = 600; private final static int FADE_OUT = 1; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case FADE_OUT: ObjectAnimator.ofFloat(FloatButton.this, "alpha", 1.0f, ASSIST_TOUCH_VIEW_ALPHA_RATE) .setDuration(ANIMATION_DURATION) .start(); break; default: break; } } }; public void setScreenWidth(int screenWidth) { this.screenWidth = screenWidth; } public void setScreenHeight(int screenHeight) { this.screenHeight = screenHeight; } public FloatButton(Context context) { super(context); } public FloatButton(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); width = getWidth(); height = getHeight(); } private float mTouchStartX; private float mTouchStartY; private static final float TOLERANCE_RANGE = 18.0f; private static final float ASSIST_TOUCH_VIEW_ALPHA_RATE = 0.3f; private static final int ANIMATION_DURATION = 110; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setAlpha(1.0f); clearAnimation(); mHandler.removeMessages(FADE_OUT); touchX = event.getX(); touchY = event.getY(); mTouchStartX = event.getRawX(); mTouchStartY = event.getRawY(); setBackgroundResource(R.drawable.standard_float_ball_pressed); return true; case MotionEvent.ACTION_MOVE: setAlpha(1.0f); float nowY = event.getRawY() - touchY - yCorrection; float nowX = event.getRawX() - touchX - xCorrection; nowX = nowX < 0 ? 0 : (nowX + width > screenWidth) ? (screenWidth - width) : nowX; nowY = nowY < 0 ? 0 : (nowY + height > screenHeight) ? (screenHeight - height) : nowY; this.setY(nowY); this.setX(nowX); invalidate(); return true; case MotionEvent.ACTION_UP: //这里做动画贴边效果 float centerX = getX() + width / 2f; int halfOfScreenWidth = screenWidth / 2; if (centerX > halfOfScreenWidth) { ObjectAnimator.ofFloat(this, "translationX", getX(), screenWidth - width) .setDuration(250) .start(); } else { ObjectAnimator.ofFloat(this, "translationX", getX(), 0) .setDuration(250) .start(); } mHandler.sendEmptyMessageDelayed(FADE_OUT, 1000); touchX = 0; touchY = 0; setBackgroundResource(R.drawable.standard_float_ball_normal); float mTouchEndX = event.getRawX(); float mTouchEndY = event.getRawY(); if (Math.abs(mTouchEndX - mTouchStartX) < TOLERANCE_RANGE && Math.abs(mTouchEndY - mTouchStartY) < TOLERANCE_RANGE) { performClick(); return true; } return true; default: return super.onTouchEvent(event); } }}
使用
使用上跟普通控件一样,只不过是在findViewById之后设置下其setScreenHeight和setScreenWidth,这也是为了设置其可移动的范围,如果不设置则默认范围为初始值。
更多相关文章
- Android(安卓)Dialog 自定义宽度
- android 为ExpandableListView中child设置监听器
- android之ImageSwitcher 图片查看
- 屏幕亮屏、熄屏监听代码
- LinearLayout设置灰色边框,只保留底部边框,去掉三个框的技巧。
- Android(安卓)QQ通知小红点
- android 自定義的對話框(AlertActivity)
- Android百度地图的搜索及附近地址的检索
- Android(SpreadTurm)获取屏幕亮度,再设置屏幕亮度