princekin-f / easyfloat Goto Github PK
View Code? Open in Web Editor NEW🔥 EasyFloat:浮窗从未如此简单(Android可拖拽悬浮窗口,支持页面过滤、自定义动画,可设置单页面浮窗、前台浮窗、全局浮窗,浮窗权限按需自动申请...)
License: Apache License 2.0
🔥 EasyFloat:浮窗从未如此简单(Android可拖拽悬浮窗口,支持页面过滤、自定义动画,可设置单页面浮窗、前台浮窗、全局浮窗,浮窗权限按需自动申请...)
License: Apache License 2.0
如果不存在就新建,存在就hide,只有个isShow,好像没看到有此类方法?
您好 您发布的悬浮窗项目 今天用到了 很棒
但是 发现弹框布局中出现的输入框能获取到焦点 但是不能输入 请问这个问题从哪里入手解决。
虚拟大师(安卓真机里的 安卓模拟器)
EasyFloat.hideAppFloat()
EasyFloat.showAppFloat()
EasyFloat.dismissAppFloat()失效咋办··
首先很感谢开源这个项目,在使用当中有些地方发现的问题提出一下,
设置了 .setSidePattern(SidePattern.TOP) 之后 配合 .setGravity(Gravity.TOP, 0, 20)这个偏移 拖动功能就失效了。我的设置总属性如下:
EasyFloat.with(this).setLayout(R.layout.item_float_top_view)
.setMatchParent(true, false)
// .setSidePattern(SidePattern.TOP)
.setTag("only" + i)
.setDragEnable(true)
.setShowPattern(ShowPattern.FOREGROUND)
.setGravity(Gravity.TOP, 0, 20)
.setAppFloatAnimator(null)
.invokeView(this)
.show();
因业务需要 弹窗会被下一个弹窗顶掉 也就是弹窗内容改变 可是 .invokeView(this) 的话貌似只能在新弹窗才能更新xml内容
然后在创新新弹窗和销毁上一个弹窗的时候 出现了一个问题 首先代码如下
private int i = 0;
@Override
public void invoke(View floatingView) {
((TextView) floatingView.findViewById(R.id.tv_tip_show)).setText("电");
((TextView) floatingView.findViewById(R.id.tv_tip_content)).setText("电气工程" + i);
}
@OnClick(R.id.btn)
public void onViewClicked() {
if (EasyFloat.appFloatIsShow("only"+i)) {
EasyFloat.dismissAppFloat(this, "only"+i);
}
i++;
showFloat();
}
先判断是否显示 然后dismiss掉它 再show一个不同的tag 此时发现一个问题 0-1 Floatservice 正常启动 然后在 1-2的过程中 dismiss 1 之后 此时 2还未被启动 也就未添加到 floatTag 中 然后在1完结动画后 就stopService了 就这样 2 成了孤儿。。而后续 又因为 2被添加进了 floatTag 并且不会被清除,所以后续的 3 ,4等tag /**
* 关闭浮窗后,检测是否需要关闭Service
*/
fun checkStop(context: Context, floatTag: String?) {
// 先清除当条浮窗信息
if (floatMap.isNotEmpty()) floatMap.remove(floatTag)
// 如有没有其他浮窗存在,关闭Service
if (floatMap.isEmpty()) context.stopService(Intent(context, FloatService::class.java))
}
并不会stopService 就独独 2 会很尴尬
我的解决方法是
private int i = 0;
private int oldI = 0;
@OnClick(R.id.btn)
public void onViewClicked() {
oldI = i;
i++;
showFloat();
if (EasyFloat.appFloatIsShow("only" + oldI)) {
EasyFloat.dismissAppFloat(this, "only" + oldI);
}
}
先show 后 dismiss 目前看 是不会stopService 了所以每一个dismiss 都会执行。
当然 还是 希望能优化 这部分。。。
我是通过xml布局加载出来的,想要获取该图片在middle_constraintlayout这个ConstraintLayout布局内的xy轴坐标,而不是整个手机屏幕的坐标
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_yiyilingqi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#3300ff00"
app:layout_constraintTop_toTopOf="parent">
</androidx.appcompat.widget.Toolbar>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/middle_constraintlayout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/tl_bottom"
android:background="#330000ff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_yiyilingqi">
<com.lzf.easyfloat.widget.activityfloat.FloatingView
android:id="@+id/floatingView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher_round" />
</com.lzf.easyfloat.widget.activityfloat.FloatingView>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/tl_bottom"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_height="wrap_content">
</androidx.appcompat.widget.Toolbar>
</androidx.constraintlayout.widget.ConstraintLayout>
我在自己项目集成,在一个被设置成过滤的Activity里面触发悬浮窗的显示;
说明:activity1:主界面(显示和隐藏的逻辑都在这里)
activity2:触发界面,被设置成过滤不显示
activity3:其他界面
bug1: 从1到2,在2里面点击触发,发送EvenBus,1收到后显示;这个时候2并没有被过滤掉。
bug2:退出2回到1,正常显示,重新进入2,发现被过滤了,返回2回到1,1也不显示了,直到进入3,又恢复正常显示。
我在demo上操作上面流程没问题,但是由于我的项目比较复杂,应该是有某些冲突,我该从什么地方入手找原因解决他。谢谢。
希望能提供动态修改WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
这样的API。
因为有的浮窗只是展示用,不需要按钮点击。希望能透过浮窗直接点击或滚动浮窗下面的按钮或界面,浮窗不占用浮窗区域的焦点。
fragment.startActivityForResult启动设置页面,会立马在OnActivityResult中响应。
minsdkversion 19?omg!
点个赞
大佬你好 ,我想实现一个推送消息来了,在屏幕上方出现一个消息框,前台的,用户点击或触摸就可以自动划上去,控制用户只能往上滑动。这个怎么实现呢
连续两次创建悬浮窗代码如下
override fun openFloatWindow() {
EasyFloat.with(AppManager.getAppManager().currentActivity())
// 设置浮窗xml布局文件
.setLayout(R.layout.float_window_select_question)
// 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示
.setShowPattern(ShowPattern.ALL_TIME)
// 设置浮窗的标签,用于区分多个浮窗
.setTag("selectQuestion")
// 设置浮窗固定坐标,ps:设置固定坐标,Gravity属性和offset属性将无效
.setLocation(ConvertUtils.dp2px(64f), ConvertUtils.dp2px(128f))
// 设置我们传入xml布局的详细信息
.invokeView(OnInvokeView {
val rootView = it.findViewById<ConstraintLayout>(R.id.cl_root_view)
val params = rootView.layoutParams as ViewGroup.LayoutParams
it.findViewById<ScaleImage>(R.id.img_scale).onScaledListener =
object : ScaleImage.OnScaledListener {
override fun onScaled(x: Float, y: Float, event: MotionEvent) {
params.width += x.toInt()
params.height += y.toInt()
rootView.layoutParams = params
}
}
})
.show()
EasyFloat.with(AppManager.getAppManager().currentActivity())
// 设置浮窗xml布局文件
.setLayout(R.layout.float_window_get_answer)
// 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示
.setShowPattern(ShowPattern.ALL_TIME)
// 设置浮窗的标签,用于区分多个浮窗
.setTag("getAnswer")
// 设置浮窗固定坐标,ps:设置固定坐标,Gravity属性和offset属性将无效
.setLocation(ConvertUtils.dp2px(30f), ConvertUtils.dp2px(500f))
// 设置我们传入xml布局的详细信息
.invokeView(OnInvokeView {
})
// 创建浮窗(不要忘记哦😂)
.show()
}
排查了下,发现原因是因为FloatService中的config属性导致
companion object {
private const val FLOAT_ACTION = "floatAction"
private const val FLOAT_VISIBLE = "floatVisible"
private const val FLOAT_DISMISS = "floatDismiss"
private const val FLOAT_TAG = "floatTag"
const val DEFAULT_TAG = "default"
val floatMap = mutableMapOf<String, AppFloatManager>()
private var config = FloatConfig()
/**
* 开启创建浮窗的Service
*/
fun startService(context: Context, floatConfig: FloatConfig) {
config = floatConfig
context.startService(Intent(context, FloatService::class.java))
}
}
由于config是静态变量,因此当连续两次调用startService的时候,第二次的config中的tag会把第一次config中的tag给覆盖掉,导致第二次的checkTag()方法返回false
另外这是个很棒的库,感谢大佬,最近项目正好需要用到
拖拽之后如何获取悬浮窗的位置
Java环境无法使用dismiss或hide,我已设置了tag,通过tag调用isShow返回的是false(悬浮窗已显示)
EasyFloat.with(activity)
.setShowPattern(ShowPattern.ALL_TIME)
.setSidePattern(SidePattern.RESULT_SIDE)
.setDragEnable(true)
.setTag(TAG_START)
.setGravity(Gravity.END | Gravity.CENTER_VERTICAL, 0, 200)
.setFilter(MainActivity.class)
.setLayout(R.layout.float_item)
.show();
EasyFloat.with(activity)
.setShowPattern(ShowPattern.ALL_TIME)
.setSidePattern(SidePattern.RESULT_SIDE)
.setDragEnable(true)
.setTag(TAG_END)
.setGravity(Gravity.END | Gravity.CENTER_VERTICAL, 0, 200)
.setFilter(MainActivity.class)
.setLayout(R.layout.float_item)
.show();
以上是创建系统悬浮窗的代码,执行时,只能显示最后创建的系统悬浮窗,我也尝试过在两次创建时间增加等待时间,还是不行,大家可以帮看下吗?
系统悬浮窗设置属性setShowPattern(ShowPattern.ALL_TIME),调用hideAppFloat,切换到另一个Activity,又把隐藏的显示出来了
项目使用的AndroidX.
集成之后:implementation 'com.github.princekin-f:EasyFloat:1.1.0'
提示:Error: Program type already present: androidx.asynclayoutinflater.view.AsyncLayoutInflater$1
大佬可否提供androidX版本的支持?
/**
* 申请悬浮窗权限
*/
internal fun requestPermission(activity: Activity, onPermissionResult: OnPermissionResult) {
PermissionFragment.requestPermission(activity, onPermissionResult)
}
就是这个方法啦 因为想在开始 就引导用户开启 而不是在触发的时候 使用 有时候 权限回调 并没有回来 。。。
应用在后台进程,当在后台进程收到消息后,调EasyFloat.with(ActivityManager.getInstance().currentActivity()).setLayout(R.layout.item_head_news).show(); 方法悬浮窗不显示
可以在根布局视图类添加
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
boolean result = super.dispatchKeyEventPreIme(event);
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
InputMethodUtils.closedInputMethod(FLOAT_TAG);
}
return result;
}
你好,请问一下你这个工程是否有对应的Java版本支持?
谢谢!
在应用内所有界面显示怎么设置
E/EGL_emulation: tid 1728: eglSurfaceAttrib(1210): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xc917edc0, error=EGL_BAD_MATCH
android 8.0上直接崩溃了、其他版本都是可以的。 @princekin-f
大佬。我能不能加你好友··
apk下不了哦
系统悬浮窗创建完后怎么去修改里面的文本内容和布局内容?
好像现在没这个功能,有没有当系统悬浮窗显示后,我需要修改悬浮窗里面的内容的时候,比如发一个通知,悬浮窗收到通知后立马更改展示的文本内容之类的。
// 设置系统浮窗的不需要显示的页面
.setFilter(MainActivity::class.java, SecondActivity::class.java)
不起作用在demo上和我自己的项目上试了不起作用,还是显示
手残党各种拼接界面拼得想哭了。。。
如果可以在release或者mainReadMe提供一个 demo apk 下载,会更加棒。
android9.0点击底部菜单栏拉出打开的应用菜单,浮窗会上移,关闭后恢复
Android 10 系统浮窗调用hideappfloat后, 再调用 showappfloat,浮窗无法显示了
android4.4红米MIUI9
无法跳转申请权限
前两天一直踩坑FloatingWindow框架,好多bug,看到作者这个,今天拿来试试,把前几天的功能基本替换完了,感谢作者,后续我可能会帮助提一些bug,祝开源项目越来越好,2020,💪加油!
class EasyMain : OnFloatAnimator {
override fun enterAnim(view: View, parentView: ViewGroup, sidePattern: SidePattern): Animator? {
val ofFloat = ObjectAnimator.ofFloat(
view,
"translationX",
view.translationX,
0f
)
ofFloat.duration = 2000
return ofFloat
}
override fun exitAnim(view: View, parentView: ViewGroup, sidePattern: SidePattern): Animator? {
val ofFloat = ObjectAnimator.ofFloat(
view,
"translationX",
view.translationX,
PixelChange.dp2px(view.context, 100f).toFloat()
)
ofFloat.duration = 2000
return ofFloat
}
}
java.lang.IllegalStateException:Not allowed to start service Intent { cmp=com.electronic/com.lzf.easyfloat.service.FloatService }: app is in background uid UidRecord{c7d93f0 u0a247 LAST bg:+1m56s623ms idle change:cached procs:2 seq(0,0,0)}
错误: 无法访问Function1
.registerCallbacks(new OnFloatCallbacks() {
^
找不到kotlin.jvm.functions.Function1的类文件
怎么弄都报这个,奇怪
/**
* 申请悬浮窗权限
*/
fun requestPermission(activity: Activity, onPermissionResult: OnPermissionResult) {
PermissionFragment.requestPermission(activity, onPermissionResult)
}
方法报错了,无法从静态上下文中引用非静态
我自己加上了@JvmStatic就可以了,不知道为什么Demo里的不会报错
/**
* 主动申请浮窗权限
*/
private fun requestPermission() {
PermissionUtils.requestPermission(this, object : OnPermissionResult {
override fun permissionResult(isOpen: Boolean) {
logger.i(isOpen)
}
})
}
首先跪谢大佬的悬浮窗开源库。
issues:当Activity有状态栏的时候,悬浮窗可以滑动到状态栏之下,状态栏会遮挡悬浮窗的一部分,不知道这个问题大佬是怎么解决的
如果setGrivity为Grivity.End,然后布局的宽度改变了,悬浮窗就没法自动贴在屏幕右侧,仍是原来的位置。看了一下源码,希望能把AppFloatManager.setGrivaity由EasyFloat暴露出来,这样就可以手动调用
调用其他方法都不会
部分代码
fun showWindow() {
var btnBack: ImageView? = null
EasyFloat.with(activity)
.setShowPattern(ShowPattern.ALL_TIME)
.setSidePattern(SidePattern.TOP)
.setDragEnable(false)
.setAnimator(null)
.setMatchParent(widthMatch = true, heightMatch = true)
.setGravity(Gravity.CENTER, 0, 51)
.startForeground(true, myNotification(activity))
.setLayout(R.layout.window_doorlock_video_call, OnInvokeView { root ->
root?.let {
btnBack = root.findViewById(R.id.iv_calling_back)
}
btnBack?.setOnClickListener {
}
})
.registerCallbacks {
// createResult { isCreated, msg, view -> }
// hide { }
// touchEvent { view, motionEvent ->
// IdleMode.instance.resetCountdown()
// }
// drag { view, motionEvent -> }
// dragEnd { }
show {
Log.i(TAG, "showWindow show") //此处不会有打印
}
dismiss {
Log.i(TAG, "showWindow dismiss")
}
}
.show()
我进入app悬浮窗权限设置的页面选择允许后,APP会报
E/InputDispatcher: channel '718ffe2 com.loma.im/com.xxxx.activity.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
然后app重启,是什么原因呢?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.