120人参与 • 2025-04-24 • Android
这是最灵活的实现方式,可以在任何界面显示悬浮按钮:
public class floatingbuttonservice extends service {
private windowmanager windowmanager;
private view floatingbutton;
@override
public ibinder onbind(intent intent) {
return null;
}
@override
public void oncreate() {
super.oncreate();
// 创建悬浮按钮视图
floatingbutton = layoutinflater.from(this).inflate(r.layout.floating_button, null);
// 设置按钮点击事件
floatingbutton.findviewbyid(r.id.float_button).setonclicklistener(v -> {
// 处理点击事件
toast.maketext(this, "悬浮按钮被点击", toast.length_short).show();
});
// 设置窗口参数
windowmanager.layoutparams params = new windowmanager.layoutparams(
windowmanager.layoutparams.wrap_content,
windowmanager.layoutparams.wrap_content,
build.version.sdk_int >= build.version_codes.o ?
windowmanager.layoutparams.type_application_overlay :
windowmanager.layoutparams.type_phone,
windowmanager.layoutparams.flag_not_focusable,
pixelformat.translucent);
// 设置初始位置
params.gravity = gravity.top | gravity.start;
params.x = 0;
params.y = 100;
// 获取windowmanager并添加视图
windowmanager = (windowmanager) getsystemservice(window_service);
windowmanager.addview(floatingbutton, params);
// 添加拖拽功能
adddragfeature();
}
private void adddragfeature() {
floatingbutton.setontouchlistener(new view.ontouchlistener() {
private int initialx;
private int initialy;
private float initialtouchx;
private float initialtouchy;
@override
public boolean ontouch(view v, motionevent event) {
switch (event.getaction()) {
case motionevent.action_down:
initialx = params.x;
initialy = params.y;
initialtouchx = event.getrawx();
initialtouchy = event.getrawy();
return true;
case motionevent.action_move:
params.x = initialx + (int) (event.getrawx() - initialtouchx);
params.y = initialy + (int) (event.getrawy() - initialtouchy);
windowmanager.updateviewlayout(floatingbutton, params);
return true;
}
return false;
}
});
}
@override
public void ondestroy() {
super.ondestroy();
if (floatingbutton != null) {
windowmanager.removeview(floatingbutton);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<imagebutton
android:id="@+id/float_button"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="@drawable/circle_background"
android:src="@drawable/ic_float_button"
android:elevation="8dp"
android:layout_margin="16dp" />
</framelayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/colorprimary" />
</shape>
// 在需要显示悬浮按钮的地方启动服务 startservice(new intent(context, floatingbuttonservice.class)); // 停止服务 stopservice(new intent(context, floatingbuttonservice.class));
<uses-permission android:name="android.permission.system_alert_window" />
// 检查悬浮窗权限
if (build.version.sdk_int >= build.version_codes.m) {
if (!settings.candrawoverlays(this)) {
intent intent = new intent(settings.action_manage_overlay_permission,
uri.parse("package:" + getpackagename()));
startactivityforresult(intent, overlay_permission_req);
} else {
// 已经有权限,启动服务
startservice(new intent(this, floatingbuttonservice.class));
}
} else {
// 6.0以下直接启动
startservice(new intent(this, floatingbuttonservice.class));
}
// 在按钮点击时添加动画
floatingbutton.setonclicklistener(v -> {
// 缩放动画
objectanimator scalex = objectanimator.offloat(v, "scalex", 1f, 0.8f, 1f);
objectanimator scaley = objectanimator.offloat(v, "scaley", 1f, 0.8f, 1f);
animatorset animatorset = new animatorset();
animatorset.playtogether(scalex, scaley);
animatorset.setduration(200);
animatorset.start();
// 执行点击操作
performbuttonaction();
});
private void autoattachtoedge() {
int screenwidth = getresources().getdisplaymetrics().widthpixels;
int buttonwidth = floatingbutton.getwidth();
if (params.x < screenwidth / 2 - buttonwidth / 2) {
// 吸附到左边
params.x = 0;
} else {
// 吸附到右边
params.x = screenwidth - buttonwidth;
}
windowmanager.updateviewlayout(floatingbutton, params);
}
public void hidebutton() {
floatingbutton.animate()
.translationy(floatingbutton.getheight())
.setduration(300)
.start();
}
public void showbutton() {
floatingbutton.animate()
.translationy(0)
.setduration(300)
.start();
}
性能优化:
updateviewlayout内存管理:
用户体验:
兼容性处理:
如果只需要在应用内显示悬浮按钮,可以使用 material design 组件:
<androidx.coordinatorlayout.widget.coordinatorlayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 其他内容 -->
<com.google.android.material.floatingactionbutton.floatingactionbutton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.coordinatorlayout>
一些流行的悬浮按钮库:
权限问题:
system_alert_window 权限位置不正确:
windowmanager.layoutparams 的 gravity 设置点击穿透:
flag_not_focusable 可能导致点击事件穿透ontouch 中返回 true 来拦截事件内存泄漏:
以上就是android studio实现自定义全局悬浮按钮的示例代码的详细内容,更多关于android studio悬浮按钮的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论