Skip to content

Commit

Permalink
Merge pull request #128 from Petterpx/perf_fx_view
Browse files Browse the repository at this point in the history
perf:优化fxView的封装
  • Loading branch information
Petterpx authored Nov 12, 2023
2 parents 89e6bb4 + 63ad0be commit f069faf
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class MainActivity : AppCompatActivity() {

private val activityFx by createFx {
setLayout(R.layout.item_floating)
setEnableLog(true, "act")
build().toControl(this@MainActivity)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.petterp.floatingx.app.test

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.petterp.floatingx.FloatingX
import com.petterp.floatingx.app.addItemView
import com.petterp.floatingx.app.addTextView
import com.petterp.floatingx.app.createLinearLayoutToParent

Expand All @@ -14,6 +16,9 @@ class BlackActivity : AppCompatActivity() {
text = "我是黑名单页面"
textSize = 50f
}
addItemView("显示全局悬浮窗") {
FloatingX.control(MultipleFxActivity.TAG_1).show(this@BlackActivity)
}
}
}
}
65 changes: 13 additions & 52 deletions check/detekt/baseline.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" ?>
<SmellBaseline>
<ManuallySuppressedIssues>
<ID>MaxLineLength:FxManagerView.kt$FxManagerView$helper.fxLog?.d("fxView--lifecycle-> onConfigurationChanged--saveLocation:[${x.roundToInt()},${y.roundToInt()}]")</ID>
<ID>MaxLineLength:FxManagerView.kt$FxManagerView$helper.fxLog?.d("fxView--lifecycle-&gt; onConfigurationChanged--saveLocation:[${x.roundToInt()},${y.roundToInt()}]")</ID>
<ID>TooManyFunctions:FxScreenExt.kt$com.petterp.floatingx.util.FxScreenExt.kt</ID>
<ID>TooGenericExceptionCaught:FxUiExt.kt$e: Exception</ID>
<ID>PrintStackTrace:FxUiExt.kt$e</ID>
Expand All @@ -10,78 +10,39 @@
<ID>SwallowedException:FxUiExt.kt$e: Exception</ID>
<ID>MagicNumber:FxScreenExt.kt$10</ID>
<ID>TooManyFunctions:IFxRunControl.kt$IFxRunControl</ID>
<ID>MaxLineLength:FxManagerView.kt$FxManagerView$"fxView->updateContainerSize: oldW-($mParentWidth),oldH-($mParentHeight),newW-($parentWidth),newH-($parentHeight)"</ID>
<ID>MaxLineLength:FxManagerView.kt$FxManagerView$"fxView-&gt;updateContainerSize: oldW-($mParentWidth),oldH-($mParentHeight),newW-($parentWidth),newH-($parentHeight)"</ID>
<ID>TooManyFunctions:AppHelper.kt$AppHelper$Builder : Builder</ID>
</ManuallySuppressedIssues>
<CurrentIssues>
<ID>ComplexCondition:FxManagerView.kt$FxManagerView$eventX >= 0 &amp;&amp; eventX &lt;= width &amp;&amp; eventY >= 0 &amp;&amp; eventY &lt;= height</ID>
<ID>ComplexCondition:FxManagerView.kt$FxManagerView$helper.enableClickListener &amp;&amp; isClickEnable &amp;&amp; helper.iFxClickListener != null &amp;&amp; isOnClickEvent()</ID>
<ID>EmptyFunctionBlock:CustomKtApplication.kt$CustomKtApplication.Companion.&lt;no name provided>${ }</ID>
<ID>EmptyFunctionBlock:FxScrollImpl.kt$FxScrollImpl${ }</ID>
<ID>EmptyFunctionBlock:FxScrollImpl.kt$FxScrollImpl${}</ID>
<ID>EmptyFunctionBlock:FxTagActivityLifecycleImpl.kt$FxTagActivityLifecycleImpl${}</ID>
<ID>LongMethod:MainActivity.kt$MainActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
<ID>LongMethod:ScopeActivity.kt$ScopeActivity$@SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?)</ID>
<ID>MagicNumber:BasisHelper.kt$BasisHelper$300L</ID>
<ID>MagicNumber:BasisHelper.kt$BasisHelper.Builder$300L</ID>
<ID>MagicNumber:BlackActivity.kt$BlackActivity$50f</ID>
<ID>MagicNumber:CustomKtApplication.kt$CustomKtApplication.Companion$10f</ID>
<ID>MagicNumber:CustomKtApplication.kt$CustomKtApplication.Companion$15f</ID>
<ID>MagicNumber:CustomKtApplication.kt$CustomKtApplication.Companion$50f</ID>
<ID>MagicNumber:FxAnimationImpl.kt$FxAnimationImpl$0.85f</ID>
<ID>MagicNumber:FxAnimationImpl.kt$FxAnimationImpl$0.95f</ID>
<ID>MagicNumber:FxAnimationImpl.kt$FxAnimationImpl$0.9f</ID>
<ID>MagicNumber:MainActivity.kt$MainActivity$10</ID>
<ID>MagicNumber:MainActivity.kt$MainActivity$15f</ID>
<ID>MagicNumber:MainActivity.kt$MainActivity$300</ID>
<ID>MagicNumber:MainActivity.kt$MainActivity$50</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$10</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$100f</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$15f</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$19f</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$20</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$40f</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$50</ID>
<ID>MagicNumber:ScopeActivity.kt$ScopeActivity$600</ID>
<ID>MagicNumber:ScreenExt.kt$10</ID>
<ID>MagicNumber:utils.kt$2</ID>
<ID>MagicNumber:FxScreenExt.kt$10</ID>
<ID>MaxLineLength:FxAppControlImpl.kt$FxAppControlImpl$throw IllegalArgumentException("view.context != Application,The global floating window must use application as context!")</ID>
<ID>MaxLineLength:FxBasisControlImpl.kt$FxBasisControlImpl$if (getContainerGroup() == null) throw NullPointerException("FloatingX window The parent container cannot be null!")</ID>
<ID>MaxLineLength:FxBasisControlImpl.kt$FxBasisControlImpl$if (helper.layoutId == 0 &amp;&amp; helper.layoutView == null) throw RuntimeException("The layout id cannot be 0 ,and layoutView==null")</ID>
<ID>MaxLineLength:FxManagerView.kt$FxManagerView$helper.fxLog?.d("fxView->updateContainerSize: oldW-($mParentWidth),oldH-($mParentHeight),newW-($parentWidth),newH-($parentHeight)")</ID>
<ID>MaxLineLength:FxProxyLifecycleCallBackImpl.kt$FxProxyLifecycleCallBackImpl$fxLog?.d("fxApp->detach? isContainActivity-${activity.isActivityInValid}--enableFx-$enableFx---isParent-$isParent")</ID>
<ID>MaxLineLength:FxProxyLifecycleCallBackImpl.kt$FxProxyLifecycleCallBackImpl$fxLog?.d("fxApp-&gt;detach? isContainActivity-${activity.isActivityInValid}--enableFx-$enableFx---isParent-$isParent")</ID>
<ID>MaxLineLength:FxScopeControl.kt$FxScopeControl$throw IllegalArgumentException("view == Application,Scope floating windows cannot use application-level views!")</ID>
<ID>MaxLineLength:MainActivity.kt$MainActivity$val</ID>
<ID>MaxLineLength:utils.kt$get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, toFloat(), Resources.getSystem().displayMetrics).toInt()</ID>
<ID>NewLineAtEndOfFile:utils.kt$com.petterp.floatingx.app.utils.kt</ID>
<ID>PrintStackTrace:ScreenExt.kt$e</ID>
<ID>PrintStackTrace:UiExt.kt$e</ID>
<ID>ReturnCount:FxExt.kt$@JvmSynthetic internal fun Float.coerceInFx(min: Float, max: Float): Float</ID>
<ID>ReturnCount:FxManagerView.kt$FxManagerView$private fun updateWidgetSize(): Boolean</ID>
<ID>ReturnCount:FxProxyLifecycleCallBackImpl.kt$FxProxyLifecycleCallBackImpl$override fun onActivityResumed(activity: Activity)</ID>
<ID>ReturnCount:ScreenExt.kt$private fun getNavigationFromAndroid(activity: Activity): Pair&lt;Int, Int></ID>
<ID>ReturnCount:ScreenExt.kt$private fun isNavBarVendorHide(context: Context): Int</ID>
<ID>SwallowedException:ScreenExt.kt$e: Exception</ID>
<ID>TooGenericExceptionCaught:ScreenExt.kt$e: Exception</ID>
<ID>TooGenericExceptionCaught:UiExt.kt$e: Exception</ID>
<ID>MaxLineLength:FxViewConfigHelper.kt$FxViewConfigHelper$helper.fxLog?.d("fxView-&gt;updateContainerSize: oldW-($mParentWidth),oldH-($mParentHeight),newW-($parentWidth),newH-($parentHeight)")</ID>
<ID>SwallowedException:FxScreenExt.kt$e: Exception</ID>
<ID>TooGenericExceptionCaught:FxScreenExt.kt$e: Exception</ID>
<ID>TooGenericExceptionThrown:FxBasisControlImpl.kt$FxBasisControlImpl$throw RuntimeException("The layout id cannot be 0 ,and layoutView==null")</ID>
<ID>TooManyFunctions:BasisHelper.kt$BasisHelper$Builder&lt;T, B : BasisHelper></ID>
<ID>TooManyFunctions:AppHelper.kt$AppHelper$Builder : Builder</ID>
<ID>TooManyFunctions:BasisHelper.kt$BasisHelper$Builder&lt;T, B : BasisHelper&gt;</ID>
<ID>TooManyFunctions:FloatingX.kt$FloatingX</ID>
<ID>TooManyFunctions:FxAppControlImpl.kt$FxAppControlImpl : FxBasisControlImplIFxAppControlActivityLifecycleCallbacks</ID>
<ID>TooManyFunctions:FxBasisControlImpl.kt$FxBasisControlImpl : IFxControlIFxConfigControl</ID>
<ID>TooManyFunctions:FxManagerView.kt$FxManagerView : FrameLayout</ID>
<ID>TooManyFunctions:FxManagerView.kt$FxManagerView : FrameLayoutOnLayoutChangeListener</ID>
<ID>TooManyFunctions:FxScreenExt.kt$com.petterp.floatingx.util.FxScreenExt.kt</ID>
<ID>TooManyFunctions:FxViewConfigHelper.kt$FxViewConfigHelper</ID>
<ID>TooManyFunctions:FxViewHolder.kt$FxViewHolder</ID>
<ID>TooManyFunctions:IFxConfigControl.kt$IFxConfigControl</ID>
<ID>TooManyFunctions:IFxControl.kt$IFxControl</ID>
<ID>TooManyFunctions:ScreenExt.kt$com.petterp.floatingx.util.ScreenExt.kt</ID>
<ID>UnusedPrivateMember:BasisHelper.kt$BasisHelper.Builder$private var enableDefaultSave: Boolean = false</ID>
<ID>UnusedPrivateMember:ScopeActivity.kt$ScopeActivity$private val activityFx by createFx { setLayout(R.layout.item_floating) setEnableScrollOutsideScreen(false) setEnableEdgeAdsorption(false) setEdgeOffset(40f) setBottomBorderMargin(40f) setAnimationImpl(FxAnimationImpl()) setEnableAnimation(false) setEnableLog(true) build().toControl(this@ScopeActivity) }</ID>
<ID>UseRequire:AppHelper.kt$AppHelper.Builder$throw IllegalArgumentException("浮窗 tag 不能为 [\"\"],请设置一个合法的tag")</ID>
<ID>UseRequire:FxAppControlImpl.kt$FxAppControlImpl$throw IllegalArgumentException("view.context != Application,The global floating window must use application as context!")</ID>
<ID>UseRequire:FxBasisControlImpl.kt$FxBasisControlImpl$throw IllegalArgumentException("resource cannot be 0!")</ID>
<ID>UseRequire:FxScopeControl.kt$FxScopeControl$throw IllegalArgumentException("view == Application,Scope floating windows cannot use application-level views!")</ID>
<ID>WildcardImport:BasisHelper.kt$import com.petterp.floatingx.assist.*</ID>
<ID>WildcardImport:CustomKtApplication.kt$import com.petterp.floatingx.app.*</ID>
<ID>WildcardImport:ScopeActivity.kt$import android.widget.*</ID>
</CurrentIssues>
</SmellBaseline>
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ class AppHelper(
fxLog?.v("system-> statusBarHeight-$statsBarHeight")
}

