Skip to content

Commit

Permalink
v 2.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
princekin-f committed Jul 14, 2021
1 parent f38f512 commit ea2b455
Showing 10 changed files with 181 additions and 116 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -44,8 +44,7 @@ allprojects {
- **在应用模块的`build.gradle`添加:**
```
dependencies {
// 最新版本,希望大家多反馈
implementation 'com.github.princekin-f:EasyFloat:2.0.2'
implementation 'com.github.princekin-f:EasyFloat:2.0.3'
}
```

@@ -77,7 +76,7 @@ EasyFloat.with(this).setLayout(R.layout.float_test).show()
## 完整使用示例:
```
EasyFloat.with(this)
// 设置浮窗xml布局文件,并可设置详细信息
// 设置浮窗xml布局文件/自定义View,并可设置详细信息
.setLayout(R.layout.float_app) { }
// 设置浮窗显示类型,默认只在当前Activity显示,可选一直显示、仅前台显示
.setShowPattern(ShowPattern.ALL_TIME)
@@ -93,6 +92,8 @@ EasyFloat.with(this)
.setLocation(100, 200)
// 设置浮窗的对齐方式和坐标偏移量
.setGravity(Gravity.END or Gravity.CENTER_VERTICAL, 0, 200)
// 设置当布局大小变化后,整体view的位置对齐方式
.setLayoutChangedGravity(Gravity.END)
// 设置拖拽边界值
.setBorder(100, 100,800,800)
// 设置宽高是否充满父布局,直接在xml设置match_parent属性无效
9 changes: 8 additions & 1 deletion UpdateDoc.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
## 版本更新日志
#### v 2.0.3:
- [支持直接设置View(`xml/View`即可使用)](https://github.com/princekin-f/EasyFloat/issues/110)
- [支持设置布局大小变化后,整体View的位置对齐方式](https://github.com/princekin-f/EasyFloat/pull/159)
- [修复`onCreate`无法创建单页面浮窗的问题](https://github.com/princekin-f/EasyFloat/issues/132)
- [修复在别的应用,横屏宽度异常问题](https://github.com/princekin-f/EasyFloat/issues/135)
- [修复浮窗创建失败,无法创建相同TAG的问题](https://github.com/princekin-f/EasyFloat/issues/138)

#### v 2.0.2:
- 解决Java关键字导致的包名冲突和[在别的应用上横屏的问题](https://github.com/princekin-f/EasyFloat/issues/135)
- 解决Java关键字导致的包名冲突。

#### v 2.0.0:
- 新增拖拽关闭、侧滑创建、状态栏沉浸、拖拽边界等功能;
16 changes: 14 additions & 2 deletions easyfloat/src/main/java/com/lzf/easyfloat/EasyFloat.kt
Original file line number Diff line number Diff line change
@@ -193,6 +193,17 @@ class EasyFloat {
config.invokeView = invokeView
}

/**
* 设置浮窗的布局视图,以及布局的操作接口
* @param layoutView 自定义的布局视图
* @param invokeView 布局视图的操作接口
*/
@JvmOverloads
fun setLayout(layoutView: View, invokeView: OnInvokeView? = null) = apply {
config.layoutView = layoutView
config.invokeView = invokeView
}

/**
* 设置浮窗的对齐方式,以及偏移量
* @param gravity 对齐方式
@@ -324,8 +335,9 @@ class EasyFloat {
* 创建浮窗,包括Activity浮窗和系统浮窗,如若系统浮窗无权限,先进行权限申请
*/
fun show() = when {
// 未设置浮窗布局文件,不予创建
config.layoutId == null -> callbackCreateFailed(WARN_NO_LAYOUT)
// 未设置浮窗布局文件/布局视图,不予创建
config.layoutId == null && config.layoutView == null ->
callbackCreateFailed(WARN_NO_LAYOUT)
// 仅当页显示,则直接创建activity浮窗
config.showPattern == ShowPattern.CURRENT_ACTIVITY -> createFloat()
// 系统浮窗需要先进行权限审核,有权限则创建app浮窗
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@ import android.graphics.PixelFormat
import android.graphics.Rect
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.*
import android.view.WindowManager.LayoutParams.*
import android.widget.EditText
@@ -35,30 +34,26 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi
var frameLayout: ParentFrameLayout? = null
private lateinit var touchUtils: TouchUtils
private var enterAnimator: Animator? = null
var lastLayoutMeasureWidth = -1
var lastLayoutMeasureHeight = -1;
private var lastLayoutMeasureWidth = -1
private var lastLayoutMeasureHeight = -1

fun createWindow() {
touchUtils = TouchUtils(context, config)
if (getToken() == null) {
val activity = if (context is Activity) context else LifecycleUtils.getTopActivity()
activity?.findViewById<View>(android.R.id.content)?.post {
createWindowInner()
}
} else {
createWindowInner()
}
fun createWindow(): Boolean = if (getToken() == null) {
val activity = if (context is Activity) context else LifecycleUtils.getTopActivity()
activity?.findViewById<View>(android.R.id.content)?.post { createWindowInner() } ?: false
} else {
createWindowInner()
}

private fun createWindowInner() {
try {
initParams()
addView()
config.isShow = true
} catch (e: Exception) {
config.callbacks?.createdResult(false, "$e", null)
config.floatCallbacks?.builder?.createdResult?.invoke(false, "$e", null)
}
private fun createWindowInner(): Boolean = try {
touchUtils = TouchUtils(context, config)
initParams()
addView()
config.isShow = true
true
} catch (e: Exception) {
config.callbacks?.createdResult(false, "$e", null)
config.floatCallbacks?.builder?.createdResult?.invoke(false, "$e", null)
false
}

private fun initParams() {
@@ -111,8 +106,8 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi
frameLayout = ParentFrameLayout(context, config)
frameLayout?.tag = config.floatTag
// 将浮窗布局文件添加到父容器frameLayout中,并返回该浮窗文件
val floatingView =
LayoutInflater.from(context).inflate(config.layoutId!!, frameLayout, true)
val floatingView = config.layoutView?.also { frameLayout?.addView(it) }
?: LayoutInflater.from(context).inflate(config.layoutId!!, frameLayout, true)
// 为了避免创建的时候闪一下,我们先隐藏视图,不能直接设置GONE,否则定位会出现问题
floatingView.visibility = View.INVISIBLE
// 将frameLayout添加到系统windowManager中
@@ -149,11 +144,19 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi
}
}

// 监听frameLayout布局完成
setChangedListener()
}

/**
* 设置布局变化监听,根据变化时的对齐方式,设置浮窗位置
*/
private fun setChangedListener() {
frameLayout?.apply {
// 监听frameLayout布局完成
viewTreeObserver?.addOnGlobalLayoutListener {
val filterInvalidVal = lastLayoutMeasureWidth == -1 || lastLayoutMeasureHeight == -1
val filterEqualVal = lastLayoutMeasureWidth == this.measuredWidth && lastLayoutMeasureHeight == this.measuredHeight
val filterEqualVal =
lastLayoutMeasureWidth == this.measuredWidth && lastLayoutMeasureHeight == this.measuredHeight
if (filterInvalidVal || filterEqualVal) {
return@addOnGlobalLayoutListener
}
@@ -166,8 +169,9 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi
val diffChangedSize = this.measuredWidth - lastLayoutMeasureWidth
params.x = params.x - diffChangedSize

} else if (config.layoutChangedGravity.and(Gravity.CENTER_HORIZONTAL) == Gravity.CENTER_HORIZONTAL ||
config.layoutChangedGravity.and(Gravity.CENTER) == Gravity.CENTER) {
} else if (config.layoutChangedGravity.and(Gravity.CENTER_HORIZONTAL) == Gravity.CENTER_HORIZONTAL
|| config.layoutChangedGravity.and(Gravity.CENTER) == Gravity.CENTER
) {
val diffChangedCenter = lastLayoutMeasureWidth / 2 - this.measuredWidth / 2
params.x += diffChangedCenter
}
@@ -180,8 +184,9 @@ internal class FloatingWindowHelper(val context: Context, var config: FloatConfi
val diffChangedSize = this.measuredHeight - lastLayoutMeasureHeight
params.y = params.y - diffChangedSize

} else if (config.layoutChangedGravity.and(Gravity.CENTER_VERTICAL) == Gravity.CENTER_VERTICAL ||
config.layoutChangedGravity.and(Gravity.CENTER) == Gravity.CENTER) {
} else if (config.layoutChangedGravity.and(Gravity.CENTER_VERTICAL) == Gravity.CENTER_VERTICAL
|| config.layoutChangedGravity.and(Gravity.CENTER) == Gravity.CENTER
) {
val diffChangedCenter = lastLayoutMeasureHeight / 2 - this.measuredHeight / 2
params.y += diffChangedCenter
}
Original file line number Diff line number Diff line change
@@ -21,13 +21,16 @@ internal object FloatingWindowManager {
* 创建浮窗,tag不存在创建,tag存在创建失败
* 创建结果通过tag添加到相应的map进行管理
*/
fun create(context: Context, config: FloatConfig) = if (!checkTag(config)) {
windowMap[config.floatTag!!] =
FloatingWindowHelper(context, config).apply { createWindow() }
} else {
// 存在相同的tag,直接创建失败
config.callbacks?.createdResult(false, WARN_REPEATED_TAG, null)
Logger.w(WARN_REPEATED_TAG)
fun create(context: Context, config: FloatConfig) {
if (!checkTag(config)) {
val helper = FloatingWindowHelper(context, config)
if (helper.createWindow()) windowMap[config.floatTag!!] = helper
} else {
// 存在相同的tag,直接创建失败
config.callbacks?.createdResult(false, WARN_REPEATED_TAG, null)
config.floatCallbacks?.builder?.createdResult?.invoke(false, WARN_REPEATED_TAG, null)
Logger.w(WARN_REPEATED_TAG)
}
}

/**
12 changes: 8 additions & 4 deletions easyfloat/src/main/java/com/lzf/easyfloat/utils/DisplayUtils.kt
Original file line number Diff line number Diff line change
@@ -44,10 +44,14 @@ object DisplayUtils {
* 获取屏幕宽度(显示宽度,横屏的时候可能会小于物理像素值)
*/
fun getScreenWidth(context: Context): Int {
val windowManager = context.getSystemService(Service.WINDOW_SERVICE) as WindowManager
val outMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(outMetrics)
return outMetrics.widthPixels
val manager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val metrics = DisplayMetrics()
manager.defaultDisplay.getRealMetrics(metrics)
return if (context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
metrics.widthPixels
} else {
metrics.widthPixels - getNavigationBarCurrentHeight(context)
}
}

/**
Binary file modified example/release/EasyFloat.apk
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -13,20 +13,25 @@ import com.lzf.easyfloat.enums.SidePattern
import com.lzf.easyfloat.example.R
import com.lzf.easyfloat.example.logger
import com.lzf.easyfloat.example.startActivity
import com.lzf.easyfloat.example.widget.RoundProgressBar
import com.lzf.easyfloat.example.widget.ScaleImage
import com.lzf.easyfloat.example.widget.*
import com.lzf.easyfloat.interfaces.OnPermissionResult
import com.lzf.easyfloat.interfaces.OnTouchRangeListener
import com.lzf.easyfloat.permission.PermissionUtils
import com.lzf.easyfloat.utils.DragUtils
import com.lzf.easyfloat.widget.BaseSwitchView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.float_seekbar.*
import kotlin.math.max


class MainActivity : BaseActivity(), View.OnClickListener {

companion object {
private const val TAG_1 = "TAG_1"
private const val TAG_2 = "TAG_2"
private const val TAG_3 = "TAG_3"
private const val TAG_4 = "TAG_4"
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
@@ -56,31 +61,31 @@ class MainActivity : BaseActivity(), View.OnClickListener {
openBorderTest.setOnClickListener(this)

// 测试activity中onCreate就启动浮框
// showActivity2()
// showActivity2()
}

override fun onClick(v: View?) {
when (v) {
open1 -> showActivityFloat()
hide1 -> EasyFloat.hide("showActivityFloat")
show1 -> EasyFloat.show("showActivityFloat")
dismiss1 -> EasyFloat.dismiss("showActivityFloat")
open1 -> showActivityFloat(TAG_1)
hide1 -> EasyFloat.hide(TAG_1)
show1 -> EasyFloat.show(TAG_1)
dismiss1 -> EasyFloat.dismiss(TAG_1)

open2 -> showActivity2()
hide2 -> EasyFloat.hide("seekBar")
show2 -> EasyFloat.show("seekBar")
dismiss2 -> EasyFloat.dismiss("seekBar")
open2 -> showActivity2(TAG_2)
hide2 -> EasyFloat.hide(TAG_2)
show2 -> EasyFloat.show(TAG_2)
dismiss2 -> EasyFloat.dismiss(TAG_2)

// 检测权限根据需求考虑有无即可,权限申请为内部进行
open3 -> checkPermission()
hide3 -> EasyFloat.hide()
show3 -> EasyFloat.show()
dismiss3 -> EasyFloat.dismiss()

open4 -> checkPermission("scaleFloat")
hide4 -> EasyFloat.hide("scaleFloat")
show4 -> EasyFloat.show("scaleFloat")
dismiss4 -> EasyFloat.dismiss("scaleFloat")
open4 -> checkPermission(TAG_4)
hide4 -> EasyFloat.hide(TAG_4)
show4 -> EasyFloat.show(TAG_4)
dismiss4 -> EasyFloat.dismiss(TAG_4)

openSecond -> startActivity<SecondActivity>(this)
openSwipeTest -> startActivity<SwipeTestActivity>(this)
@@ -94,15 +99,16 @@ class MainActivity : BaseActivity(), View.OnClickListener {
* 测试Callback回调
*/
@SuppressLint("SetTextI18n")
private fun showActivityFloat(tag: String = "showActivityFloat") {
private fun showActivityFloat(tag: String) {
EasyFloat.with(this)
.setSidePattern(SidePattern.RESULT_HORIZONTAL)
.setImmersionStatusBar(true)
.setGravity(Gravity.END, 0, 10)
.setLayout(R.layout.float_custom) {
// 传入View,传入布局文件皆可,如:MyCustomView(this)、R.layout.float_custom
.setLayout(MyCustomView(this)) {
it.findViewById<TextView>(R.id.textView).setOnClickListener { toast() }
}
.setTag(tag)
.setTag(TAG_1)
.registerCallback {
// 在此处设置view也可以,建议在setLayout进行view操作
createResult { isCreated, msg, _ ->
@@ -153,17 +159,15 @@ class MainActivity : BaseActivity(), View.OnClickListener {
.show()
}

private fun showActivity2(tag: String = "seekBar") {
private fun showActivity2(tag: String) {
// 改变浮窗1的文字
EasyFloat.getFloatView("showActivityFloat")?.findViewById<TextView>(R.id.textView)?.text =
"欢迎浮窗2"
EasyFloat.getFloatView(TAG_1)?.findViewById<TextView>(R.id.textView)?.text = "😆😆😆"

EasyFloat.with(this)
.setTag(tag)
.setGravity(Gravity.CENTER)
.setLayoutChangedGravity(Gravity.END)
.setLayout(R.layout.float_seekbar) {
val layoutContent = it.findViewById<View>(R.id.layoutContent);
it.findViewById<ImageView>(R.id.ivClose).setOnClickListener {
EasyFloat.dismiss(tag)
}
@@ -182,9 +186,11 @@ class MainActivity : BaseActivity(), View.OnClickListener {

override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
it.findViewById<TextView>(R.id.viewOther).setOnClickListener { otherView->
if (layoutContent.visibility == View.VISIBLE) layoutContent.visibility = View.GONE
else layoutContent.visibility = View.VISIBLE

val layoutContent = it.findViewById<View>(R.id.layoutContent)
it.findViewById<TextView>(R.id.viewOther).setOnClickListener {
layoutContent.visibility =
if (layoutContent.visibility == View.VISIBLE) View.GONE else View.VISIBLE
}
}
.show()
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.lzf.easyfloat.example.widget

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.lzf.easyfloat.example.R

/**
* @author: Liuzhenfeng
* @date: 2021/7/14 20:19
* @Package: com.lzf.easyfloat.example.widget
* @Description:
*/
class MyCustomView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

init {
(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?)
?.inflate(R.layout.float_custom, this)
}

}
Loading

0 comments on commit ea2b455

Please sign in to comment.