最近在写悬浮的按钮,而且可以拖动,查了一下, 整理了自己的方法,ok 直接开始吧;
第一步新建一个自定义的线性布局:
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.xlky.xlxt.core.util.DensityUtils;
import com.xlky.xlxt.tools.LogUtils;
/**
* 悬浮按钮布局 2023.7.25
*/
public class DragLinearLayout extends LinearLayout {
/*
private boolean
onlyX,//仅X轴可移动
onlyY;//仅Y轴可移动*/
private int
lastX,lastY,//记录上一次的x,y坐标
mLeft,mTop,mRight,mBottom,//记录当前元素的的上下左右(相对于父元素)
startX,startY,//记录初始x,y坐标
endX,endY;//移动结束x,y坐标,用于计算是否点击事件
//用于点击事件触发
public interface OnClickListener
{
void onClick(View view);
}
OnClickListener clickListener = null;
public DragLinearLayout(Context context) {
super(context);
}
public void setOnClickListener(OnClickListener listener)
{
clickListener = listener;
}
public DragLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
/*
//获取属性值
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.DragLinearLayout);
onlyX = type.getBoolean(R.styleable.DragLinearLayout_onlyX,false);
onlyY = type.getBoolean(R.styleable.DragLinearLayout_onlyY,false);
type.recycle();*/
}
public DragLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int rawX = (int)event.getRawX();
int rawY = (int)event.getRawY();
switch (action)
{
case MotionEvent.ACTION_DOWN://按下记录初始坐标
startX = lastX = rawX;
startY = lastY = rawY;
break;
case MotionEvent.ACTION_MOVE:
//计算偏移量
int dx = rawX - lastX;
int dy = rawY - lastY;
/*
//限制只能x轴方向拖动
if (onlyX)
{
dy = 0;
//限制只能y轴方向拖动
}else if (onlyY)
{
dx = 0;
}*/
//计算控件坐标距离父控件原点各方向距离
mLeft = getLeft() + dx;
mRight = getRight() + dx;
mTop = getTop() + dy;
mBottom = getBottom() + dy;
Log.d("mawl","移动监听=="+mLeft+" "+mTop+" "+mRight+" "+mBottom);
// 移动监听==631 1899 931 2199 为了限制在一定范围内拖动
if(mLeft>35&&mTop>140&&mRight<DensityUtils.getScreenWidth()-50&&mBottom<DensityUtils.getScreenHeight()-200){
layout(mLeft,mTop,mRight,mBottom);
}
//拖动时背景半透明
//setBackground(getResources().getDrawable(R.drawable.draglinearlayout_press));
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_UP:
LogUtils.d("屏幕宽高是=="+DensityUtils.getScreenWidth()+" "+DensityUtils.getScreenHeight());
endX = rawX;
endY = rawY;
//拖动完毕背景恢复
//setBackground(getResources().getDrawable(R.drawable.draglinearlayout_up));
//点击事件
if (Math.abs(endX - startX) < 3 || Math.abs(endY - startY) < 3) {
this.performClick();
// clickListener.onClick(this);
}
if(mLeft==0&&mTop==0&&mRight==0&&mBottom==0){
//该判断是为了防止点击跳转界面时候 获取到的四个位置尺寸为0,界面又绘制到0的位置
}else {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)getLayoutParams();
params.setMargins(mLeft,mTop,0,0);
//这里指定下宽高,否则如果布局文件指定了match_parent/wrap_content,会导致自动伸缩宽高
params.width = getMeasuredWidth();
params.height = getMeasuredHeight();
setLayoutParams(params);
}
break;
}
return true;
}
}
第二步 在布局中的配置:
```java
<com.xlky.xlxt.tools.widget.DragLinearLayout
android:id="@+id/float_view"
android:layout_width="@dimen/dp_66"
android:visibility="gone"
android:layout_height="@dimen/dp_66"
android:orientation="vertical"
>
<ImageView
android:id="@+id/iv_home_float_ad"
android:layout_width="@dimen/dp_66"
android:layout_height="@dimen/dp_66"
android:src="@mipmap/ic_launcher"
></ImageView>
</com.xlky.xlxt.tools.widget.DragLinearLayout>
别忘了 最外部布局是 相对布局的,ok 继续最后一步,在代码中的使用:
@BindView(R.id.float_view)
DragLinearLayout float_view;//首页悬浮按钮
@BindView(R.id.iv_home_float_ad)
ImageView iv_home_float_ad;//首页悬浮按钮
// 。。。。。。略去其他的不用代码
//初始化 悬浮按钮 位置
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)float_view.getLayoutParams();
// params.setMargins(DensityUtils.getScreenWidth()-100-iv_home_float_ad.getWidth(),DensityUtils.getScreenHeight()-300-iv_home_float_ad.getHeight(), DensityUtils.getScreenWidth()-100,DensityUtils.getScreenHeight()-300);
params.setMargins(1122 , 2401 , 1375 , 2654);//设置在当前布局的某个位置,比如右下角,具体根据自己手机分辨率来填写
float_view.setLayoutParams(params);
//。。。。。。略去其他的不用代码
float_view.setVisibility(View.VISIBLE);
ossAdFloatBean = ossAdEntity.getData().get(0);
GlideManager.loadImg(HttpConstants.XLXT_IMG + ossAdFloatBean.getImgUrl(), iv_home_float_ad, R.drawable.img_all_bg); //给图片配置图片信息
//点击方法
float_view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!TextUtils.isEmpty(ossAdFloatBean.getADUrl())) {
//点击首页悬浮按钮
if (!LoginManager.getInstance().isLogin()) {
LogUtils.d("点击悬浮按钮 去登录=="+ossAdFloatBean);
Intent intent=new Intent(mActivity,LoginPasswordActivity.class);
intent.putExtra(XlxtConstant.HOME_OSS_MASSAGE, ossAdFloatBean);
startActivity(intent);
}else {
HomeRoutManager.getInstance().ossH5OrNativeRout(mActivity, ossAdFloatBean);
}
}
}
});
ok 就简单的这么写吧,可以试试