本文实例讲述了Android实现带磁性的悬浮窗体效果。分享给大家供大家参考,具体如下: 带磁性的悬浮窗体,类似于360绿色小人 主要实现的是: 1.悬浮所有窗体之上 2.有吸引力,吸附于屏幕边上 3.有点击效果 下面我就实现上面三点,简单封装了个FloatView 先看下本次Demo的效果图,然后再看代码, 效果图: FloatView代码如下 package com.manymore13.flowwindowdemo; import android.content.Context; import android.graphics.PixelFormat; import android.g 在Android开发中,创建一个带有磁性吸附效果的悬浮窗体可以增强用户的交互体验,尤其在工具类应用中常见,例如360安全卫士的绿色小人。本实例将介绍如何实现这样的功能。 我们需要创建一个自定义的`FloatView`类,继承自`ImageView`。`FloatView`类的职责是处理悬浮窗体的显示、移动以及吸附到屏幕边缘的能力。以下是`FloatView`类的部分核心代码: ```java public class FloatView extends ImageView { private Context c; private int imgId; private WindowManager windowManager; private WindowManager.LayoutParams windowManagerParams; // 其他成员变量... public FloatView(Context context, AttributeSet attrs) { super(context, attrs); } public FloatView(Context c) { super(c); initView(c); } // 初始化窗体 private void initView(Context c) { windowManager = (WindowManager) c.getApplicationContext().getSystemService(Context.WINDOW_SERVICE); // 获取屏幕宽度 screenWidth = windowManager.getDefaultDisplay().getWidth(); // 设置初始图像资源 this.setImageResource(imgId); // 设置LayoutParams windowManagerParams = new WindowManager.LayoutParams(); // 窗口类型 windowManagerParams.type = LayoutParams.TYPE_PHONE; // 背景透明 windowManagerParams.format = PixelFormat.RGBA_8888; // 非触摸模式,非聚焦 windowManagerParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL| LayoutParams.FLAG_NOT_FOCUSABLE; // 初始位置设为左上角 windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP; // 设置初始坐标 windowManagerParams.x = 0; windowManagerParams.y = 200; // 设置宽高为WRAP_CONTENT windowManagerParams.width = LayoutParams.WRAP_CONTENT; windowManagerParams.height = LayoutParams.WRAP_CONTENT; } // 设置图像资源 public void setImgResource(int id) { imgId = id; } // 处理触摸事件 @Override public boolean onTouchEvent(MotionEvent event) { // ... return true; } } ``` 在`onTouchEvent`方法中,我们需要处理用户的触摸操作,包括拖动悬浮窗体和判断是否吸附到屏幕边缘。当用户触摸到悬浮窗时,记录触摸点的坐标,并根据用户的手势更新悬浮窗的位置。同时,当悬浮窗靠近屏幕边缘时,需要让它自动吸附到边缘,这可以通过计算距离并设置新的坐标来实现。 为了实现吸附效果,可以在`onTouchEvent`中添加以下逻辑: ```java switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mTouchX = event.getX(); mTouchY = event.getY(); break; case MotionEvent.ACTION_UP: // 检查是否需要吸附 checkAndStickToEdge(); break; case MotionEvent.ACTION_MOVE: x = event.getX() - mTouchX; y = event.getY() - mTouchY; // 更新坐标 windowManagerParams.x = (int) (startX + x); windowManagerParams.y = (int) (startY + y); windowManager.updateViewLayout(this, windowManagerParams); break; } // 检查并吸附到边缘 private void checkAndStickToEdge() { // 计算与屏幕边缘的距离 Rect displayFrame = new Rect(); windowManager.getDefaultDisplay().getRectSize(displayFrame); int leftDist = Math.abs(windowManagerParams.x); int topDist = Math.abs(windowManagerParams.y); int rightDist = displayFrame.width() - (windowManagerParams.x + getWidth()); int bottomDist = displayFrame.height() - (windowManagerParams.y + getHeight()); // 如果距离小于预设的阈值,则吸附 if (leftDist < controlledSpace) { windowManagerParams.x = -getWidth(); } else if (rightDist < controlledSpace) { windowManagerParams.x = displayFrame.width() - getWidth(); } if (topDist < controlledSpace) { windowManagerParams.y = -getHeight(); } else if (bottomDist < controlledSpace) { windowManagerParams.y = displayFrame.height() - getHeight(); } windowManager.updateViewLayout(this, windowManagerParams); } ``` 在上面的代码中,`checkAndStickToEdge`方法会检查悬浮窗体与屏幕四边的距离,如果小于设定的阈值(`controlledSpace`),则将其吸附到对应边缘。此外,还需要处理点击事件,可以通过设置`OnClickListener`来实现。 在实际应用中,你可能还需要考虑权限问题,因为悬浮窗通常需要`SYSTEM_ALERT_WINDOW`权限才能正常工作。在AndroidManifest.xml中添加以下权限: ```xml <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> ``` 并且,对于Android 6.0(API级别23)及以上版本,还需要在运行时动态请求权限。 要在Activity或Service中创建并显示这个悬浮窗体,可以这样操作: ```java FloatView floatView = new FloatView(this); floatView.setImgResource(R.drawable.my_image); // 设置其他属性... WindowManager.LayoutParams layoutParams = floatView.initLayoutParams(); windowManager.addView(floatView, layoutParams); ``` 通过以上步骤,你就可以在Android应用中实现一个具有磁性吸附效果的悬浮窗体了。这个悬浮窗体不仅能够自由移动,而且会在接近屏幕边缘时自动吸附,增强了用户体验。
- 粉丝: 6
- 资源: 939
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
评论0