11人参与 • 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 举报,一经查实将立刻删除。
发表评论