From 677cc20cda94dae095cb7e4e05be43633a25f28d Mon Sep 17 00:00:00 2001 From: LukeXeon <694014820@qq.com> Date: Fri, 15 Nov 2019 01:06:11 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/guet/flexbox/build/DataBinding.kt | 1 - el/build.gradle | 2 + .../guet/flexbox/el/JSONArrayELResolver.kt | 43 ++----------- .../guet/flexbox/el/JSONObjectELResolver.kt | 62 +++++++++++++++++++ .../guet/flexbox/el/StandardELContext.java | 2 + 5 files changed, 71 insertions(+), 39 deletions(-) rename core/src/main/java/com/guet/flexbox/build/JsonELResolver.kt => el/src/main/java/com/guet/flexbox/el/JSONArrayELResolver.kt (58%) create mode 100644 el/src/main/java/com/guet/flexbox/el/JSONObjectELResolver.kt diff --git a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt b/core/src/main/java/com/guet/flexbox/build/DataBinding.kt index d7fad4db..6308010e 100644 --- a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt +++ b/core/src/main/java/com/guet/flexbox/build/DataBinding.kt @@ -15,7 +15,6 @@ class DataBinding private constructor(data: Any?) { private val el = ELManager() init { - el.addELResolver(JsonELResolver) functions.forEach { el.mapFunction(it.first, it.second.name, it.second) } diff --git a/el/build.gradle b/el/build.gradle index b8629b09..c772b89b 100644 --- a/el/build.gradle +++ b/el/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' apply plugin: 'com.github.dcendents.android-maven' group='com.guet.flexbox' @@ -28,6 +29,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.github.panga:lite-beans:1.0.0' + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' } diff --git a/core/src/main/java/com/guet/flexbox/build/JsonELResolver.kt b/el/src/main/java/com/guet/flexbox/el/JSONArrayELResolver.kt similarity index 58% rename from core/src/main/java/com/guet/flexbox/build/JsonELResolver.kt rename to el/src/main/java/com/guet/flexbox/el/JSONArrayELResolver.kt index 75a4c4b0..b2fcee26 100644 --- a/core/src/main/java/com/guet/flexbox/build/JsonELResolver.kt +++ b/el/src/main/java/com/guet/flexbox/el/JSONArrayELResolver.kt @@ -1,13 +1,9 @@ -package com.guet.flexbox.build +package com.guet.flexbox.el -import com.guet.flexbox.el.ELContext -import com.guet.flexbox.el.ELResolver -import com.guet.flexbox.el.PropertyNotFoundException import lite.beans.FeatureDescriptor import org.json.JSONArray -import org.json.JSONObject -internal object JsonELResolver : ELResolver() { +internal object JSONArrayELResolver : ELResolver() { override fun getValue(context: ELContext, base: Any?, property: Any?): Any? { if (base is JSONArray) { @@ -17,10 +13,6 @@ internal object JsonELResolver : ELResolver() { null } else base[idx] } - if (base is JSONObject) { - context.setPropertyResolved(base, property) - return base[property.toString()] - } return null } @@ -30,10 +22,6 @@ internal object JsonELResolver : ELResolver() { val idx = coerce(property) return if (idx < 0 || idx >= base.length()) null else base[idx]?.javaClass } - if (base is JSONObject) { - context.setPropertyResolved(base, property) - return base[property.toString()]?.javaClass - } return null } @@ -44,10 +32,6 @@ internal object JsonELResolver : ELResolver() { checkBounds(base, idx) base.put(idx, value) } - if (base is JSONObject) { - context.setPropertyResolved(base, property) - base.put(property.toString(), value) - } } override fun isReadOnly(context: ELContext, base: Any?, property: Any?): Boolean { @@ -56,31 +40,14 @@ internal object JsonELResolver : ELResolver() { override fun getFeatureDescriptors(context: ELContext?, base: Any?) : MutableIterator? { - if (base is JSONObject) { - val feats = ArrayList(base.length()) - base.keys().forEach { key -> - val desc = FeatureDescriptor() - desc.displayName = key.toString() - desc.shortDescription = "" - desc.isExpert = false - desc.isHidden = false - desc.name = key.toString() - desc.isPreferred = true - desc.setValue(RESOLVABLE_AT_DESIGN_TIME, true) - desc.setValue(TYPE, key.javaClass) - feats.add(desc) - } - return feats.iterator() - } return null } override fun getCommonPropertyType(context: ELContext?, base: Any?): Class<*>? { - return when (base) { - is JSONArray -> Int::class.java - is JSONObject -> String::class.java - else -> null + if (base is JSONArray) { + return Int::class.java } + return null } private fun coerce(property: Any?): Int { diff --git a/el/src/main/java/com/guet/flexbox/el/JSONObjectELResolver.kt b/el/src/main/java/com/guet/flexbox/el/JSONObjectELResolver.kt new file mode 100644 index 00000000..5f12d594 --- /dev/null +++ b/el/src/main/java/com/guet/flexbox/el/JSONObjectELResolver.kt @@ -0,0 +1,62 @@ +package com.guet.flexbox.el + +import lite.beans.FeatureDescriptor +import org.json.JSONObject + +internal object JSONObjectELResolver : ELResolver() { + + override fun getValue(context: ELContext, base: Any?, property: Any?): Any? { + if (base is JSONObject) { + context.setPropertyResolved(base, property) + return base[property.toString()] + } + return null + } + + override fun getType(context: ELContext, base: Any?, property: Any?): Class<*>? { + if (base is JSONObject) { + context.setPropertyResolved(base, property) + return base[property.toString()]?.javaClass + } + return null + } + + override fun setValue(context: ELContext, base: Any?, property: Any?, value: Any?) { + if (base is JSONObject) { + context.setPropertyResolved(base, property) + base.put(property.toString(), value) + } + } + + override fun isReadOnly(context: ELContext, base: Any?, property: Any?): Boolean { + return false + } + + override fun getFeatureDescriptors(context: ELContext?, base: Any?) + : MutableIterator? { + if (base is JSONObject) { + val feats = ArrayList(base.length()) + base.keys().forEach { key -> + val desc = FeatureDescriptor() + desc.displayName = key.toString() + desc.shortDescription = "" + desc.isExpert = false + desc.isHidden = false + desc.name = key + desc.isPreferred = true + desc.setValue(RESOLVABLE_AT_DESIGN_TIME, true) + desc.setValue(TYPE, key.javaClass) + feats.add(desc) + } + return feats.iterator() + } + return null + } + + override fun getCommonPropertyType(context: ELContext?, base: Any?): Class<*>? { + if (base is JSONObject) { + return String::class.java + } + return null + } +} \ No newline at end of file diff --git a/el/src/main/java/com/guet/flexbox/el/StandardELContext.java b/el/src/main/java/com/guet/flexbox/el/StandardELContext.java index a179cbd2..dae7dcb7 100644 --- a/el/src/main/java/com/guet/flexbox/el/StandardELContext.java +++ b/el/src/main/java/com/guet/flexbox/el/StandardELContext.java @@ -56,6 +56,8 @@ public StandardELContext(ExpressionFactory factory) { standardResolver.add(new ListELResolver()); standardResolver.add(new ArrayELResolver()); standardResolver.add(new BeanELResolver()); + standardResolver.add(JSONArrayELResolver.INSTANCE); + standardResolver.add(JSONObjectELResolver.INSTANCE); } public StandardELContext(ELContext context) { From a7e7fd611abda179f81f21b7f07bd0ef3d69d594 Mon Sep 17 00:00:00 2001 From: LukeXeon <694014820@qq.com> Date: Fri, 15 Nov 2019 01:36:25 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/guet/flexbox/DynamicBoxSpec.java | 5 +-- .../com/guet/flexbox/build/DataBinding.kt | 15 +++++-- .../com/guet/flexbox/build/ForBehavior.kt | 2 +- .../com/guet/flexbox/build/ForEachBehavior.kt | 2 +- .../java/com/guet/flexbox/build/IfBehavior.kt | 2 +- .../com/guet/flexbox/build/NativeFactory.kt | 22 +++++----- .../java/com/guet/flexbox/build/Transform.kt | 40 ------------------- .../main/java/com/guet/flexbox/build/Utils.kt | 32 ++++++++++++++- .../com/guet/flexbox/build/WidgetFactory.kt | 2 +- 9 files changed, 59 insertions(+), 63 deletions(-) diff --git a/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java b/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java index 0bb3087e..cfd601e3 100644 --- a/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java +++ b/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java @@ -15,7 +15,6 @@ import com.facebook.litho.annotations.Param; import com.facebook.litho.annotations.Prop; import com.guet.flexbox.build.DataBinding; -import com.guet.flexbox.build.Transform; @LayoutSpec final class DynamicBoxSpec { @@ -25,9 +24,9 @@ static Component onCreateLayout(ComponentContext componentContext, @Prop(optional = true) Object bind, @Prop(optional = true) DataBinding dataBinding, @Prop NodeInfo layout) { - return Transform.Companion.createLayout( + return DataBinding.createLayout( componentContext, - dataBinding != null ? dataBinding : DataBinding.create(bind), + dataBinding != null ? dataBinding : new DataBinding(bind), layout ); } diff --git a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt b/core/src/main/java/com/guet/flexbox/build/DataBinding.kt index 6308010e..49bb9399 100644 --- a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt +++ b/core/src/main/java/com/guet/flexbox/build/DataBinding.kt @@ -6,11 +6,15 @@ import android.graphics.Color.parseColor import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable.Orientation import androidx.annotation.ColorInt +import androidx.annotation.RestrictTo +import com.facebook.litho.Component +import com.facebook.litho.ComponentContext +import com.guet.flexbox.NodeInfo import com.guet.flexbox.el.ELException import com.guet.flexbox.el.ELManager import java.lang.reflect.Modifier -class DataBinding private constructor(data: Any?) { +class DataBinding(data: Any?) { private val el = ELManager() @@ -71,8 +75,13 @@ class DataBinding private constructor(data: Any?) { companion object { @JvmStatic - fun create(data: Any?): DataBinding { - return DataBinding(data) + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) + fun createLayout( + c: ComponentContext, + dataBinding: DataBinding, + root: NodeInfo + ): Component { + return c.createFromElement(dataBinding, root).single() } internal val colorMap by lazy { diff --git a/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt b/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt index 051be7f2..6890ad3e 100644 --- a/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt @@ -19,7 +19,7 @@ internal object ForBehavior : Behavior() { return (from..to).map { return@map dataBinding.scope(Collections.singletonMap(name, it)) { children.map { item -> - Transform.createFromElement(c, dataBinding, item, upperVisibility) + c.createFromElement(dataBinding, item, upperVisibility) }.flatten() } }.flatten() diff --git a/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt b/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt index ec531e1b..df4ca5ec 100644 --- a/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt @@ -18,7 +18,7 @@ internal object ForEachBehavior : Behavior() { return items.map { item -> dataBinding.scope(Collections.singletonMap(name, item)) { children.map { - Transform.createFromElement(c, dataBinding, it, upperVisibility) + c.createFromElement(dataBinding, it, upperVisibility) }.flatten() } }.flatten() diff --git a/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt b/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt index 3297d583..08fefa7e 100644 --- a/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt @@ -14,7 +14,7 @@ internal object IfBehavior : Behavior() { ): List { return if (dataBinding.requestValue("test", attrs)) { return children.map { - Transform.createFromElement(c, dataBinding, it, upperVisibility) + c.createFromElement(dataBinding, it, upperVisibility) }.flatten() } else { emptyList() diff --git a/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt b/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt index ceee51a5..0cd98a1b 100644 --- a/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt @@ -4,7 +4,6 @@ package com.guet.flexbox.build import android.content.Context import android.graphics.Outline -import android.util.LruCache import android.view.View import android.view.ViewGroup import android.view.ViewOutlineProvider @@ -26,7 +25,14 @@ internal object NativeFactory : WidgetFactory> if (attrs != null) { val type = dataBinding.tryGetValue(attrs["type"], "") if (type.isNotEmpty()) { - val view = ViewTypeCache[type] + val view = viewTypeCache.getOrPut(type) { + val viewType = Class.forName(type) + if (View::class.java.isAssignableFrom(viewType)) { + return@getOrPut ReflectViewCreator(viewType.getConstructor(Context::class.java)) + } else { + throw IllegalStateException("$type is not as 'View' type") + } + } val radius = dataBinding.tryGetValue(attrs["borderRadius"], 0f) val va = ViewAdapter(visibility, radius) return ViewCompatComponent.get(view, type) @@ -34,19 +40,11 @@ internal object NativeFactory : WidgetFactory> .viewBinder(va) } } + throw IllegalArgumentException("can not found View type") } - internal object ViewTypeCache : LruCache(32) { - override fun create(key: String): ReflectViewCreator { - val viewType = Class.forName(key) - if (View::class.java.isAssignableFrom(viewType)) { - return ReflectViewCreator(viewType.getConstructor(Context::class.java)) - } else { - throw IllegalArgumentException("$key is not as 'View' type") - } - } - } + private val viewTypeCache = HashMap(32) internal class ReflectViewCreator(private val constructor: Constructor<*>) : ViewCreator { override fun createView(c: Context, parent: ViewGroup?): View { diff --git a/core/src/main/java/com/guet/flexbox/build/Transform.kt b/core/src/main/java/com/guet/flexbox/build/Transform.kt index ff083faf..53363411 100644 --- a/core/src/main/java/com/guet/flexbox/build/Transform.kt +++ b/core/src/main/java/com/guet/flexbox/build/Transform.kt @@ -1,7 +1,5 @@ package com.guet.flexbox.build -import android.view.View -import androidx.annotation.RestrictTo import com.facebook.litho.Component import com.facebook.litho.ComponentContext import com.guet.flexbox.NodeInfo @@ -15,42 +13,4 @@ internal interface Transform { upperVisibility: Int ): List - companion object { - - @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) - fun createLayout( - context: ComponentContext, - dataBinding: DataBinding, - root: NodeInfo - ): Component { - return createFromElement(context, dataBinding, root).single() - } - - internal fun createFromElement( - context: ComponentContext, - dataBinding: DataBinding, - element: NodeInfo, - upperVisibility: Int = View.VISIBLE - ): List { - return transforms[element.type]?.transform( - context, - dataBinding, - element, - upperVisibility - ) ?: emptyList() - } - - private val transforms = mapOf( - "Image" to ImageFactory, - "Flex" to FlexFactory, - "Text" to TextFactory, - "Frame" to FrameFactory, - "Native" to NativeFactory, - "Scroller" to ScrollerFactory, - "Empty" to EmptyFactory, - "for" to ForBehavior, - "foreach" to ForEachBehavior, - "if" to IfBehavior - ) - } } \ No newline at end of file diff --git a/core/src/main/java/com/guet/flexbox/build/Utils.kt b/core/src/main/java/com/guet/flexbox/build/Utils.kt index de722b27..91629ac1 100644 --- a/core/src/main/java/com/guet/flexbox/build/Utils.kt +++ b/core/src/main/java/com/guet/flexbox/build/Utils.kt @@ -3,8 +3,12 @@ package com.guet.flexbox.build import android.content.res.Resources +import android.view.View import androidx.annotation.ColorInt +import com.facebook.litho.Component +import com.facebook.litho.ComponentContext import com.guet.flexbox.BuildConfig +import com.guet.flexbox.NodeInfo import com.guet.flexbox.el.ELException import lite.beans.Introspector import org.json.JSONObject @@ -235,4 +239,30 @@ internal fun tryToMap(o: Any): Map { }.toMap() } } -} \ No newline at end of file +} + +internal fun ComponentContext.createFromElement( + dataBinding: DataBinding, + element: NodeInfo, + upperVisibility: Int = View.VISIBLE +): List { + return transforms[element.type]?.transform( + this, + dataBinding, + element, + upperVisibility + ) ?: emptyList() +} + +private val transforms = mapOf( + "Image" to ImageFactory, + "Flex" to FlexFactory, + "Text" to TextFactory, + "Frame" to FrameFactory, + "Native" to NativeFactory, + "Scroller" to ScrollerFactory, + "Empty" to EmptyFactory, + "for" to ForBehavior, + "foreach" to ForEachBehavior, + "if" to IfBehavior +) \ No newline at end of file diff --git a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt index a0c10445..819550a7 100644 --- a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt @@ -135,7 +135,7 @@ internal abstract class WidgetFactory> : Transform { val builder = onCreateWidget(c, dataBinding, attrs, visibility) onLoadStyles(builder, c, dataBinding, attrs, visibility) onInstallChildren(builder, c, dataBinding, attrs, childrenNodes?.map { - Transform.createFromElement(c, dataBinding, it, visibility) + c.createFromElement(dataBinding, it, visibility) }?.flatten(), visibility) return builder.build() } From 16f23d8a5a3099dfe8301afc517206bb6e7f9803 Mon Sep 17 00:00:00 2001 From: Luke <694014820@qq.com> Date: Fri, 15 Nov 2019 12:51:38 +0800 Subject: [PATCH 3/4] bugfix --- .../java/com/guet/flexbox/DynamicBoxSpec.java | 8 ++++---- .../main/java/com/guet/flexbox/build/Behavior.kt | 4 ++-- .../build/{DataBinding.kt => DataContext.kt} | 4 ++-- .../java/com/guet/flexbox/build/EmptyFactory.kt | 4 ++-- .../java/com/guet/flexbox/build/FlexFactory.kt | 4 ++-- .../java/com/guet/flexbox/build/ForBehavior.kt | 2 +- .../com/guet/flexbox/build/ForEachBehavior.kt | 2 +- .../java/com/guet/flexbox/build/FrameFactory.kt | 4 ++-- .../java/com/guet/flexbox/build/IfBehavior.kt | 2 +- .../java/com/guet/flexbox/build/ImageFactory.kt | 2 +- .../java/com/guet/flexbox/build/NativeFactory.kt | 2 +- .../com/guet/flexbox/build/ScrollerFactory.kt | 4 ++-- .../java/com/guet/flexbox/build/TextFactory.kt | 4 ++-- .../java/com/guet/flexbox/build/Transform.kt | 2 +- .../main/java/com/guet/flexbox/build/Utils.kt | 14 +++++++------- .../java/com/guet/flexbox/build/WidgetFactory.kt | 16 ++++++++-------- 16 files changed, 39 insertions(+), 39 deletions(-) rename core/src/main/java/com/guet/flexbox/build/{DataBinding.kt => DataContext.kt} (98%) diff --git a/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java b/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java index cfd601e3..66315281 100644 --- a/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java +++ b/core/src/main/java/com/guet/flexbox/DynamicBoxSpec.java @@ -14,7 +14,7 @@ import com.facebook.litho.annotations.OnEvent; import com.facebook.litho.annotations.Param; import com.facebook.litho.annotations.Prop; -import com.guet.flexbox.build.DataBinding; +import com.guet.flexbox.build.DataContext; @LayoutSpec final class DynamicBoxSpec { @@ -22,11 +22,11 @@ final class DynamicBoxSpec { @OnCreateLayout static Component onCreateLayout(ComponentContext componentContext, @Prop(optional = true) Object bind, - @Prop(optional = true) DataBinding dataBinding, + @Prop(optional = true) DataContext dataContext, @Prop NodeInfo layout) { - return DataBinding.createLayout( + return DataContext.createLayout( componentContext, - dataBinding != null ? dataBinding : new DataBinding(bind), + dataContext != null ? dataContext : new DataContext(bind), layout ); } diff --git a/core/src/main/java/com/guet/flexbox/build/Behavior.kt b/core/src/main/java/com/guet/flexbox/build/Behavior.kt index 11732262..651acbb8 100644 --- a/core/src/main/java/com/guet/flexbox/build/Behavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/Behavior.kt @@ -8,7 +8,7 @@ internal abstract class Behavior : Transform { final override fun transform( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, nodeInfo: NodeInfo, upperVisibility: Int ): List { @@ -26,7 +26,7 @@ internal abstract class Behavior : Transform { protected abstract fun onApply( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map, children: List, upperVisibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt b/core/src/main/java/com/guet/flexbox/build/DataContext.kt similarity index 98% rename from core/src/main/java/com/guet/flexbox/build/DataBinding.kt rename to core/src/main/java/com/guet/flexbox/build/DataContext.kt index 49bb9399..22aaefdf 100644 --- a/core/src/main/java/com/guet/flexbox/build/DataBinding.kt +++ b/core/src/main/java/com/guet/flexbox/build/DataContext.kt @@ -14,7 +14,7 @@ import com.guet.flexbox.el.ELException import com.guet.flexbox.el.ELManager import java.lang.reflect.Modifier -class DataBinding(data: Any?) { +class DataContext(data: Any?) { private val el = ELManager() @@ -78,7 +78,7 @@ class DataBinding(data: Any?) { @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) fun createLayout( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, root: NodeInfo ): Component { return c.createFromElement(dataBinding, root).single() diff --git a/core/src/main/java/com/guet/flexbox/build/EmptyFactory.kt b/core/src/main/java/com/guet/flexbox/build/EmptyFactory.kt index a5957986..19f3a42a 100644 --- a/core/src/main/java/com/guet/flexbox/build/EmptyFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/EmptyFactory.kt @@ -7,7 +7,7 @@ import com.facebook.litho.widget.EmptyComponent internal object EmptyFactory : WidgetFactory() { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): EmptyComponent.Builder { @@ -15,7 +15,7 @@ internal object EmptyFactory : WidgetFactory() { } override fun calculateVisibility( - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, upperVisibility: Int): Int { val value = super.calculateVisibility(dataBinding, attrs, upperVisibility) diff --git a/core/src/main/java/com/guet/flexbox/build/FlexFactory.kt b/core/src/main/java/com/guet/flexbox/build/FlexFactory.kt index a2466644..327fabd2 100644 --- a/core/src/main/java/com/guet/flexbox/build/FlexFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/FlexFactory.kt @@ -67,7 +67,7 @@ internal object FlexFactory : WidgetFactory>() { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): Component.ContainerBuilder<*> { @@ -101,7 +101,7 @@ internal object FlexFactory : WidgetFactory>() { override fun onInstallChildren( owner: Component.ContainerBuilder<*>, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, children: List?, visibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt b/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt index 6890ad3e..f7292f47 100644 --- a/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/ForBehavior.kt @@ -8,7 +8,7 @@ import java.util.* internal object ForBehavior : Behavior() { override fun onApply( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map, children: List, upperVisibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt b/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt index df4ca5ec..5e14707e 100644 --- a/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/ForEachBehavior.kt @@ -8,7 +8,7 @@ import java.util.* internal object ForEachBehavior : Behavior() { override fun onApply( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map, children: List, upperVisibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/FrameFactory.kt b/core/src/main/java/com/guet/flexbox/build/FrameFactory.kt index 9997d302..88402a18 100644 --- a/core/src/main/java/com/guet/flexbox/build/FrameFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/FrameFactory.kt @@ -26,7 +26,7 @@ internal object FrameFactory : WidgetFactory(), ThreadFactory { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): Row.Builder { @@ -36,7 +36,7 @@ internal object FrameFactory : WidgetFactory(), ThreadFactory { override fun onInstallChildren( owner: Row.Builder, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, children: List?, visibility: Int) { diff --git a/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt b/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt index 08fefa7e..47b2fa14 100644 --- a/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt +++ b/core/src/main/java/com/guet/flexbox/build/IfBehavior.kt @@ -7,7 +7,7 @@ import com.guet.flexbox.NodeInfo internal object IfBehavior : Behavior() { override fun onApply( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map, children: List, upperVisibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/ImageFactory.kt b/core/src/main/java/com/guet/flexbox/build/ImageFactory.kt index 77dda596..a20bcda4 100644 --- a/core/src/main/java/com/guet/flexbox/build/ImageFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/ImageFactory.kt @@ -47,7 +47,7 @@ internal object ImageFactory : WidgetFactory() { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): NetworkImage.Builder { diff --git a/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt b/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt index 0cd98a1b..8d4ac6b6 100644 --- a/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/NativeFactory.kt @@ -18,7 +18,7 @@ internal object NativeFactory : WidgetFactory> override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): ViewCompatComponent.Builder { diff --git a/core/src/main/java/com/guet/flexbox/build/ScrollerFactory.kt b/core/src/main/java/com/guet/flexbox/build/ScrollerFactory.kt index 2aaf0c58..2ef20d5d 100644 --- a/core/src/main/java/com/guet/flexbox/build/ScrollerFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/ScrollerFactory.kt @@ -29,7 +29,7 @@ internal object ScrollerFactory : WidgetFactory>() { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): Component.Builder<*> { @@ -46,7 +46,7 @@ internal object ScrollerFactory : WidgetFactory>() { override fun onInstallChildren( owner: Component.Builder<*>, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, children: List?, visibility: Int diff --git a/core/src/main/java/com/guet/flexbox/build/TextFactory.kt b/core/src/main/java/com/guet/flexbox/build/TextFactory.kt index 922d90e7..f378dce8 100644 --- a/core/src/main/java/com/guet/flexbox/build/TextFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/TextFactory.kt @@ -68,7 +68,7 @@ internal object TextFactory : WidgetFactory() { override fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): Text.Builder { @@ -78,7 +78,7 @@ internal object TextFactory : WidgetFactory() { override fun onLoadStyles( owner: Text.Builder, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ) { diff --git a/core/src/main/java/com/guet/flexbox/build/Transform.kt b/core/src/main/java/com/guet/flexbox/build/Transform.kt index 53363411..425aabab 100644 --- a/core/src/main/java/com/guet/flexbox/build/Transform.kt +++ b/core/src/main/java/com/guet/flexbox/build/Transform.kt @@ -8,7 +8,7 @@ internal interface Transform { fun transform( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, nodeInfo: NodeInfo, upperVisibility: Int ): List diff --git a/core/src/main/java/com/guet/flexbox/build/Utils.kt b/core/src/main/java/com/guet/flexbox/build/Utils.kt index 91629ac1..fa0e64b3 100644 --- a/core/src/main/java/com/guet/flexbox/build/Utils.kt +++ b/core/src/main/java/com/guet/flexbox/build/Utils.kt @@ -21,7 +21,7 @@ internal inline fun T.toPx(): Int { return (this.toFloat() * Resources.getSystem().displayMetrics.widthPixels / 360f).toInt() } -internal inline fun DataBinding.tryGetValue(expr: String?, fallback: T): T { +internal inline fun DataContext.tryGetValue(expr: String?, fallback: T): T { if (expr == null) { return fallback } @@ -35,7 +35,7 @@ internal inline fun DataBinding.tryGetValue(expr: String?, fal } } -internal inline fun DataBinding.scope(scope: Map, action: () -> T): T { +internal inline fun DataContext.scope(scope: Map, action: () -> T): T { enterScope(scope) try { return action() @@ -44,7 +44,7 @@ internal inline fun DataBinding.scope(scope: Map, action: () -> } } -internal inline fun > DataBinding.tryGetEnum( +internal inline fun > DataContext.tryGetEnum( expr: String?, scope: Map, fallback: T = T::class.java.enumConstants[0]): T { @@ -57,7 +57,7 @@ internal inline fun > DataBinding.tryGetEnum( } } -internal inline fun DataBinding.requestValue( +internal inline fun DataContext.requestValue( name: String, attrs: Map ): T { @@ -65,7 +65,7 @@ internal inline fun DataBinding.requestValue( } @ColorInt -internal fun DataBinding.tryGetColor(expr: String?, @ColorInt fallback: Int): Int { +internal fun DataContext.tryGetColor(expr: String?, @ColorInt fallback: Int): Int { if (expr == null) { return fallback } @@ -102,7 +102,7 @@ private typealias JsonSupports = Map, FromJson<*>> private typealias SupportMap = HashMap, FromJson<*>> -internal typealias Mapping = T.(DataBinding, Map, Boolean, String) -> Unit +internal typealias Mapping = T.(DataContext, Map, Boolean, String) -> Unit internal typealias Mappings = HashMap> @@ -242,7 +242,7 @@ internal fun tryToMap(o: Any): Map { } internal fun ComponentContext.createFromElement( - dataBinding: DataBinding, + dataBinding: DataContext, element: NodeInfo, upperVisibility: Int = View.VISIBLE ): List { diff --git a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt index 819550a7..224061ba 100644 --- a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt @@ -70,7 +70,7 @@ internal abstract class WidgetFactory> : Transform { final override fun transform( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, nodeInfo: NodeInfo, upperVisibility: Int ): List { @@ -84,7 +84,7 @@ internal abstract class WidgetFactory> : Transform { protected abstract fun onCreateWidget( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ): T @@ -92,7 +92,7 @@ internal abstract class WidgetFactory> : Transform { protected open fun onInstallChildren( owner: T, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, children: List?, visibility: Int) { @@ -102,7 +102,7 @@ internal abstract class WidgetFactory> : Transform { protected open fun onLoadStyles( owner: T, c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, visibility: Int ) { @@ -122,7 +122,7 @@ internal abstract class WidgetFactory> : Transform { private fun create( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, nodeInfo: NodeInfo, upperVisibility: Int ): Component? { @@ -142,7 +142,7 @@ internal abstract class WidgetFactory> : Transform { private fun T.applyBackground( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map ) { val borderRadius = dataBinding.tryGetValue(attrs["borderRadius"], 0).toPx() @@ -193,7 +193,7 @@ internal abstract class WidgetFactory> : Transform { private fun T.applyEvent( c: ComponentContext, - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map, visibility: Int ) { @@ -217,7 +217,7 @@ internal abstract class WidgetFactory> : Transform { } protected open fun calculateVisibility( - dataBinding: DataBinding, + dataBinding: DataContext, attrs: Map?, upperVisibility: Int ): Int { From faa93c9bc07319e287e2c23d0a6d1cfb3af3cae6 Mon Sep 17 00:00:00 2001 From: Luke <694014820@qq.com> Date: Fri, 15 Nov 2019 14:20:08 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8DLiveReload=E6=97=B6Bitmap?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=BE=88=E5=A5=BD=E5=A4=8D=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/guet/flexbox/build/DataContext.kt | 42 ++++++------ .../com/guet/flexbox/build/WidgetFactory.kt | 18 ++--- .../guet/flexbox/widget/BackgroundDrawable.kt | 35 ++++++++++ .../guet/flexbox/widget/DrawableWrapper.kt | 6 +- .../guet/flexbox/widget/MatrixDrawable.java | 3 +- .../guet/flexbox/widget/NetworkDrawable.kt | 43 ------------ .../flexbox/widget/NetworkLazyDrawable.kt | 65 +++++++++++++++++++ 7 files changed, 134 insertions(+), 78 deletions(-) create mode 100644 core/src/main/java/com/guet/flexbox/widget/BackgroundDrawable.kt delete mode 100644 core/src/main/java/com/guet/flexbox/widget/NetworkDrawable.kt create mode 100644 core/src/main/java/com/guet/flexbox/widget/NetworkLazyDrawable.kt diff --git a/core/src/main/java/com/guet/flexbox/build/DataContext.kt b/core/src/main/java/com/guet/flexbox/build/DataContext.kt index 22aaefdf..388bf9e7 100644 --- a/core/src/main/java/com/guet/flexbox/build/DataContext.kt +++ b/core/src/main/java/com/guet/flexbox/build/DataContext.kt @@ -3,12 +3,12 @@ package com.guet.flexbox.build import android.content.res.Resources import android.graphics.Color import android.graphics.Color.parseColor -import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable.Orientation import androidx.annotation.ColorInt import androidx.annotation.RestrictTo import com.facebook.litho.Component import com.facebook.litho.ComponentContext +import com.facebook.litho.drawable.ComparableGradientDrawable import com.guet.flexbox.NodeInfo import com.guet.flexbox.el.ELException import com.guet.flexbox.el.ELManager @@ -84,26 +84,22 @@ class DataContext(data: Any?) { return c.createFromElement(dataBinding, root).single() } - internal val colorMap by lazy { - @Suppress("UNCHECKED_CAST") - HashMap((Color::class.java - .getDeclaredField("sColorNameMap") - .apply { isAccessible = true } - .get(null) as Map)) - } - - internal val functions by lazy { - Functions::class.java.declaredMethods - .filter { - it.modifiers.let { mod -> - Modifier.isPublic(mod) && Modifier.isStatic(mod) - } && it.isAnnotationPresent(Prefix::class.java) - }.map { - it.apply { it.isAccessible = true } - }.map { - it.getAnnotation(Prefix::class.java).value to it - }.toTypedArray() - } + @Suppress("UNCHECKED_CAST") + internal val colorMap = HashMap((Color::class.java + .getDeclaredField("sColorNameMap") + .apply { isAccessible = true } + .get(null) as Map)) + + internal val functions = Functions::class.java.declaredMethods + .filter { + it.modifiers.let { mod -> + Modifier.isPublic(mod) && Modifier.isStatic(mod) + } && it.isAnnotationPresent(Prefix::class.java) + }.map { + it.apply { it.isAccessible = true } + }.map { + it.getAnnotation(Prefix::class.java).value to it + }.toTypedArray() } internal object Functions { @@ -126,8 +122,8 @@ class DataContext(data: Any?) { fun gradient( orientation: Orientation, vararg colors: String - ): GradientDrawable { - return GradientDrawable(orientation, colors.map { + ): ComparableGradientDrawable { + return ComparableGradientDrawable(orientation, colors.map { parseColor(it) }.toIntArray()) } diff --git a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt index 224061ba..6bcf9da8 100644 --- a/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt +++ b/core/src/main/java/com/guet/flexbox/build/WidgetFactory.kt @@ -1,7 +1,6 @@ package com.guet.flexbox.build import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.view.View @@ -9,12 +8,14 @@ import androidx.annotation.CallSuper import com.bumptech.glide.request.target.Target import com.facebook.litho.Component import com.facebook.litho.ComponentContext +import com.facebook.litho.drawable.ComparableColorDrawable +import com.facebook.litho.drawable.ComparableGradientDrawable import com.facebook.yoga.YogaAlign import com.facebook.yoga.YogaEdge import com.guet.flexbox.DynamicBox import com.guet.flexbox.NodeInfo -import com.guet.flexbox.widget.BorderDrawable -import com.guet.flexbox.widget.NetworkDrawable +import com.guet.flexbox.widget.BackgroundDrawable +import com.guet.flexbox.widget.NetworkLazyDrawable import com.guet.flexbox.widget.NoOpDrawable import java.util.* @@ -152,14 +153,14 @@ internal abstract class WidgetFactory> : Transform { val background = attrs["background"] if (background != null) { try { - backgroundDrawable = ColorDrawable(dataBinding.getColor(background)) + backgroundDrawable = ComparableColorDrawable.create(dataBinding.getColor(background)) } catch (e: Exception) { val backgroundELResult = dataBinding.scope(orientations) { dataBinding.scope(colorNameMap) { dataBinding.tryGetValue(background, Unit) } } - if (backgroundELResult is Drawable) { + if (backgroundELResult is ComparableGradientDrawable) { backgroundDrawable = backgroundELResult } else if (backgroundELResult is CharSequence && backgroundELResult.isNotEmpty()) { var width = dataBinding.tryGetValue(attrs["width"], Target.SIZE_ORIGINAL) @@ -170,10 +171,10 @@ internal abstract class WidgetFactory> : Transform { if (height <= 0) { height = Target.SIZE_ORIGINAL } - backgroundDrawable = NetworkDrawable( + backgroundDrawable = NetworkLazyDrawable( + c.androidContext, width.toPx(), height.toPx(), - c.androidContext, backgroundELResult ) } @@ -182,8 +183,7 @@ internal abstract class WidgetFactory> : Transform { if (backgroundDrawable == null) { backgroundDrawable = NoOpDrawable() } - @Suppress("DEPRECATION") - this.background(BorderDrawable( + this.background(BackgroundDrawable( backgroundDrawable, borderRadius, borderWidth, diff --git a/core/src/main/java/com/guet/flexbox/widget/BackgroundDrawable.kt b/core/src/main/java/com/guet/flexbox/widget/BackgroundDrawable.kt new file mode 100644 index 00000000..b5520c9f --- /dev/null +++ b/core/src/main/java/com/guet/flexbox/widget/BackgroundDrawable.kt @@ -0,0 +1,35 @@ +package com.guet.flexbox.widget + +import android.graphics.Color +import android.graphics.drawable.Drawable +import com.facebook.litho.drawable.ComparableDrawable +import com.facebook.litho.drawable.ComparableDrawableWrapper + +internal class BackgroundDrawable( + drawable: Drawable, + radius: Int = 0, + width: Int = 0, + color: Int = Color.TRANSPARENT +) : ComparableDrawableWrapper(BorderDrawable(drawable, radius, width, color)) { + + override fun isEquivalentTo(other: ComparableDrawable?): Boolean { + if (other == this) { + return true + } + if (other is BackgroundDrawable) { + var inner = wrappedDrawable + while (inner is DrawableWrapper<*>) { + inner = inner.wrappedDrawable + } + var otherInner = other.wrappedDrawable + while (otherInner is DrawableWrapper<*>) { + otherInner = otherInner.wrappedDrawable + } + if (inner is ComparableDrawable && otherInner is ComparableDrawable) { + return ComparableDrawable.isEquivalentTo(inner, otherInner) + } + } + return false + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/guet/flexbox/widget/DrawableWrapper.kt b/core/src/main/java/com/guet/flexbox/widget/DrawableWrapper.kt index 6e9b4077..fc69e7a4 100644 --- a/core/src/main/java/com/guet/flexbox/widget/DrawableWrapper.kt +++ b/core/src/main/java/com/guet/flexbox/widget/DrawableWrapper.kt @@ -6,9 +6,11 @@ import android.graphics.drawable.Drawable import androidx.core.graphics.drawable.DrawableCompat -internal open class DrawableWrapper(drawable: T) : Drawable(), Drawable.Callback { +internal open class DrawableWrapper( + drawable: T +) : Drawable(), Drawable.Callback { - protected var wrappedDrawable: T = drawable.apply { callback = this@DrawableWrapper } + var wrappedDrawable: T = drawable.apply { callback = this@DrawableWrapper } set(value) { field.callback = null field = value diff --git a/core/src/main/java/com/guet/flexbox/widget/MatrixDrawable.java b/core/src/main/java/com/guet/flexbox/widget/MatrixDrawable.java index 7324c546..54b6221a 100644 --- a/core/src/main/java/com/guet/flexbox/widget/MatrixDrawable.java +++ b/core/src/main/java/com/guet/flexbox/widget/MatrixDrawable.java @@ -44,6 +44,7 @@ final class MatrixDrawable extends Drawable implements Drawable.Callback, Touchable { private static final int UNSET = -1; + private static final int[] EMPTY = new int[0]; private Drawable mDrawable; private DrawableMatrix mMatrix; @@ -203,7 +204,7 @@ public boolean setState(@NonNull final int[] stateSet) { @Override public @NonNull int[] getState() { - return mDrawable == null ? new int[0] : mDrawable.getState(); + return mDrawable == null ? EMPTY : mDrawable.getState(); } @Override diff --git a/core/src/main/java/com/guet/flexbox/widget/NetworkDrawable.kt b/core/src/main/java/com/guet/flexbox/widget/NetworkDrawable.kt deleted file mode 100644 index 7cc98424..00000000 --- a/core/src/main/java/com/guet/flexbox/widget/NetworkDrawable.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.guet.flexbox.widget - -import android.content.Context -import android.graphics.drawable.Drawable -import com.bumptech.glide.Glide -import com.bumptech.glide.request.target.CustomTarget -import com.bumptech.glide.request.transition.Transition - -internal class NetworkDrawable( - width: Int, - height: Int, - c: Context, - url: CharSequence) - : DrawableWrapper(NoOpDrawable()) { - - init { - Glide.with(c.applicationContext).load(url) - .into(DrawableTarget(width, height)) - } - - internal inner class DrawableTarget( - width: Int, - height: Int - ) : CustomTarget(width, height) { - override fun onLoadCleared(placeholder: Drawable?) { - if (placeholder != null) { - onResourceReady(placeholder, null) - } else { - onResourceReady(NoOpDrawable(), null) - } - } - - override fun onResourceReady( - resource: Drawable, - transition: Transition?) { - resource.bounds = bounds - wrappedDrawable = resource - invalidateSelf() - } - } - -} - diff --git a/core/src/main/java/com/guet/flexbox/widget/NetworkLazyDrawable.kt b/core/src/main/java/com/guet/flexbox/widget/NetworkLazyDrawable.kt new file mode 100644 index 00000000..cacca42f --- /dev/null +++ b/core/src/main/java/com/guet/flexbox/widget/NetworkLazyDrawable.kt @@ -0,0 +1,65 @@ +package com.guet.flexbox.widget + +import android.content.Context +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.text.TextUtils +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.facebook.litho.drawable.ComparableDrawable +import com.facebook.litho.drawable.ComparableDrawableWrapper +import java.util.concurrent.atomic.AtomicBoolean + +internal class NetworkLazyDrawable( + c: Context, + private val width: Int, + private val height: Int, + private val url: CharSequence) + : ComparableDrawableWrapper(NoOpDrawable()) { + + private val loaded = AtomicBoolean(false) + private val context = c.applicationContext + + override fun draw(canvas: Canvas) { + if (loaded.compareAndSet(false, true)) { + Glide.with(context).load(url) + .into(LazyTarget(width, height)) + } else { + super.draw(canvas) + } + } + + override fun isEquivalentTo(other: ComparableDrawable?): Boolean { + if (other == this) { + return true + } + if (other is NetworkLazyDrawable) { + return width == other.width + && height == other.height + && TextUtils.equals(url, other.url) + } + return false + } + + internal inner class LazyTarget( + width: Int, + height: Int + ) : CustomTarget(width, height) { + override fun onLoadCleared(placeholder: Drawable?) { + if (placeholder != null) { + onResourceReady(placeholder, null) + } else { + onResourceReady(NoOpDrawable(), null) + } + } + + override fun onResourceReady( + resource: Drawable, + transition: Transition?) { + resource.bounds = bounds + wrappedDrawable = NetworkMatrixDrawable.transition(null, resource) + invalidateSelf() + } + } +} \ No newline at end of file