From 8f29ffc83413933c312985a9ef4d4ea027f2c66d Mon Sep 17 00:00:00 2001 From: Fitz Date: Fri, 9 Sep 2022 16:00:10 +0800 Subject: [PATCH 01/12] =?UTF-8?q?:art:=20=E3=80=90=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E3=80=91=E9=AA=A8=E6=9E=B6=E5=B1=8F=E6=96=B0=E5=A2=9E=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8CSkeleton.suppressLayout(true)=20=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E8=AE=BE=E7=BD=AE=E5=9C=A8=E5=B1=95=E7=A4=BA=E6=97=B6?= =?UTF-8?q?=E9=98=BB=E6=AD=A2=20RV=20=E6=BB=91=E5=8A=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/yifeiyuan/flap/skeleton/Skeleton.kt | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/flap/src/main/java/me/yifeiyuan/flap/skeleton/Skeleton.kt b/flap/src/main/java/me/yifeiyuan/flap/skeleton/Skeleton.kt index 028c2feb..d42c35f6 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/skeleton/Skeleton.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/skeleton/Skeleton.kt @@ -48,6 +48,12 @@ class Skeleton : OnAdapterDataChangedObserver() { */ var hasShown = false + /** + * true : 在展示 skeleton 的时候不可以滑动 RV + * true to suppress layout and scroll, false to re-enable. + */ + var suppressLayout = false + /** * EmptyViewHelper 基于 Adapter 而 Skeleton 会动态切换 Adapter,导致 EmptyViewHelper 判断失败; * 所以如果使用了 EmptyViewHelper 就一定要设置; @@ -67,22 +73,18 @@ class Skeleton : OnAdapterDataChangedObserver() { fun layout(@LayoutRes layoutRes: Int) = apply { skeletonAdapter.skeletonLayoutRes = layoutRes - } fun layouts(layouts: ((position: Int) -> Int)) = apply { skeletonAdapter.multiSkeletonLayoutRes = layouts - } fun count(count: Int) = apply { skeletonAdapter.skeletonItemCount = count - } fun shimmer(enable: Boolean) = apply { skeletonAdapter.shimmer = enable - } fun autoHide(autoHide: Boolean) = apply { @@ -90,12 +92,10 @@ class Skeleton : OnAdapterDataChangedObserver() { if (autoHide) { targetAdapter.registerAdapterDataObserver(this) } - } fun withEmptyViewHelper(emptyViewHelper: EmptyViewHelper) = apply { this.emptyViewHelper = emptyViewHelper - } /**只展示一次*/ @@ -103,12 +103,16 @@ class Skeleton : OnAdapterDataChangedObserver() { this.onlyOnce = onlyOnce } + fun suppressLayout(suppressLayout: Boolean) = apply { + this.suppressLayout = suppressLayout + } + fun show() = apply { if (skeletonAdapter.skeletonItemCount < 0) { - throw IllegalArgumentException("skeletonCount 不能小于 0!") + throw IllegalArgumentException("skeleton count 不能小于 0!") } if (skeletonAdapter.skeletonLayoutRes <= 0 && skeletonAdapter.multiSkeletonLayoutRes == null) { - throw IllegalArgumentException("未设置 skeletonLayoutRes 和 multiSkeletonLayoutRes !") + throw IllegalArgumentException("未设置 skeletonLayoutRes 或 multiSkeletonLayoutRes !") } if (onlyOnce && hasShown) { @@ -123,11 +127,14 @@ class Skeleton : OnAdapterDataChangedObserver() { targetRecyclerView.adapter = skeletonAdapter + if (!targetRecyclerView.isComputingLayout && suppressLayout) { + targetRecyclerView.suppressLayout(true) + } + emptyViewHelper?.attachAdapter(skeletonAdapter, true) isShowing = true hasShown = true - return this } fun hide() = apply { From 11bad86c7ea9edd0d3f65a33fb6d1544ba751106 Mon Sep 17 00:00:00 2001 From: Fitz Date: Fri, 9 Sep 2022 16:00:41 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=20Flap.init=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=9B=E4=BF=AE=E6=94=B9=E9=93=BE=E5=BC=8F?= =?UTF-8?q?=20API=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/yifeiyuan/flapdev/FlapApplication.kt | 2 +- flap/src/main/java/me/yifeiyuan/flap/Flap.kt | 13 +++++---- .../java/me/yifeiyuan/flap/FlapAdapter.kt | 29 ++++++++----------- .../flap/decoration/LinearItemDecoration.kt | 6 ++-- .../decoration/LinearSpaceItemDecoration.kt | 6 ++-- 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt index b87971c6..3d3de60d 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt @@ -48,7 +48,7 @@ class FlapApplication : MultiDexApplication() { ) //可选 - init(this@FlapApplication) + withContext(this@FlapApplication) //打开日志 setDebug(true) diff --git a/flap/src/main/java/me/yifeiyuan/flap/Flap.kt b/flap/src/main/java/me/yifeiyuan/flap/Flap.kt index 5333abf3..92ae2f29 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/Flap.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/Flap.kt @@ -36,8 +36,6 @@ object Flap : ComponentCallbacks2, IAdapterHookManager by AdapterHookManager(), internal var globalDefaultAdapterDelegate: AdapterDelegate<*, *>? = FallbackAdapterDelegate() - var applicationContext: Context? = null - override fun onTrimMemory(level: Int) { globalComponentPool.onTrimMemory(level) } @@ -50,12 +48,15 @@ object Flap : ComponentCallbacks2, IAdapterHookManager by AdapterHookManager(), globalComponentPool.onLowMemory() } - fun init(context: Context) { - applicationContext = context.applicationContext - applicationContext?.registerComponentCallbacks(this) + fun withContext(context: Context) = apply { + context.applicationContext.registerComponentCallbacks(this) + } + + fun withFallbackAdapterDelegate(fallbackAdapterDelegate: AdapterDelegate<*, *>) = apply { + globalDefaultAdapterDelegate = fallbackAdapterDelegate } - fun setDebug(debug: Boolean) { + fun setDebug(debug: Boolean) = apply { FlapDebug.isDebug = debug } diff --git a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt index b3b24b39..33d12494 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt @@ -361,9 +361,8 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 会尝试去获取 recyclerView.context 作为 LifecycleOwner * @see handleOnAttachedToRecyclerView */ - fun setLifecycleOwner(lifecycleOwner: LifecycleOwner): FlapAdapter { + fun setLifecycleOwner(lifecycleOwner: LifecycleOwner) = apply { this.lifecycleOwner = lifecycleOwner - return this } /** @@ -373,9 +372,8 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * * @param lifecycleEnable 是否开启 */ - fun setLifecycleEnable(lifecycleEnable: Boolean): FlapAdapter { + fun setLifecycleEnable(lifecycleEnable: Boolean) = apply { this.lifecycleEnable = lifecycleEnable - return this } /** @@ -386,16 +384,13 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 是否使用全局单例的 FlapComponentPool * * @param enable false by default - * @return this */ - fun enableGlobalComponentPool(enable: Boolean): FlapAdapter { + fun enableGlobalComponentPool(enable: Boolean) = apply { useGlobalComponentPool = enable - return this } - fun enableComponentPool(enable: Boolean): FlapAdapter { + fun enableComponentPool(enable: Boolean) = apply { useComponentPool = enable - return this } /** @@ -415,14 +410,14 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 观察指定 eventName 的事件 * @see fireEvent */ - fun observeEvent(eventName: String, block: (Event) -> Unit) { + fun observeEvent(eventName: String, block: (Event) -> Unit) = apply { eventObservers[eventName] = EventObserverWrapper(block) } /** * 观察所有的事件 */ - fun observerEvents(block: (Event<*>) -> Unit) { + fun observerEvents(block: (Event<*>) -> Unit) = apply { allEventsObserver = object : EventObserver { override fun onEvent(event: Event<*>) { block.invoke(event) @@ -435,7 +430,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * * @see PreloadHook */ - fun doOnPreload(offset: Int = 0, minItemCount: Int = 2, onPreload: () -> Unit) { + fun doOnPreload(offset: Int = 0, minItemCount: Int = 2, onPreload: () -> Unit) = apply { preloadHook?.let { unregisterAdapterHook(it) } @@ -448,7 +443,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 设置是否启用预加载 * 需要先调用 doOnPreload 开启才有效。 */ - fun setPreloadEnable(enable: Boolean) { + fun setPreloadEnable(enable: Boolean) = apply { preloadHook?.preloadEnable = enable } @@ -466,7 +461,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag return paramProvider?.getParam(key) as? P? } - fun setParamProvider(block: (key: String) -> Any?) { + fun setParamProvider(block: (key: String) -> Any?) = apply { paramProvider = ExtraParamsProviderWrapper(block) } @@ -483,7 +478,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 设置点击事件监听 * @see doOnItemLongClick */ - fun doOnItemClick(onItemClick: OnItemClickListener?) { + fun doOnItemClick(onItemClick: OnItemClickListener?) = apply { itemClicksHelper.onItemClickListener = onItemClick } @@ -491,11 +486,11 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag * 设置长按事件监听 * @see doOnItemClick */ - fun doOnItemLongClick(onItemLongClick: OnItemLongClickListener?) { + fun doOnItemLongClick(onItemLongClick: OnItemLongClickListener?) = apply { itemClicksHelper.onItemLongClickListener = onItemLongClick } - fun setEmptyView(emptyView: View?) { + fun setEmptyView(emptyView: View?) = apply { emptyViewHelper.emptyView = emptyView } diff --git a/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearItemDecoration.kt b/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearItemDecoration.kt index 8a92d383..02222c79 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearItemDecoration.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearItemDecoration.kt @@ -161,13 +161,11 @@ class LinearItemDecoration : RecyclerView.ItemDecoration { } } - fun withFirstItemTopEdge(enable: Boolean): LinearItemDecoration { + fun withFirstItemTopEdge(enable: Boolean) = apply { isIncludeFirstItemTopEdge = enable - return this } - fun withLastItemBottomEdge(enable: Boolean): LinearItemDecoration { + fun withLastItemBottomEdge(enable: Boolean) = apply { isIncludeLastItemBottomEdge = enable - return this } } \ No newline at end of file diff --git a/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearSpaceItemDecoration.kt b/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearSpaceItemDecoration.kt index d5eea1d0..a4c35a59 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearSpaceItemDecoration.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/decoration/LinearSpaceItemDecoration.kt @@ -74,13 +74,11 @@ class LinearSpaceItemDecoration(var space: Int, var orientation: Int = RecyclerV } } - fun withFirstItemTopEdge(enable: Boolean): LinearSpaceItemDecoration { + fun withFirstItemTopEdge(enable: Boolean)= apply { isIncludeFirstItemTopEdge = enable - return this } - fun withLastItemBottomEdge(enable: Boolean): LinearSpaceItemDecoration { + fun withLastItemBottomEdge(enable: Boolean)= apply { isIncludeLastItemBottomEdge = enable - return this } } \ No newline at end of file From 5f347894c6eaa05ed5abdd726ba153601795902a Mon Sep 17 00:00:00 2001 From: Fitz Date: Fri, 9 Sep 2022 16:05:45 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=87=E5=AE=9A=20in?= =?UTF-8?q?dex=20=E7=9A=84=E6=B3=A8=E5=86=8C=20AdapterDelegate=20=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flap/delegate/IAdapterDelegateManager.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt b/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt index b09b1007..04bd70c9 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt @@ -12,33 +12,40 @@ import androidx.annotation.NonNull */ interface IAdapterDelegateManager { - val adapterDelegates: MutableList> + val adapterDelegates: MutableList> /** * 注册单个 AdapterDelegate */ - fun registerAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*,*>){ + fun registerAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*, *>) { this.adapterDelegates.add(adapterDelegate) } + /** + * 注册单个 AdapterDelegate,并指定 index + */ + fun registerAdapterDelegate(index: Int, @NonNull adapterDelegate: AdapterDelegate<*, *>) { + this.adapterDelegates.add(index, adapterDelegate) + } + /** * 注册多个 AdapterDelegate */ - fun registerAdapterDelegates(vararg adapterDelegates: AdapterDelegate<*, *>){ + fun registerAdapterDelegates(vararg adapterDelegates: AdapterDelegate<*, *>) { this.adapterDelegates.addAll(adapterDelegates) } /** * 注销单个 AdapterDelegate */ - fun unregisterAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*,*>){ + fun unregisterAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*, *>) { this.adapterDelegates.remove(adapterDelegate) } /** * 注销所有 AdapterDelegate */ - fun clearAdapterDelegates(){ + fun clearAdapterDelegates() { adapterDelegates.clear() } } \ No newline at end of file From 1c7515864f9d74b85fb33388e34aead0eeefba47 Mon Sep 17 00:00:00 2001 From: Fitz Date: Fri, 9 Sep 2022 16:08:13 +0800 Subject: [PATCH 04/12] cleanup --- .../me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt | 8 +++----- .../java/me/yifeiyuan/flap/hook/IAdapterHookManager.kt | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt b/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt index 04bd70c9..2bec1e6f 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/delegate/IAdapterDelegateManager.kt @@ -1,7 +1,5 @@ package me.yifeiyuan.flap.delegate -import androidx.annotation.NonNull - /** * AdapterDelegate 管理者的抽象 * @@ -17,14 +15,14 @@ interface IAdapterDelegateManager { /** * 注册单个 AdapterDelegate */ - fun registerAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*, *>) { + fun registerAdapterDelegate(adapterDelegate: AdapterDelegate<*, *>) { this.adapterDelegates.add(adapterDelegate) } /** * 注册单个 AdapterDelegate,并指定 index */ - fun registerAdapterDelegate(index: Int, @NonNull adapterDelegate: AdapterDelegate<*, *>) { + fun registerAdapterDelegate(index: Int, adapterDelegate: AdapterDelegate<*, *>) { this.adapterDelegates.add(index, adapterDelegate) } @@ -38,7 +36,7 @@ interface IAdapterDelegateManager { /** * 注销单个 AdapterDelegate */ - fun unregisterAdapterDelegate(@NonNull adapterDelegate: AdapterDelegate<*, *>) { + fun unregisterAdapterDelegate(adapterDelegate: AdapterDelegate<*, *>) { this.adapterDelegates.remove(adapterDelegate) } diff --git a/flap/src/main/java/me/yifeiyuan/flap/hook/IAdapterHookManager.kt b/flap/src/main/java/me/yifeiyuan/flap/hook/IAdapterHookManager.kt index b53a19f6..2cffb2a5 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/hook/IAdapterHookManager.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/hook/IAdapterHookManager.kt @@ -13,7 +13,7 @@ interface IAdapterHookManager { val adapterHooks: MutableList - fun registerAdapterHook(@NonNull adapterHook: AdapterHook) { + fun registerAdapterHook(adapterHook: AdapterHook) { adapterHooks.add(adapterHook) } @@ -21,7 +21,7 @@ interface IAdapterHookManager { this.adapterHooks.addAll(adapterHooks) } - fun unregisterAdapterHook(@NonNull adapterHook: AdapterHook) { + fun unregisterAdapterHook(adapterHook: AdapterHook) { adapterHooks.remove(adapterHook) } From 01f09596a4f9f51cf05a5ab4934c039a8bd38b62 Mon Sep 17 00:00:00 2001 From: Fitz Date: Sun, 11 Sep 2022 10:56:39 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20IAdapterServiceManag?= =?UTF-8?q?er.registerAdapterServices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/yifeiyuan/flapdev/FlapApplication.kt | 3 +++ flap/src/main/java/me/yifeiyuan/flap/Flap.kt | 4 ++-- .../flap/service/IAdapterServiceManager.kt | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt index 3d3de60d..e5de179b 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt @@ -22,6 +22,7 @@ class FlapApplication : MultiDexApplication() { } private fun initFlap() { + Flap.apply { //Flap 这里注册的都是是全局的,只是为了测试方便 @@ -47,6 +48,8 @@ class FlapApplication : MultiDexApplication() { // ApmHook() ) + registerAdapterService(TestService::class.java) + //可选 withContext(this@FlapApplication) diff --git a/flap/src/main/java/me/yifeiyuan/flap/Flap.kt b/flap/src/main/java/me/yifeiyuan/flap/Flap.kt index 92ae2f29..c67cebb8 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/Flap.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/Flap.kt @@ -32,9 +32,9 @@ object Flap : ComponentCallbacks2, IAdapterHookManager by AdapterHookManager(), */ var inflateWithApplicationContext = false - internal val globalComponentPool = ComponentPool() + internal val globalComponentPool: ComponentPool by lazy { ComponentPool() } - internal var globalDefaultAdapterDelegate: AdapterDelegate<*, *>? = FallbackAdapterDelegate() + internal var globalDefaultAdapterDelegate: AdapterDelegate<*, *> = FallbackAdapterDelegate() override fun onTrimMemory(level: Int) { globalComponentPool.onTrimMemory(level) diff --git a/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt b/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt index eeb1f806..2559c441 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt @@ -12,7 +12,7 @@ interface IAdapterServiceManager { val adapterServices: MutableMap, AdapterService> /** - * 注册 AdapterService,并反射实例化 + * 注册 AdapterService,并调用反射进行实例化 */ fun registerAdapterService(serviceClass: Class) { try { @@ -23,6 +23,20 @@ interface IAdapterServiceManager { } } + /** + * 注册多个 AdapterService,并调用反射进行实例化 + */ + fun registerAdapterServices(vararg serviceClasses: Class) { + try { + serviceClasses.forEach { + val service = it.getConstructor().newInstance() + adapterServices[it] = service + } + } catch (e: Exception) { + e.printStackTrace() + } + } + /** * 注册 AdapterService 实例 */ From 11f66bc13d68d2f2c050821b18ba882e0db1cfc7 Mon Sep 17 00:00:00 2001 From: Fitz Date: Sun, 11 Sep 2022 11:13:54 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt | 6 ++---- .../me/yifeiyuan/flap/animation/AlphaInAdapterAnimation.kt | 2 +- flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt | 4 ++-- .../me/yifeiyuan/flap/service/IAdapterServiceManager.kt | 6 ++++-- flap/src/main/java/me/yifeiyuan/flap/skeleton/Shimmer.java | 1 + .../java/me/yifeiyuan/flap/skeleton/ShimmerFrameLayout.java | 1 + 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt index 33d12494..f0d3701a 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt @@ -1,4 +1,4 @@ -@file:Suppress("MemberVisibilityCanBePrivate", "unused") +@file:Suppress("MemberVisibilityCanBePrivate", "unused", "LeakingThis", "LeakingThis", "LeakingThis") package me.yifeiyuan.flap @@ -108,9 +108,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag adapterDelegates.addAll(Flap.adapterDelegates) adapterServices.putAll(Flap.adapterServices) - Flap.globalDefaultAdapterDelegate?.let { - defaultAdapterDelegate = it - } + defaultAdapterDelegate = Flap.globalDefaultAdapterDelegate inflateWithApplicationContext = Flap.inflateWithApplicationContext } diff --git a/flap/src/main/java/me/yifeiyuan/flap/animation/AlphaInAdapterAnimation.kt b/flap/src/main/java/me/yifeiyuan/flap/animation/AlphaInAdapterAnimation.kt index c2f36253..a88dd5e6 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/animation/AlphaInAdapterAnimation.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/animation/AlphaInAdapterAnimation.kt @@ -10,7 +10,7 @@ import me.yifeiyuan.flap.Component * * @since 3.0.7 */ -class AlphaInAdapterAnimation(var startAlpha: Float = 0f) : BaseAdapterAnimation() { +class AlphaInAdapterAnimation(private var startAlpha: Float = 0f) : BaseAdapterAnimation() { override fun createAnimator(view: View, component: Component<*>, data: Any, position: Int): Animator { return ObjectAnimator.ofFloat(view, "alpha", startAlpha, 1f) diff --git a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt index 77b9d693..d30b41d8 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt @@ -185,11 +185,11 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback if (ItemTouchHelper.ACTION_STATE_SWIPE == actionState) { swipedViewHolder = viewHolder callback.onSwipeStarted(viewHolder!!, viewHolder.adapterPosition) - onSwipeStarted?.invoke(viewHolder!!, viewHolder.adapterPosition) + onSwipeStarted?.invoke(viewHolder, viewHolder.adapterPosition) } else if (ItemTouchHelper.ACTION_STATE_DRAG == actionState) { draggedViewHolder = viewHolder callback.onDragStarted(viewHolder!!, viewHolder.adapterPosition) - onDragStarted?.invoke(viewHolder!!, viewHolder.adapterPosition) + onDragStarted?.invoke(viewHolder, viewHolder.adapterPosition) } else if (ItemTouchHelper.ACTION_STATE_IDLE == actionState) { if (draggedViewHolder != null) { callback.onDragReleased(draggedViewHolder!!, draggedViewHolder!!.adapterPosition) diff --git a/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt b/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt index 2559c441..6f7c8b26 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/service/IAdapterServiceManager.kt @@ -3,6 +3,8 @@ package me.yifeiyuan.flap.service /** * AdapterService 管理,可以注册或获取 AdapterService * + * 可以在 Activity 中注册 AdapterService,在 Component 中使用。 + * * Created by 程序亦非猿 on 2022/8/18. * * @since 3.0.3 @@ -12,7 +14,7 @@ interface IAdapterServiceManager { val adapterServices: MutableMap, AdapterService> /** - * 注册 AdapterService,并调用反射进行实例化 + * 注册 AdapterService,并反射调用无参构造器进行实例化 */ fun registerAdapterService(serviceClass: Class) { try { @@ -24,7 +26,7 @@ interface IAdapterServiceManager { } /** - * 注册多个 AdapterService,并调用反射进行实例化 + * 注册多个 AdapterService,并反射调用无参构造器进行实例化 */ fun registerAdapterServices(vararg serviceClasses: Class) { try { diff --git a/flap/src/main/java/me/yifeiyuan/flap/skeleton/Shimmer.java b/flap/src/main/java/me/yifeiyuan/flap/skeleton/Shimmer.java index b0671377..5d7310e3 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/skeleton/Shimmer.java +++ b/flap/src/main/java/me/yifeiyuan/flap/skeleton/Shimmer.java @@ -143,6 +143,7 @@ void updateBounds(int viewWidth, int viewHeight) { bounds.set(-padding, -padding, width(viewWidth) + padding, height(viewHeight) + padding); } + @SuppressWarnings({"SameParameterValue", "UnusedReturnValue"}) public abstract static class Builder> { final Shimmer mShimmer = new Shimmer(); diff --git a/flap/src/main/java/me/yifeiyuan/flap/skeleton/ShimmerFrameLayout.java b/flap/src/main/java/me/yifeiyuan/flap/skeleton/ShimmerFrameLayout.java index 01cafe77..09f619aa 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/skeleton/ShimmerFrameLayout.java +++ b/flap/src/main/java/me/yifeiyuan/flap/skeleton/ShimmerFrameLayout.java @@ -30,6 +30,7 @@ * Copy from https://github.com/facebook/shimmer-android * @since 3.0.1 */ +@SuppressWarnings("UnusedReturnValue") public class ShimmerFrameLayout extends FrameLayout { private final Paint mContentPaint = new Paint(); private final ShimmerDrawable mShimmerDrawable = new ShimmerDrawable(); From e6cbf8622ad73558983e2d5d90e905768a251762 Mon Sep 17 00:00:00 2001 From: Fitz Date: Tue, 13 Sep 2022 14:45:25 +0800 Subject: [PATCH 07/12] =?UTF-8?q?:art:=20=E5=A2=9E=E5=8A=A0=20DSL=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/yifeiyuan/flapdev/components/Banner.kt | 5 ++++ .../flapdev/components/FullFeature.kt | 5 ++++ app/src/main/res/layout/component_banner.xml | 6 ++++ .../res/layout/component_banner_image.xml | 15 ++++++++++ .../res/layout/component_full_feature.xml | 6 ++++ ...e_image.xml => component_simple_image.xml} | 0 .../yifeiyuan/flap/dsl/AdapterDelegateDsl.kt | 30 +++++++++++++++++++ 7 files changed, 67 insertions(+) create mode 100644 app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt create mode 100644 app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt create mode 100644 app/src/main/res/layout/component_banner.xml create mode 100644 app/src/main/res/layout/component_banner_image.xml create mode 100644 app/src/main/res/layout/component_full_feature.xml rename app/src/main/res/layout/{flap_item_simple_image.xml => component_simple_image.xml} (100%) diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt new file mode 100644 index 00000000..7de7a97b --- /dev/null +++ b/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt @@ -0,0 +1,5 @@ +package me.yifeiyuan.flapdev.components + +/** + * Created by 程序亦非猿 on 2022/9/11. + */ diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt new file mode 100644 index 00000000..584856ae --- /dev/null +++ b/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt @@ -0,0 +1,5 @@ +package me.yifeiyuan.flapdev.components + +/** + * Created by 程序亦非猿 on 2022/9/13. + */ diff --git a/app/src/main/res/layout/component_banner.xml b/app/src/main/res/layout/component_banner.xml new file mode 100644 index 00000000..61a4490a --- /dev/null +++ b/app/src/main/res/layout/component_banner.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/component_banner_image.xml b/app/src/main/res/layout/component_banner_image.xml new file mode 100644 index 00000000..f9dead4a --- /dev/null +++ b/app/src/main/res/layout/component_banner_image.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/component_full_feature.xml b/app/src/main/res/layout/component_full_feature.xml new file mode 100644 index 00000000..61a4490a --- /dev/null +++ b/app/src/main/res/layout/component_full_feature.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/flap_item_simple_image.xml b/app/src/main/res/layout/component_simple_image.xml similarity index 100% rename from app/src/main/res/layout/flap_item_simple_image.xml rename to app/src/main/res/layout/component_simple_image.xml diff --git a/flap/src/main/java/me/yifeiyuan/flap/dsl/AdapterDelegateDsl.kt b/flap/src/main/java/me/yifeiyuan/flap/dsl/AdapterDelegateDsl.kt index 606d24fa..c4355052 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/dsl/AdapterDelegateDsl.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/dsl/AdapterDelegateDsl.kt @@ -175,6 +175,36 @@ class DslComponent(view: View) : Component(view) { return onFailedToRecycleView?.invoke() ?: super.onFailedToRecycleView(flapAdapter) } + var swipeFlags: Int? = null + override fun getSwipeFlags(): Int { + return swipeFlags ?: super.getSwipeFlags() + } + + var dragFlags: Int? = null + override fun getDragFlags(): Int { + return dragFlags ?: super.getDragFlags() + } + + var swipeEnable: Boolean? = null + override fun isSwipeEnabled(): Boolean { + return swipeEnable ?: super.isSwipeEnabled() + } + + var dragEnable: Boolean? = null + override fun isDragEnabled(): Boolean { + return dragEnable ?: super.isDragEnabled() + } + + var clickable: Boolean? = null + override fun isClickable(): Boolean { + return clickable ?: super.isClickable() + } + + var longClickable: Boolean? = null + override fun isLongClickable(): Boolean { + return longClickable ?: super.isLongClickable() + } + fun onBind(onBind: ((model: T) -> Unit)) { this.onBind = onBind } From b42c30e6f2e1173496321dcf45aba825c2e5d66f Mon Sep 17 00:00:00 2001 From: Fitz Date: Tue, 13 Sep 2022 15:13:22 +0800 Subject: [PATCH 08/12] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=20SwipeDragHel?= =?UTF-8?q?per=20=E6=B2=A1=E6=9C=89=E6=AD=A3=E7=A1=AE=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/fullfeatures.json | 0 flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 app/src/main/assets/fullfeatures.json diff --git a/app/src/main/assets/fullfeatures.json b/app/src/main/assets/fullfeatures.json new file mode 100644 index 00000000..e69de29b diff --git a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt index d30b41d8..cac4e56c 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt @@ -77,7 +77,7 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback var finalDragFlags = if (dragFlags != FLAG_UN_SET) dragFlags else getDefaultDragFlags(recyclerView, viewHolder) if (viewHolder is ComponentConfig) { if (viewHolder.isDragEnabled()) { - finalDragFlags = if (viewHolder.getDragFlags() == FLAG_UN_SET) finalDragFlags else 0 + finalDragFlags = if (viewHolder.getDragFlags() == FLAG_UN_SET) finalDragFlags else viewHolder.getDragFlags() } else { finalDragFlags = FLAG_DISABLE } @@ -87,7 +87,7 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback if (viewHolder is ComponentConfig) { if (viewHolder.isSwipeEnabled()) { - finalSwipeFlags = if (viewHolder.getSwipeFlags() == FLAG_UN_SET) finalSwipeFlags else 0 + finalSwipeFlags = if (viewHolder.getSwipeFlags() == FLAG_UN_SET) finalSwipeFlags else viewHolder.getSwipeFlags() } else { finalSwipeFlags = FLAG_DISABLE } From 57c1fa0a78184dd0ff635665222fca8316224b84 Mon Sep 17 00:00:00 2001 From: Fitz Date: Tue, 13 Sep 2022 15:57:02 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9Component.onBind=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=8F=AF=E8=A7=81=E6=80=A7=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20Adapter.setData=20=E9=80=82=E7=94=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/fullfeatures.json | 0 .../flapdev/components/FullFeature.kt | 5 -- .../flapdev/components/TestConfig.kt | 59 +++++++++++++++++++ .../main/java/me/yifeiyuan/flap/Component.kt | 21 +++++-- .../java/me/yifeiyuan/flap/FlapAdapter.kt | 2 +- .../flap/differ/FlapDifferAdapter.kt | 5 +- 6 files changed, 80 insertions(+), 12 deletions(-) delete mode 100644 app/src/main/assets/fullfeatures.json delete mode 100644 app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt create mode 100644 app/src/main/java/me/yifeiyuan/flapdev/components/TestConfig.kt diff --git a/app/src/main/assets/fullfeatures.json b/app/src/main/assets/fullfeatures.json deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt deleted file mode 100644 index 584856ae..00000000 --- a/app/src/main/java/me/yifeiyuan/flapdev/components/FullFeature.kt +++ /dev/null @@ -1,5 +0,0 @@ -package me.yifeiyuan.flapdev.components - -/** - * Created by 程序亦非猿 on 2022/9/13. - */ diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/TestConfig.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/TestConfig.kt new file mode 100644 index 00000000..02692ba1 --- /dev/null +++ b/app/src/main/java/me/yifeiyuan/flapdev/components/TestConfig.kt @@ -0,0 +1,59 @@ +package me.yifeiyuan.flapdev.components + +import me.yifeiyuan.flap.differ.IDiffer +import me.yifeiyuan.flap.dsl.adapterDelegate +import me.yifeiyuan.flap.ext.bindTextView +import me.yifeiyuan.flapdev.R + +/** + * Created by 程序亦非猿 on 2022/9/13. + */ + +class TestConfigModel : IDiffer { + + var id: Int = -1 + var title: String? = null + var content: String? = null + + var dragEnable: Boolean = false + var swipeEnable: Boolean = false + + var swipeFlags: Int = 0 + var dragFlags: Int = 0 + + var clickEnable: Boolean = false + var longClickEnable: Boolean = false + + override fun areItemsTheSame(newItem: Any): Boolean { + return false + } + + override fun areContentsTheSame(newItem: Any): Boolean { + return false + } + + override fun getChangePayload(newItem: Any): Any? { + return super.getChangePayload(newItem) + } +} + +fun fullConfigAdapterDelegate() = adapterDelegate(R.layout.component_full_feature) { + + onBind { model, position, payloads, adapter -> + + bindTextView(R.id.title) { + text = model.title + } + + bindTextView(R.id.content) { + text = model.content + } + + swipeEnable = model.swipeEnable + dragEnable = model.dragEnable + swipeFlags = model.swipeFlags + dragFlags = model.dragFlags + clickable = model.clickEnable + longClickable = model.longClickEnable + } +} \ No newline at end of file diff --git a/flap/src/main/java/me/yifeiyuan/flap/Component.kt b/flap/src/main/java/me/yifeiyuan/flap/Component.kt index def62d7f..f32fb553 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/Component.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/Component.kt @@ -14,6 +14,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.OnLifecycleEvent import androidx.recyclerview.widget.RecyclerView import me.yifeiyuan.flap.delegate.AdapterDelegate +import java.lang.IllegalArgumentException /** * Component is used by Flap as the base ViewHolder , which provides some useful and convenient abilities as well. @@ -42,15 +43,26 @@ open class Component(itemView: View) : RecyclerView.ViewHolder(itemView), Lif * @see FlapAdapter.inflateWithApplicationContext * @see FlapAdapter.getActivityContext */ - protected val context: Context = itemView.context + val context: Context = itemView.context /** * @return true if component is visible */ protected var isVisible = false + internal var _bindingData: Any? = null + + val data: T + get() = if (_bindingData == null) { + throw IllegalArgumentException("onBind 还未调用,不可以使用 bindingData") + } else { + @Suppress("UNCHECKED_CAST") + _bindingData as T + } + @Suppress("UNCHECKED_CAST") fun bindData(model: Any, position: Int, payloads: List, adapter: FlapAdapter, delegate: AdapterDelegate<*, *>) { + _bindingData = model onBind(model as T, position, payloads, adapter, delegate) } @@ -62,7 +74,7 @@ open class Component(itemView: View) : RecyclerView.ViewHolder(itemView), Lif * @param adapter Your adapter. * @param payloads The payloads you may need. */ - open fun onBind( + protected open fun onBind( model: T, position: Int, payloads: List, @@ -77,9 +89,10 @@ open class Component(itemView: View) : RecyclerView.ViewHolder(itemView), Lif * * @see onBind */ - open fun onBind(model: T) {} + protected open fun onBind(model: T) {} - protected fun findViewById(@IdRes viewId: Int): V { + @Suppress("UNCHECKED_CAST") + fun findViewById(@IdRes viewId: Int): V { return itemView.findViewById(viewId) as V } diff --git a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt index f0d3701a..ef3fbd75 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt @@ -118,7 +118,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag data.addAll(newDataList) } - open fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean = false) { + open fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean = false) { data.clear() data.addAll(newDataList) if (notifyAll) { diff --git a/flap/src/main/java/me/yifeiyuan/flap/differ/FlapDifferAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/differ/FlapDifferAdapter.kt index 3e9a3369..e618057e 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/differ/FlapDifferAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/differ/FlapDifferAdapter.kt @@ -22,6 +22,7 @@ import java.util.* * @since 2020/9/22 * @since 3.0.0 */ +@Suppress("UNCHECKED_CAST") class FlapDifferAdapter : FlapAdapter { private val differ: AsyncListDiffer @@ -88,8 +89,8 @@ class FlapDifferAdapter : FlapAdapter { } @Deprecated(message = "请使用 submitList", replaceWith = ReplaceWith("submitList(newDataList)", "me.yifeiyuan.flap.differ.FlapDifferAdapter")) - override fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean) { - this.setData(newDataList) + override fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean) { + super.setDataAndNotify(newDataList, notifyAll) } @Deprecated(message = "请使用 submitList", replaceWith = ReplaceWith("submitList(appendDataList)", "me.yifeiyuan.flap.differ.FlapDifferAdapter")) From 0f7ebf1f3e254e534a04ae96e269366443f4356a Mon Sep 17 00:00:00 2001 From: Fitz Date: Tue, 13 Sep 2022 15:59:03 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 ++ app/src/main/AndroidManifest.xml | 2 + .../me/yifeiyuan/flapdev/FlapApplication.kt | 14 +++-- .../main/java/me/yifeiyuan/flapdev/Mocks.kt | 59 +++++++++++++++++++ .../me/yifeiyuan/flapdev/components/Banner.kt | 48 +++++++++++++++ .../components/SimpleImageComponent.kt | 17 +++++- .../flapdev/testcases/DSLTestcase.kt | 7 +-- app/src/main/res/layout/component_banner.xml | 12 +++- .../res/layout/component_full_feature.xml | 32 +++++++++- .../java/me/yifeiyuan/flap/FlapAdapter.kt | 2 +- 10 files changed, 178 insertions(+), 19 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3090d97c..e052841d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -107,4 +107,8 @@ dependencies { // kapt 'me.yifeiyuan.flap:flap-compiler:2.0.0' implementation 'jp.wasabeef:recyclerview-animators:4.0.2' +// implementation 'com.google.code.gson:gson:2.9.1' + + implementation 'com.github.bumptech.glide:glide:4.13.2' + annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6f2cda66..bc58a38e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="me.yifeiyuan.flapdev"> + + diff --git a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt index e5de179b..5bdf400d 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/FlapApplication.kt @@ -1,13 +1,11 @@ package me.yifeiyuan.flapdev +import android.app.Application import androidx.multidex.MultiDexApplication import me.yifeiyuan.flap.Flap import me.yifeiyuan.flap.apt.delegates.* -import me.yifeiyuan.flap.hook.ApmHook import me.yifeiyuan.flap.hook.LoggingHook -import me.yifeiyuan.flapdev.components.CustomViewTypeComponentDelegate -import me.yifeiyuan.flapdev.components.SimpleTextComponentDelegate -import me.yifeiyuan.flapdev.components.ZeroHeightComponent +import me.yifeiyuan.flapdev.components.* import me.yifeiyuan.flapdev.components.generictest.GenericFlapComponentDelegate /** @@ -16,8 +14,14 @@ import me.yifeiyuan.flapdev.components.generictest.GenericFlapComponentDelegate */ class FlapApplication : MultiDexApplication() { + companion object{ + + var application :Application?=null + } + override fun onCreate() { super.onCreate() + application = this initFlap() } @@ -28,6 +32,8 @@ class FlapApplication : MultiDexApplication() { //Flap 这里注册的都是是全局的,只是为了测试方便 //实际开发使用的话 哪个 Adapter 需要才注册更加合适。 registerAdapterDelegates( + fullConfigAdapterDelegate(), + bannerAdapterDelegate(), ZeroHeightComponentAdapterDelegate(), SimpleTextComponentDelegate(), SimpleImageComponentAdapterDelegate(), diff --git a/app/src/main/java/me/yifeiyuan/flapdev/Mocks.kt b/app/src/main/java/me/yifeiyuan/flapdev/Mocks.kt index 7c53fb31..5b51aa3c 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/Mocks.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/Mocks.kt @@ -1,5 +1,6 @@ package me.yifeiyuan.flapdev +import androidx.recyclerview.widget.ItemTouchHelper import me.yifeiyuan.flap.ktmodule.KtComponentModel import me.yifeiyuan.flapdev.components.* import me.yifeiyuan.flapdev.components.SimpleDataBindingModel @@ -17,6 +18,16 @@ import java.util.* */ fun mockMultiTypeModels(): MutableList { val models: MutableList = ArrayList() + + val bannerModel = BannerModel() + + bannerModel.images = mutableListOf().apply { + add(BannerImageModel().apply { resId = R.drawable.flap_ic_baicai }) + add(BannerImageModel().apply { resId = R.drawable.flap_ic_baozi }) + add(BannerImageModel().apply { resId = R.drawable.flap_ic_jd }) + } + + models.add(bannerModel) models.add(SimpleTextModel("Flap(灵动)")) models.add(SimpleTextModel("一个基于 RecyclerView 的页面组件化框架")) models.add(SimpleTextModel("—— by 程序亦非猿")) @@ -31,6 +42,54 @@ fun mockMultiTypeModels(): MutableList { models.add(KtComponentModel()) models.add(TestBinderModel()) models.add(UnknownModel()) + models.addAll(mockFullFeatureModels()) + return models +} + +fun mockFullFeatureModels(): MutableList { + val models: MutableList = ArrayList() + + val clickModel = TestConfigModel().apply { + clickEnable = true + title = "测试点击" + content = "可单击" + } + val clickModel2 = TestConfigModel().apply { + clickEnable = false + title = "测试点击" + content = "不可点击" + } + models.add(clickModel) + models.add(clickModel2) + + val longClickModel = TestConfigModel().apply { + longClickEnable = true + title = "测试长按" + content = "可长按" + } + val longClickModel2 = TestConfigModel().apply { + longClickEnable = false + title = "测试长按" + content = "不可长按" + } + models.add(longClickModel) + models.add(longClickModel2) + + val swipeModel = TestConfigModel().apply { + swipeEnable = true + title = "测试滑动删除" + content = "可从右往左滑动删除" + swipeFlags = ItemTouchHelper.LEFT + } + val swipeModel2 = TestConfigModel().apply { + swipeEnable = true + title = "测试滑动删除" + content = "可从左往右滑动删除" + swipeFlags = ItemTouchHelper.RIGHT + } + models.add(swipeModel) + models.add(swipeModel2) + return models } diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt index 7de7a97b..6249a991 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/components/Banner.kt @@ -1,5 +1,53 @@ package me.yifeiyuan.flapdev.components +import android.widget.ImageView +import androidx.viewpager2.widget.ViewPager2 +import com.bumptech.glide.Glide +import me.yifeiyuan.flap.FlapAdapter +import me.yifeiyuan.flap.dsl.adapterDelegate +import me.yifeiyuan.flapdev.R + /** * Created by 程序亦非猿 on 2022/9/11. */ + +class BannerModel { + var images: MutableList? = null +} + +class BannerImageModel { + var url: String? = null + var resId: Int = 0 +} + +fun bannerAdapterDelegate() = adapterDelegate(R.layout.component_banner) { + + swipeEnable = false + dragEnable = false + + val viewPager2 = findViewById(R.id.banner) + val bannerAdapter = FlapAdapter().apply { + registerAdapterDelegate(bannerImageDelegate()) + } + + viewPager2.adapter = bannerAdapter + + onBind { model, position, payloads, adapter -> + model.images?.let { + bannerAdapter.setDataAndNotify(it) + } + } +} + +fun bannerImageDelegate() = adapterDelegate(R.layout.component_banner_image) { + + val imageView = findViewById(R.id.logo) + + onBind { model -> + if (model.url?.isNotEmpty() == true) { + Glide.with(context).load(model.url).into(imageView) + } else if (model.resId > 0) { + Glide.with(context).load(model.resId).into(imageView) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/yifeiyuan/flapdev/components/SimpleImageComponent.kt b/app/src/main/java/me/yifeiyuan/flapdev/components/SimpleImageComponent.kt index dd64a79f..c09c7c9a 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/components/SimpleImageComponent.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/components/SimpleImageComponent.kt @@ -1,6 +1,8 @@ package me.yifeiyuan.flapdev.components import android.view.View +import android.widget.ImageView +import com.bumptech.glide.Glide import me.yifeiyuan.flap.Component import me.yifeiyuan.flap.annotations.Delegate import me.yifeiyuan.flapdev.R @@ -10,11 +12,22 @@ import me.yifeiyuan.flapdev.R * Created by 程序亦非猿 on 2018/12/4. */ -class SimpleImageModel +class SimpleImageModel { + var url: String? = null + var resId: Int = 0 +} -@Delegate(layoutId = R.layout.flap_item_simple_image) +@Delegate(layoutId = R.layout.component_simple_image) //@Delegate(layoutName = "flap_item_simple_image") class SimpleImageComponent(itemView: View) : Component(itemView) { + + private val imageView = findViewById(R.id.logo) + override fun onBind(model: SimpleImageModel) { + if (model.url?.isNotEmpty() == true) { + Glide.with(context).load(model.url).into(imageView) + } else if (model.resId > 0) { + Glide.with(context).load(model.resId).into(imageView) + } } } \ No newline at end of file diff --git a/app/src/main/java/me/yifeiyuan/flapdev/testcases/DSLTestcase.kt b/app/src/main/java/me/yifeiyuan/flapdev/testcases/DSLTestcase.kt index 25e61e2e..5e6a9c55 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/testcases/DSLTestcase.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/testcases/DSLTestcase.kt @@ -3,19 +3,14 @@ package me.yifeiyuan.flapdev.testcases import android.util.Log import android.view.View import android.widget.ImageView -import me.yifeiyuan.flap.Component import me.yifeiyuan.flap.FlapAdapter -import me.yifeiyuan.flap.delegate.AdapterDelegate -import me.yifeiyuan.flap.delegate.LayoutAdapterDelegate import me.yifeiyuan.flap.dsl.adapterDelegate import me.yifeiyuan.flap.dsl.adapterHook import me.yifeiyuan.flap.ext.* -import me.yifeiyuan.flap.hook.AdapterHook import me.yifeiyuan.flapdev.R import me.yifeiyuan.flapdev.components.SimpleImageModel import me.yifeiyuan.flapdev.components.SimpleTextModel import me.yifeiyuan.flapdev.components.TestAllModel -import me.yifeiyuan.flapdev.components.TestBinderModel import me.yifeiyuan.flapdev.mockMultiTypeModels private const val TAG = "DSLTestcase" @@ -132,7 +127,7 @@ class DSLTestcase : BaseTestcaseFragment() { } } - val simpleImageDelegate = adapterDelegate(R.layout.flap_item_simple_image) { + val simpleImageDelegate = adapterDelegate(R.layout.component_simple_image) { onBind { model, position, payloads, adapter -> bindView(R.id.logo) { diff --git a/app/src/main/res/layout/component_banner.xml b/app/src/main/res/layout/component_banner.xml index 61a4490a..9e380d94 100644 --- a/app/src/main/res/layout/component_banner.xml +++ b/app/src/main/res/layout/component_banner.xml @@ -1,6 +1,12 @@ - + android:layout_height="wrap_content"> - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/component_full_feature.xml b/app/src/main/res/layout/component_full_feature.xml index 61a4490a..739c8f9a 100644 --- a/app/src/main/res/layout/component_full_feature.xml +++ b/app/src/main/res/layout/component_full_feature.xml @@ -1,6 +1,32 @@ - + + + + + \ No newline at end of file diff --git a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt index ef3fbd75..bb3261a1 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt @@ -118,7 +118,7 @@ open class FlapAdapter : RecyclerView.Adapter>(), IAdapterHookManag data.addAll(newDataList) } - open fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean = false) { + open fun setDataAndNotify(newDataList: MutableList, notifyAll: Boolean = false) { data.clear() data.addAll(newDataList) if (notifyAll) { From 9f9d5700f8c22c87a8efb8440fd4f4ebf1c2639d Mon Sep 17 00:00:00 2001 From: Fitz Date: Tue, 13 Sep 2022 16:01:21 +0800 Subject: [PATCH 11/12] =?UTF-8?q?:memo:=20=E6=9B=B4=E6=96=B0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flap/src/main/java/me/yifeiyuan/flap/Component.kt | 3 +++ .../java/me/yifeiyuan/flap/delegate/LayoutAdapterDelegate.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flap/src/main/java/me/yifeiyuan/flap/Component.kt b/flap/src/main/java/me/yifeiyuan/flap/Component.kt index f32fb553..6c0f7a20 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/Component.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/Component.kt @@ -52,6 +52,9 @@ open class Component(itemView: View) : RecyclerView.ViewHolder(itemView), Lif internal var _bindingData: Any? = null + /** + * @since 3.1.2 + */ val data: T get() = if (_bindingData == null) { throw IllegalArgumentException("onBind 还未调用,不可以使用 bindingData") diff --git a/flap/src/main/java/me/yifeiyuan/flap/delegate/LayoutAdapterDelegate.kt b/flap/src/main/java/me/yifeiyuan/flap/delegate/LayoutAdapterDelegate.kt index daa7fced..b1ec1666 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/delegate/LayoutAdapterDelegate.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/delegate/LayoutAdapterDelegate.kt @@ -21,7 +21,7 @@ import me.yifeiyuan.flap.FlapAdapter * @see me.yifeiyuan.flap.dsl.adapterDelegate * * Created by 程序亦非猿 on 2021/10/27. - * @since 3.0.0 + * @since 3.1.1 */ class LayoutAdapterDelegate( private var modelClass: Class?, From 19a7ce59766278a927461b61bbdf2d561ec38a56 Mon Sep 17 00:00:00 2001 From: Fitz Date: Mon, 19 Sep 2022 19:21:45 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0SwipeDragHelper.onClear?= =?UTF-8?q?View=E5=9B=9E=E8=B0=83=EF=BC=9B=E5=AE=8C=E5=96=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flapdev/testcases/SwipeAndDragTestcase.kt | 13 +++ .../me/yifeiyuan/flap/ext/SwipeDragHelper.kt | 89 ++++++++++++++----- 2 files changed, 81 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/me/yifeiyuan/flapdev/testcases/SwipeAndDragTestcase.kt b/app/src/main/java/me/yifeiyuan/flapdev/testcases/SwipeAndDragTestcase.kt index f27fc7c9..dbbf4b8d 100644 --- a/app/src/main/java/me/yifeiyuan/flapdev/testcases/SwipeAndDragTestcase.kt +++ b/app/src/main/java/me/yifeiyuan/flapdev/testcases/SwipeAndDragTestcase.kt @@ -1,10 +1,12 @@ package me.yifeiyuan.flapdev.testcases +import android.animation.ObjectAnimator import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.util.Log import android.view.View import androidx.recyclerview.widget.ItemTouchHelper +import androidx.vectordrawable.graphics.drawable.ArgbEvaluator import me.yifeiyuan.flap.FlapAdapter import me.yifeiyuan.flap.ext.SwipeDragHelper @@ -39,10 +41,18 @@ class SwipeAndDragTestcase : BaseTestcaseFragment() { .onDragStarted { viewHolder, adapterPosition -> Log.d(TAG, "开始拖动 position=$adapterPosition") toast("开始拖动 position=$adapterPosition") + + //做个放大动画 + val scaleY = ObjectAnimator.ofFloat(viewHolder.itemView, "scaleY", 1f, 1.5f) + scaleY.start() } .onDragReleased { viewHolder, adapterPosition -> Log.d(TAG, "拖动结束 position=$adapterPosition") toast("拖动结束 position=$adapterPosition") + + //恢复原状 + val scaleY = ObjectAnimator.ofFloat(viewHolder.itemView, "scaleY", 1f) + scaleY.start() } .onSwipeStarted { viewHolder, adapterPosition -> Log.d(TAG, "滑动开始 position=$adapterPosition") @@ -52,6 +62,9 @@ class SwipeAndDragTestcase : BaseTestcaseFragment() { Log.d(TAG, "滑动结束 position=$adapterPosition") toast("滑动结束 position=$adapterPosition") } + .onClearView { viewHolder, adapterPosition -> + Log.d(TAG, "onClearView called position=$adapterPosition") + } .attachToRecyclerView(recyclerView) recyclerView.addItemDecoration(spaceItemDecoration) diff --git a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt index cac4e56c..40a7dde7 100644 --- a/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt +++ b/flap/src/main/java/me/yifeiyuan/flap/ext/SwipeDragHelper.kt @@ -12,14 +12,35 @@ typealias OnItemMoveListener = (fromPosition: Int, toPosition: Int) -> Unit * item 被删除 */ typealias OnItemSwipedListener = (position: Int) -> Unit + +/** + * 滑动开始 + */ typealias OnSwipeStartedListener = (viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) -> Unit + /** - * 一次滑动手势释放 - * 但是不代表被删除 + * 一次滑动手势释放,不管是否被删除,都会回调,所以不代表被删除 + * adapterPosition 等同于 OnSwipeStartedListener.adapterPosition */ typealias OnSwipeReleasedListener = (viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) -> Unit -typealias OnDragStartedListener = (viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) -> Unit -typealias OnDragReleasedListener = (viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) -> Unit + +/** + * @param fromPosition 最开始被拖动的 ViewHolder 的 position + */ +typealias OnDragStartedListener = (viewHolder: RecyclerView.ViewHolder, fromPosition: Int) -> Unit + +/** + * @param toPosition 最终被拖动到的位置 + */ +typealias OnDragReleasedListener = (viewHolder: RecyclerView.ViewHolder, toPosition: Int) -> Unit + + +/** + * 一次手势结束后回调,包括拖放和滑动两种手势 + * + * 在 OnSwipeReleasedListener 和 OnDragReleasedListener 回调之后回调 + */ +typealias OnClearViewListener = (viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) -> Unit /** * @@ -61,6 +82,8 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback private var onDragStarted: OnDragStartedListener? = null private var onDragReleased: OnDragReleasedListener? = null + private var onClearView: OnClearViewListener? = null + private var swipeBackground: Drawable? = null private val itemTouchHelper: ItemTouchHelper = ItemTouchHelper(this) @@ -147,19 +170,19 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback onMoved = listener } - fun onSwipeStarted(listener: OnSwipeStartedListener)= apply { + fun onSwipeStarted(listener: OnSwipeStartedListener) = apply { onSwipeStarted = listener } - fun onSwipeReleased(listener: OnSwipeReleasedListener)= apply { + fun onSwipeReleased(listener: OnSwipeReleasedListener) = apply { onSwipedReleased = listener } - fun onDragStarted(listener: OnDragStartedListener)= apply { + fun onDragStarted(listener: OnDragStartedListener) = apply { onDragStarted = listener } - fun onDragReleased(listener: OnDragReleasedListener)= apply { + fun onDragReleased(listener: OnDragReleasedListener) = apply { onDragReleased = listener } @@ -169,11 +192,11 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback callback.onSwiped(viewHolder.adapterPosition) } - fun onItemSwiped(listener: OnItemSwipedListener)= apply { + fun onItemSwiped(listener: OnItemSwipedListener) = apply { onSwiped = listener } - fun attachToRecyclerView(recyclerView: RecyclerView)= apply { + fun attachToRecyclerView(recyclerView: RecyclerView) = apply { itemTouchHelper.attachToRecyclerView(recyclerView) } @@ -225,6 +248,12 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback */ override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { super.clearView(recyclerView, viewHolder) + callback.onClearView(recyclerView, viewHolder) + onClearView?.invoke(viewHolder,viewHolder.adapterPosition) + } + + fun onClearView(listener: OnClearViewListener) = apply { + onClearView = listener } override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { @@ -253,65 +282,82 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback /** * 拖动是否可用 */ - fun withDragEnable(enable: Boolean)= apply { + fun withDragEnable(enable: Boolean) = apply { isDragEnable = enable } /** * 滑动删除是否可用 */ - fun withSwipeEnable(enable: Boolean)= apply { + fun withSwipeEnable(enable: Boolean) = apply { isSwipeEnable = enable } /** * 快捷设置 dragFlags 为垂直方向 up or down */ - fun forVerticalList()= apply { + fun forVerticalList() = apply { this.dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN } /** * 快捷设置 dragFlags 为水平方向 left or right */ - fun forHorizontalList()= apply { + fun forHorizontalList() = apply { this.dragFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT } /** * 快捷设置 dragFlags 为全方向 */ - fun forGrid()= apply { + fun forGrid() = apply { this.dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT } - fun withDragFlags(dragFlags: Int)= apply { + fun withDragFlags(dragFlags: Int) = apply { this.dragFlags = dragFlags } - fun withSwipeFlags(swipeFlags: Int)= apply { + fun withSwipeFlags(swipeFlags: Int) = apply { this.swipeFlags = swipeFlags } - fun withSwipeThreshold(swipeThreshold: Float)= apply { + fun withSwipeThreshold(swipeThreshold: Float) = apply { this.swipeThreshold = swipeThreshold } - fun withDragThreshold(dragThreshold: Float)= apply { + fun withDragThreshold(dragThreshold: Float) = apply { this.dragThreshold = dragThreshold } /** * 设置被滑动的 item 的背景 */ - fun withSwipeBackground(swipeBackground: Drawable)= apply { + fun withSwipeBackground(swipeBackground: Drawable) = apply { this.swipeBackground = swipeBackground } - fun withSwipeBackgroundColor(color: Int)= apply { + /** + * 设置被滑动的 item 的背景颜色 + */ + fun withSwipeBackgroundColor(color: Int) = apply { this.swipeBackground = ColorDrawable(color) } + /** + * 开始拖动 + */ + fun startDrag(viewHolder: RecyclerView.ViewHolder) { + itemTouchHelper.startDrag(viewHolder) + } + + /** + * 开始滑动 + */ + fun startSwipe(viewHolder: RecyclerView.ViewHolder) { + itemTouchHelper.startSwipe(viewHolder) + } + interface Callback { fun onSwipeStarted(viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) {} fun onSwipeReleased(viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) {} @@ -319,5 +365,6 @@ class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback fun onDragStarted(viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) {} fun onMoved(fromPosition: Int, toPosition: Int) {} fun onDragReleased(viewHolder: RecyclerView.ViewHolder, adapterPosition: Int) {} + fun onClearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {} } } \ No newline at end of file