@JvmSynthetic
internal fun isCanInstall(act: Activity): Boolean {
return isCanInstall(act.javaClass)
}

@JvmSynthetic
internal fun isCanInstall(cls: Class<*>): Boolean {
return (isAllInstall && !blackFilterList.contains(cls)) ||
(!isAllInstall && whiteInsertList.contains(cls))
}

class Builder : BasisHelper.Builder<Builder, AppHelper>() {
private var whiteInsertList: MutableList<Class<*>> = mutableListOf()
private var blackFilterList: MutableList<Class<*>> = mutableListOf()
Expand Down Expand Up @@ -142,7 +153,7 @@ class AppHelper(
blackFilterList,
whiteInsertList,
isEnableAllInstall,
fxLifecycleExpand
fxLifecycleExpand,
)

override fun build(): AppHelper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class FxAppControlImpl(
}

override fun show(activity: Activity) {
if (isShow()) return
if (!helper.isCanInstall(activity) || isShow()) return
if (attach(activity)) {
getManagerView()?.show()
updateEnableStatus(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class FxLifecycleCallbackImpl : Application.ActivityLifecycleCallbacks {

@JvmSynthetic
internal fun updateTopActivity(activity: Activity?) {
if (activity == null) return
if (activity == null || topActivity?.get() === activity) return
topActivity = WeakReference(activity)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class FxProxyLifecycleCallBackImpl : Application.ActivityLifecycleCallbacks {

private val Activity.isActivityInValid: Boolean
get() {
val cls = this::class.java
val cls = this.javaClass
return insertCls[cls] ?: isInsertActivity(cls)
}

Expand All @@ -52,8 +52,8 @@ class FxProxyLifecycleCallBackImpl : Application.ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
if (!enableFx) return
appLifecycleCallBack?.let {
if (activity.isActivityInValid) it.onCreated(activity, savedInstanceState)
if (appLifecycleCallBack != null && activity.isActivityInValid) {
appLifecycleCallBack?.onCreated(activity, savedInstanceState)
}
}

Expand All @@ -68,8 +68,9 @@ class FxProxyLifecycleCallBackImpl : Application.ActivityLifecycleCallbacks {
val activityName = activity.name
fxLog?.d("fxApp->insert, insert [$activityName] Start ---------->")
val isActivityInValid = activity.isActivityInValid
if (isActivityInValid) appLifecycleCallBack?.onResumes(activity)
else {
if (isActivityInValid) {
appLifecycleCallBack?.onResumes(activity)
} else {
fxLog?.d("fxApp->insert, insert [$activityName] Fail ,This activity is not in the list of allowed inserts.")
return
}
Expand Down Expand Up @@ -118,9 +119,8 @@ class FxProxyLifecycleCallBackImpl : Application.ActivityLifecycleCallbacks {
private fun isInsertActivity(cls: Class<*>): Boolean =
helper?.let {
// 条件 允许全局安装&&不在黑名单 || 禁止全局安装&&在白名单
val isInsert = (it.isAllInstall && !it.blackFilterList.contains(cls)) ||
(!it.isAllInstall && it.whiteInsertList.contains(cls))
val isInsert = it.isCanInstall(cls)
insertCls[cls] = isInsert
return isInsert
isInsert
} ?: false
}
20 changes: 20 additions & 0 deletions floatingx/src/main/java/com/petterp/floatingx/util/FxExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.petterp.floatingx.util
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.view.MotionEvent
import com.petterp.floatingx.assist.helper.ScopeHelper
import java.lang.Exception

@JvmSynthetic
internal const val FX_GRAVITY_TOP = 0x00000001
Expand All @@ -14,6 +16,13 @@ internal const val FX_GRAVITY_CENTER = 0x00000002
@JvmSynthetic
internal const val FX_GRAVITY_BOTTOM = 0x00000003

internal const val TOUCH_CLICK_OFFSET = 2F
internal const val TOUCH_TIME_THRESHOLD = 150L
internal const val INVALID_TOUCH_ID = -1
internal const val INVALID_LAYOUT_ID = 0
internal const val INVALID_TOUCH_IDX = -1
internal const val DEFAULT_MOVE_ANIMATOR_DURATION = 200L

/**
* 创建一个fx,自行初始化并控制插入位置
*
Expand Down Expand Up @@ -47,6 +56,17 @@ internal fun Float.coerceInFx(min: Float, max: Float): Float {
return this
}

internal fun Float.withIn(min: Number, max: Number): Boolean {
return this in min.toFloat()..max.toFloat()
}

internal val MotionEvent.pointerId: Int
get() = try {
getPointerId(actionIndex)
} catch (_: Exception) {
INVALID_TOUCH_ID
}

@JvmSynthetic
internal fun Context.findActivity(): Activity? {
return when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.petterp.floatingx.view

import androidx.annotation.Keep
import com.petterp.floatingx.assist.helper.BasisHelper
import com.petterp.floatingx.util.TOUCH_CLICK_OFFSET
import com.petterp.floatingx.util.TOUCH_TIME_THRESHOLD
import kotlin.math.abs

/**
Expand Down Expand Up @@ -31,8 +33,8 @@ class FxClickHelper {

fun checkClickEvent(x: Float, y: Float) {
if (!isClickEvent) return
isClickEvent = abs(x - initX) < FxManagerView.TOUCH_CLICK_OFFSET &&
abs(y - initY) < FxManagerView.TOUCH_CLICK_OFFSET
isClickEvent = abs(x - initX) < TOUCH_CLICK_OFFSET &&
abs(y - initY) < TOUCH_CLICK_OFFSET
}

@Keep
Expand All @@ -56,7 +58,7 @@ class FxClickHelper {

private fun isClickEffective(): Boolean {
return isClickEvent && clickEnable && helper.enableClickListener &&
helper.iFxClickListener != null &&
System.currentTimeMillis() - mLastTouchDownTime < FxManagerView.TOUCH_TIME_THRESHOLD
helper.iFxClickListener != null &&
System.currentTimeMillis() - mLastTouchDownTime < TOUCH_TIME_THRESHOLD
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import com.petterp.floatingx.util.coerceInFx
* Fx location restore helper,Used to restore the location of the floating window after the screen is rotated
* @author petterp
*/
class FxLocationRestoreHelper {
class FxLocationHelper {
private lateinit var config: BasisHelper
private var screenW = 0
private var screenH = 0
private var x: Float = 0f
private var y: Float = 0f
private var isNearestLeft = false
private var enableEdgeAdsorption = false
private var screenChanged: Boolean = false
private var isInitLocation = true

fun initConfig(config: BasisHelper) {
this.config = config
}

/**
* Whether to restore the position
* */
Expand All @@ -37,14 +41,11 @@ class FxLocationRestoreHelper {
fun saveLocation(
x: Float,
y: Float,
parentW: Float,
config: BasisHelper
): FxLocationRestoreHelper {
configHelper: FxViewConfigHelper,
): FxLocationHelper {
this.x = x
this.y = y
val middle = parentW / 2
isNearestLeft = x < middle
this.enableEdgeAdsorption = config.enableEdgeAdsorption
isNearestLeft = configHelper.isNearestLeft(x)
return this
}

Expand All @@ -66,15 +67,15 @@ class FxLocationRestoreHelper {
}

/** get location config */
fun getLocation(minW: Float, maxW: Float, minH: Float, maxH: Float): Pair<Float, Float> {
val newX = getX(minW, maxW)
val newY = getY(minH, maxH)
fun getLocation(viewConfig: FxViewConfigHelper): Pair<Float, Float> {
val newX = getX(viewConfig.minWBoundary, viewConfig.minWBoundary)
val newY = getY(viewConfig.minHBoundary, viewConfig.maxHBoundary)
this.screenChanged = false
return newX to newY
}

private fun getX(min: Float, max: Float): Float {
return if (enableEdgeAdsorption) {
return if (config.enableEdgeAdsorption) {
if (isNearestLeft) min else max
} else {
x.coerceInFx(min, max)
Expand Down
Loading

0 comments on commit f069faf

Please sign in to comment.