import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.DecelerateInterpolator;
import androidx.appcompat.widget.AppCompatImageView;
public class DragFloatActionButton extends AppCompatImageView {
private int parentHeight;
private int parentWidth;
private int lastX;
private int lastY;
private ViewGroup parent;
private OnClickListener onClickListener;
public DragFloatActionButton(Context context) {
super(context);
}
public DragFloatActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DragFloatActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private int downX = 0;
private int downY = 0;
private int upX = 0;
private int upY = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
ViewParent viewParent = getParent();
downX = lastX = rawX;
downY = lastY = rawY;
if (viewParent != null) {
//请求父控件不中断事件
viewParent.requestDisallowInterceptTouchEvent(true);
this.parent = (ViewGroup) viewParent;
//获取父控件的高度
parentHeight = this.parent.getHeight();
//获取父控件的宽度
parentWidth = this.parent.getWidth();
}
break;
case MotionEvent.ACTION_MOVE:
int dx = rawX - lastX;
int dy = rawY - lastY;
float x = getX() + dx;
float y = getY() + dy;
//检测是否到达边缘 左上右下
x = x < 0 ? 0 : x > parentWidth - getWidth() ? parentWidth - getWidth() : x;
//控件距离底部的margin
double bottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,60,getResources().getDisplayMetrics());
y = y < 0 ? 0 : (float) (y > parentHeight - getHeight() - bottomMargin ? parentHeight - getHeight() - bottomMargin : y);
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_UP:
upX = (int) event.getRawX();
upY = (int) event.getRawY();
int distanceX = Math.abs(Math.abs(upX) - Math.abs(downX));
int distanceY = Math.abs(Math.abs(upY) - Math.abs(downY));
//当手指按下的事件跟手指抬起事件之间的距离小于10时执行点击事件
if (Math.max(distanceX, distanceY) <= 10) {
if (onClickListener != null) {
onClickListener.onClick();
}
}
moveHide(rawX);
break;
}
//如果是拖拽则消s耗事件,否则正常传递即可。
return true;
}
private void moveHide(int rawX) {
if (rawX >= parentWidth / 2) {
//靠右吸附
animate().setInterpolator(new DecelerateInterpolator())
.setDuration(500)
.xBy(parentWidth - getWidth() - getX())
.start();
} else {
//靠左吸附
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
oa.start();
}
}
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public interface OnClickListener {
void onClick();
}
}
DragFloatActionButton(自定义全屏拖动按钮)
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 需求说明:使用video.js播放视频,要求点击全屏按钮的时候,弹幕可以跟视频一起全屏。 看起来是个很简单的需求,...
- 项目需求:过程中要实现能在页面中随意的拖动,刚开始实现是用悬浮球的形式进行实现,因为之前项目中用过,实现后发现用户...
- 导航控制器的返回按钮设置以及一些细节处理 导航控制器的返回按钮可以通过下面两个属性来设置 根据谁的东西谁管理的原则...