From a3a4207afcb2019473a55d2793f0d70ed04e5e06 Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Tue, 22 Aug 2023 21:20:07 +0530 Subject: [PATCH] fix(xml-inflater): 'layout' attribute in tags is not preserved while inflating layouts (closes #1214) --- .../itsaky/androidide/uidesigner/undo/AttrAddedAction.kt | 2 +- .../src/main/java/com/itsaky/androidide/inflater/IView.kt | 7 +++++-- .../androidide/inflater/internal/ImmutableViewImpl.kt | 2 +- .../androidide/inflater/internal/LayoutInflaterImpl.kt | 7 ++----- .../com/itsaky/androidide/inflater/internal/ViewImpl.kt | 8 +++++++- .../androidide/inflater/internal/adapters/ViewAdapter.kt | 5 +++++ 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/undo/AttrAddedAction.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/undo/AttrAddedAction.kt index 4f1d321750..8ef22db754 100644 --- a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/undo/AttrAddedAction.kt +++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/undo/AttrAddedAction.kt @@ -33,6 +33,6 @@ internal class AttrAddedAction(view: com.itsaky.androidide.inflater.IView, attr: } override fun redo() { - view.addAttribute(attr, true) + view.addAttribute(attr, update = true) } } diff --git a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/IView.kt b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/IView.kt index dfcc3f04ae..b50ff31f7f 100644 --- a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/IView.kt +++ b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/IView.kt @@ -52,8 +52,11 @@ interface IView { * Add and apply the given attribute to this view. * * @param attribute The attribute to apply. + * @param apply Whether the attribute should be applied to the attribute. If this `false` then the + * attribute will be simply added to the attributes list. + * @param update Whether the attribute's value should be updated if the attribute is already applied to this view. */ - fun addAttribute(attribute: IAttribute, update: Boolean = false) + fun addAttribute(attribute: IAttribute, apply: Boolean = true, update: Boolean = false) /** * Remove the given attribute and update the view accordingly. @@ -185,7 +188,7 @@ interface IView { override fun onAttributeAdded(view: IView, attribute: IAttribute) {} override fun onAttributeRemoved(view: IView, attribute: IAttribute) {} override fun onAttributeUpdated(view: IView, attribute: IAttribute, - oldValue: String + oldValue: String ) { } } diff --git a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ImmutableViewImpl.kt b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ImmutableViewImpl.kt index 3feb1b43cf..9510a8eb92 100644 --- a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ImmutableViewImpl.kt +++ b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ImmutableViewImpl.kt @@ -28,7 +28,7 @@ import com.itsaky.androidide.inflater.IView.AttributeChangeListener */ class ImmutableViewImpl(private val src: ViewImpl) : IView by src { - override fun addAttribute(attribute: IAttribute, update: Boolean) { + override fun addAttribute(attribute: IAttribute, apply: Boolean, update: Boolean) { throw UnsupportedOperationException("Immutable!") } diff --git a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/LayoutInflaterImpl.kt b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/LayoutInflaterImpl.kt index 1a5cbe5cf5..50a2d92692 100644 --- a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/LayoutInflaterImpl.kt +++ b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/LayoutInflaterImpl.kt @@ -217,7 +217,7 @@ open class LayoutInflaterImpl : ILayoutInflater { view: ViewImpl, parent: IViewGroup, attachToParent: Boolean = true, - checkAttr: (XmlAttribute) -> Boolean = { true } + shouldApplyAttr: (XmlAttribute) -> Boolean = { true } ) { val parentView = parent.view as ViewGroup val adapter = @@ -233,16 +233,13 @@ open class LayoutInflaterImpl : ILayoutInflater { if (element.attributeCount > 0) { for (xmlAttribute in element.attributeList) { - if (!checkAttr(xmlAttribute)) { - continue - } val namespace = if (xmlAttribute.namespaceUri.isNullOrBlank()) null else view.findNamespaceByUri(xmlAttribute.namespaceUri) val attr = onCreateAttribute(view, namespace, xmlAttribute.name, xmlAttribute.value) - view.addAttribute(attribute = attr, update = true) + view.addAttribute(attribute = attr, apply = shouldApplyAttr(xmlAttribute), update = true) inflationEventListener?.onEvent(OnApplyAttributeEvent(view, attr)) } } diff --git a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ViewImpl.kt b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ViewImpl.kt index 5300ca2410..25d23d8ce4 100644 --- a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ViewImpl.kt +++ b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/ViewImpl.kt @@ -56,7 +56,7 @@ constructor( override val attributes: List get() = this._attributes - override fun addAttribute(attribute: IAttribute, update: Boolean) { + override fun addAttribute(attribute: IAttribute, apply: Boolean, update: Boolean) { if (hasAttribute(attribute)) { if (!update) { return @@ -64,6 +64,12 @@ constructor( updateAttribute(attribute) } else { this._attributes.add(attribute) + + if (!apply) { + // attribute should not be applied + return + } + applyAttribute(attribute) notifyAttrAdded(attribute) } diff --git a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/adapters/ViewAdapter.kt b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/adapters/ViewAdapter.kt index a48396b2e2..afd6e2751f 100644 --- a/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/adapters/ViewAdapter.kt +++ b/xml-inflater/src/main/java/com/itsaky/androidide/inflater/internal/adapters/ViewAdapter.kt @@ -38,6 +38,7 @@ import com.itsaky.androidide.inflater.IAttribute import com.itsaky.androidide.inflater.INamespace import com.itsaky.androidide.inflater.IView import com.itsaky.androidide.inflater.IViewAdapter +import com.itsaky.androidide.inflater.internal.IncludeView import com.itsaky.androidide.resources.R import com.itsaky.androidide.inflater.models.UiWidget import com.itsaky.androidide.inflater.utils.newAttribute @@ -143,6 +144,10 @@ open class ViewAdapter : IViewAdapter() { } override fun applyBasic(view: IView) { + if (view is IncludeView) { + return + } + view.addAttribute(newAttribute(view = view, name = "layout_height", value = "wrap_content")) view.addAttribute(newAttribute(view = view, name = "layout_width", value = "wrap_content")) }