From cee557b5f7fb345d26a89d40cdfdedf671e80742 Mon Sep 17 00:00:00 2001 From: Appcelerator Build Date: Tue, 23 Mar 2021 12:54:06 -0400 Subject: [PATCH] fix(android): amend TableViewRow reuse (#12642) * validate activity for ripple effect Fixes TIMOB-28399 --- .../modules/titanium/ui/TableViewProxy.java | 13 +++++++-- .../titanium/ui/TableViewRowProxy.java | 9 ++---- .../titanium/ui/TableViewSectionProxy.java | 6 ++-- .../widget/listview/TiRecyclerViewHolder.java | 28 +++++++++++-------- .../titanium/proxy/TiViewProxy.java | 22 +++++++++++++++ 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java index 7bd9a925a6d..cf8bd33ae8f 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java @@ -317,9 +317,14 @@ public void deleteRow(Object rowObj, @Kroll.argument(optional = true) KrollDict @Kroll.method public void deleteSection(int index, @Kroll.argument(optional = true) KrollDict animation) { - this.sections.remove(getSectionByIndex(index)); + final TableViewSectionProxy section = getSectionByIndex(index); - update(); + if (section != null) { + this.sections.remove(section); + section.setParent(null); + + update(); + } } @Override @@ -351,6 +356,10 @@ public Object[] getData() public void setData(Object[] data) // clang-format on { + for (final TableViewSectionProxy section : this.sections) { + section.releaseViews(); + section.setParent(null); + } this.sections.clear(); for (Object d : data) { diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewRowProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewRowProxy.java index 01b48408380..b82cc54a0c2 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewRowProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewRowProxy.java @@ -12,7 +12,6 @@ import java.util.List; import org.appcelerator.kroll.KrollDict; -import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.TiC; @@ -81,14 +80,10 @@ public TableViewRowProxy(boolean placeholder) * * @return TableViewRowProxy */ + @Override public TableViewRowProxy clone() { - final TableViewRowProxy proxy = (TableViewRowProxy) KrollProxy.createProxy( - this.getClass(), - getKrollObject(), - new Object[] { properties }, - this.creationUrl.url - ); + final TableViewRowProxy proxy = (TableViewRowProxy) super.clone(); // Reference clone, to update properties. clones.add(new WeakReference<>(proxy)); diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewSectionProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewSectionProxy.java index 80bfc96beb9..cc5516f5c89 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewSectionProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewSectionProxy.java @@ -48,7 +48,8 @@ public void add(int index, Object rowObj) if (row != null) { - if (row.getParent() != null) { + final TiViewProxy parent = row.getParent(); + if (parent != null && parent.getParent() != null) { // Row already exists, clone. row = row.clone(); @@ -79,7 +80,8 @@ public void add(Object rowObj) if (row != null) { - if (row.getParent() != null) { + final TiViewProxy parent = row.getParent(); + if (parent != null && parent.getParent() != null) { // Row already exists, clone. row = row.clone(); diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiRecyclerViewHolder.java b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiRecyclerViewHolder.java index 81411d730d8..3ccd1fa3e02 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiRecyclerViewHolder.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiRecyclerViewHolder.java @@ -110,19 +110,23 @@ public TiRecyclerViewHolder(final Context context, final ViewGroup viewGroup) */ protected Drawable generateRippleDrawable(Drawable drawable, String color) { - final int[][] rippleStates = new int[][] { new int[] { } }; - final TypedValue typedValue = new TypedValue(); final Activity activity = TiApplication.getAppCurrentActivity(); - final TypedArray colorControlHighlight = activity.obtainStyledAttributes( - typedValue.data, new int[] { android.R.attr.colorControlHighlight }); - final int colorControlHighlightInt = color != null && !color.isEmpty() - ? TiConvert.toColor(color) : colorControlHighlight.getColor(0, 0); - final int[] rippleColors = new int[] { colorControlHighlightInt }; - final ColorStateList colorStateList = new ColorStateList(rippleStates, rippleColors); - final ShapeDrawable maskDrawable = drawable == null ? new ShapeDrawable() : null; - - // Create the RippleDrawable. - drawable = new RippleDrawable(colorStateList, drawable, maskDrawable); + + if (activity != null) { + final int[][] rippleStates = new int[][] { new int[] {} }; + final TypedValue typedValue = new TypedValue(); + + final TypedArray colorControlHighlight = activity.obtainStyledAttributes( + typedValue.data, new int[] { android.R.attr.colorControlHighlight }); + final int colorControlHighlightInt = color != null && !color.isEmpty() + ? TiConvert.toColor(color) : colorControlHighlight.getColor(0, 0); + final int[] rippleColors = new int[] { colorControlHighlightInt }; + final ColorStateList colorStateList = new ColorStateList(rippleStates, rippleColors); + final ShapeDrawable maskDrawable = drawable == null ? new ShapeDrawable() : null; + + // Create the RippleDrawable. + drawable = new RippleDrawable(colorStateList, drawable, maskDrawable); + } return drawable; } diff --git a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiViewProxy.java b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiViewProxy.java index 1eb9cb66295..bf21e9fd270 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/proxy/TiViewProxy.java +++ b/android/titanium/src/java/org/appcelerator/titanium/proxy/TiViewProxy.java @@ -547,6 +547,28 @@ public void release() */ public abstract TiUIView createView(Activity activity); + /** + * Create clone of existing proxy, including children. + * + * @return TiViewProxy + */ + public TiViewProxy clone() + { + final TiViewProxy proxy = (TiViewProxy) KrollProxy.createProxy( + this.getClass(), + getKrollObject(), + new Object[] { properties }, + this.creationUrl.url + ); + + // Include children. + for (final TiViewProxy child : this.children) { + proxy.add(child.clone()); + } + + return proxy; + } + /** * Adds a child to this view proxy. * @param args The child view proxy/proxies to add.