实现悬浮窗口自动吸附到屏幕边缘

本文介绍如何创建两个View,一个用于悬浮显示,另一个通过OnHoverListener监听鼠标事件,实现悬浮窗口在靠近屏幕边缘时自动吸附的效果。
摘要由CSDN通过智能技术生成

2个View:FloatView  SensorView随便继承个View类。FloatView作为悬浮窗显示按钮等等,SensorView使用OnHoverListener接口感知鼠标进入、移除屏幕边缘。

FloatView布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" 
    >

   <Button 
    android:id="@+id/handup"
    android:layout_marginTop="4dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    
    android:textSize="36sp"
    android:drawableLeft="@drawable/floatbar_handup"
    android:background="#66CD00"
   >
       
   </Button>

       <Button 
    android:id="@+id/reboot_terminal"
    android:layout_marginTop="4dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    
    android:textSize="36sp"
    android:drawableLeft="@drawable/floatbar_reboot_terminal"
    android:background="#66CD00"
   >
  </Button>
       <Button 
    android:id="@+id/poweroff_terminal"
    android:layout_marginTop="4dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    
    android:textSize="36sp"
    android:drawableLeft="@drawable/floatbar_poweroff_terminal"
    android:background="#66CD00"
   ></Button>
    <Button 
    android:id="@+id/reboot_vm"
    android:layout_marginTop="4dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"  
    android:textSize="36sp"
    android:drawableLeft="@drawable/floatbar_reboot_vm"
    android:background="#66CD00"
   >
  </Button>
   <Button 
    android:id="@+id/window_close"
    android:layout_marginTop
以下是实现可拖动悬浮球的Vue代码示例,其中使用了Vue指令和事件监听来实现: ``` <template> <div class="floating-ball" v-draggable v-resizable :class="{ 'adhering': adhering }" :style="{ 'top': posY + 'px', 'left': posX + 'px' }" @mousedown="startDrag($event)" @mousemove="dragging($event)" @mouseup="endDrag()" @mouseleave="endDrag()" @touchstart="startDrag($event)" @touchmove="dragging($event)" @touchend="endDrag()"> <div class="inner-ball"></div> </div> </template> <script> export default { data() { return { posX: 0, posY: 0, adhering: false, screenWidth: 0, screenHeight: 0, ballDiameter: 50, halfBallDiameter: 25, adherenceDistance: 20, dragStartX: 0, dragStartY: 0, isDragging: false }; }, mounted() { this.screenWidth = window.innerWidth; this.screenHeight = window.innerHeight; window.addEventListener('scroll', this.handleScroll); }, destroyed() { window.removeEventListener('scroll', this.handleScroll); }, directives: { draggable: { inserted: function(el) { el.style.position = 'fixed'; } }, resizable: { inserted: function(el, binding) { el.style.width = binding.value + 'px'; el.style.height = binding.value + 'px'; } } }, methods: { startDrag(e) { this.isDragging = true; if (e.type === 'touchstart') { this.dragStartX = e.touches[0].clientX; this.dragStartY = e.touches[0].clientY; } else { this.dragStartX = e.clientX; this.dragStartY = e.clientY; } }, dragging(e) { if (!this.isDragging) { return; } let diffX, diffY; if (e.type === 'touchmove') { diffX = e.touches[0].clientX - this.dragStartX; diffY = e.touches[0].clientY - this.dragStartY; } else { diffX = e.clientX - this.dragStartX; diffY = e.clientY - this.dragStartY; } this.posX += diffX; this.posY += diffY; this.dragStartX = e.clientX; this.dragStartY = e.clientY; }, endDrag() { this.isDragging = false; this.adhereToScreenEdge(); }, handleScroll() { if (this.adhering) { this.adhereToScreenEdge(); } }, adhereToScreenEdge() { const leftDistance = this.posX; const topDistance = this.posY; const rightDistance = this.screenWidth - this.ballDiameter - this.posX; const bottomDistance = this.screenHeight - this.ballDiameter - this.posY; let adhering = false; if (leftDistance < this.adherenceDistance) { this.posX = -this.halfBallDiameter; adhering = true; } if (rightDistance < this.adherenceDistance) { this.posX = this.screenWidth - this.halfBallDiameter; adhering = true; } if (topDistance < this.adherenceDistance) { this.posY = -this.halfBallDiameter; adhering = true; } if (bottomDistance < this.adherenceDistance) { this.posY = this.screenHeight - this.halfBallDiameter; adhering = true; } this.adhering = adhering; } } }; </script> <style> .floating-ball { position: absolute; width: 50px; height: 50px; border-radius: 25px; background-color: #2196F3; cursor: move; } .inner-ball { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20px; height: 20px; border-radius: 10px; background-color: #fff; } .adhering { opacity: 0.5; } </style> ``` 在上面的代码中,我们使用了Vue指令`v-draggable`和`v-resizable`来使悬浮球可拖动和可调整大小。通过监听鼠标或触摸事件,我们可以在悬浮球被拖动时更新其位置。为了防止滚动屏幕导致悬浮球抖动,我们也监听了窗滚动事件,并在事件触发时重新计算悬浮球位置。 为了使悬浮球可以吸附屏幕边缘,我们定义了`adhereToScreenEdge`方法来计算悬浮球与屏幕边缘的距离,并在距离足够小的情况下将悬浮球位置设置为屏幕边缘。当悬浮吸附屏幕边缘时,我们使用CSS样式`opacity`将其透明度设置为0.5,并隐藏一半的悬浮球。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值