diff --git a/packages/core/platforms/android/widgets-release.aar b/packages/core/platforms/android/widgets-release.aar index 069e06470..aeee5c318 100644 Binary files a/packages/core/platforms/android/widgets-release.aar and b/packages/core/platforms/android/widgets-release.aar differ diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/GridLayout.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/GridLayout.java index ff362ea94..68bc9b5ce 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/GridLayout.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/GridLayout.java @@ -223,8 +223,9 @@ public class GridLayout extends LayoutBase { } private void removeFromMap(View child) { - this.map.get(child).child = null; - this.map.remove(child); + if (this.map.containsKey(child)) { + this.map.remove(child).child = null; + } } @Override diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/HorizontalScrollView.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/HorizontalScrollView.java index f988fc076..dc5ec0643 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/HorizontalScrollView.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/HorizontalScrollView.java @@ -2,17 +2,13 @@ package org.nativescript.widgets; import android.content.Context; import android.graphics.Rect; -import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewParent; import android.widget.FrameLayout; -import androidx.annotation.NonNull; - /** * @author hhristov */ @@ -23,7 +19,7 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { private int contentMeasuredWidth = 0; private int contentMeasuredHeight = 0; private int scrollableLength = 0; - private SavedState mSavedState; + private ScrollSavedState mSavedState; private boolean isFirstLayout = true; private boolean scrollEnabled = true; @@ -180,7 +176,7 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { this.mIsLayoutDirty = false; // Give a child focus if it needs it - if (this.mChildToScrollTo != null && isViewDescendantOf(this.mChildToScrollTo, this)) { + if (this.mChildToScrollTo != null && Utils.isViewDescendantOf(this.mChildToScrollTo, this)) { this.scrollToChild(this.mChildToScrollTo); } @@ -194,7 +190,7 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { final int scrollRange = Math.max(0, childWidth - (right - left - this.getPaddingLeft() - this.getPaddingRight())); if (this.mSavedState != null) { - scrollX = (this.isLayoutRtl() == mSavedState.isLayoutRtl) ? mSavedState.scrollPosition : (scrollRange - this.mSavedState.scrollPosition); + scrollX = this.isLayoutRtl() ? scrollRange - mSavedState.scrollOffsetFromStart : mSavedState.scrollOffsetFromStart; mSavedState = null; } else { if (this.isLayoutRtl()) { @@ -228,7 +224,7 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { @Override protected void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; + ScrollSavedState ss = (ScrollSavedState) state; super.onRestoreInstanceState(ss.getSuperState()); this.mSavedState = ss; this.requestLayout(); @@ -237,9 +233,8 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.scrollPosition = this.getScrollX(); - ss.isLayoutRtl = this.isLayoutRtl(); + ScrollSavedState ss = new ScrollSavedState(superState); + ss.scrollOffsetFromStart = isLayoutRtl() ? -this.getScrollX() : this.getScrollX(); return ss; } @@ -258,58 +253,4 @@ public class HorizontalScrollView extends android.widget.HorizontalScrollView { private boolean isLayoutRtl() { return (this.getLayoutDirection() == LAYOUT_DIRECTION_RTL); } - - /** - * Return true if child is a descendant of parent, (or equal to the parent). - */ - static boolean isViewDescendantOf(View child, View parent) { - if (child == parent) { - return true; - } - - final ViewParent theParent = child.getParent(); - return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent); - } - - static class SavedState extends BaseSavedState { - public int scrollPosition; - public boolean isLayoutRtl; - - SavedState(Parcelable superState) { - super(superState); - } - - public SavedState(Parcel source) { - super(source); - scrollPosition = source.readInt(); - isLayoutRtl = source.readInt() == 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeInt(scrollPosition); - dest.writeInt(isLayoutRtl ? 1 : 0); - } - - @NonNull - @Override - public String toString() { - return "HorizontalScrollView.SavedState{" - + Integer.toHexString(System.identityHashCode(this)) - + " scrollPosition=" + scrollPosition - + " isLayoutRtl=" + isLayoutRtl + "}"; - } - - public static final Creator CREATOR - = new Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } } diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/ScrollSavedState.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/ScrollSavedState.java new file mode 100644 index 000000000..c29e4fcc3 --- /dev/null +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/ScrollSavedState.java @@ -0,0 +1,63 @@ +package org.nativescript.widgets; + +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.View.BaseSavedState; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +/** + * @author CatchABus + */ +class ScrollSavedState extends BaseSavedState { + public int scrollOffsetFromStart; + + ScrollSavedState(Parcelable superState) { + super(superState); + } + + public ScrollSavedState(Parcel source) { + super(source); + scrollOffsetFromStart = source.readInt(); + } + + @RequiresApi(Build.VERSION_CODES.N) + public ScrollSavedState(Parcel source, ClassLoader loader) { + super(source, loader); + scrollOffsetFromStart = source.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(scrollOffsetFromStart); + } + + @NonNull + @Override + public String toString() { + return "ScrollSavedState{" + + Integer.toHexString(System.identityHashCode(this)) + + " scrollPosition=" + scrollOffsetFromStart + + "}"; + } + + public static final Creator CREATOR = new ClassLoaderCreator() { + public ScrollSavedState createFromParcel(Parcel in, ClassLoader loader) + { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new ScrollSavedState(in, loader) : new ScrollSavedState(in); + } + + @Override + public ScrollSavedState createFromParcel(Parcel in) + { + return createFromParcel(in, null); + } + + public ScrollSavedState[] newArray(int size) { + return new ScrollSavedState[size]; + } + }; +} \ No newline at end of file diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/Utils.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/Utils.java index 7706174ab..f46ce2dd7 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/Utils.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/Utils.java @@ -21,6 +21,7 @@ import android.util.Log; import android.util.Pair; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.view.ViewCompat; @@ -512,6 +513,18 @@ public class Utils { }); } + /** + * Return true if child is a descendant of parent, (or equal to the parent). + */ + static boolean isViewDescendantOf(View child, View parent) { + if (child == parent) { + return true; + } + + final ViewParent childParent = child.getParent(); + return (childParent instanceof ViewGroup) && isViewDescendantOf((View) childParent, parent); + } + // public static void clearBoxShadow(View view) { // if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { // return; diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/VerticalScrollView.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/VerticalScrollView.java index bb7c35593..8d8e08dc2 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/VerticalScrollView.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/VerticalScrollView.java @@ -10,8 +10,6 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.core.widget.NestedScrollView; -import org.nativescript.widgets.HorizontalScrollView.SavedState; - /** * @author hhristov */ @@ -22,7 +20,7 @@ public class VerticalScrollView extends NestedScrollView { private int contentMeasuredWidth = 0; private int contentMeasuredHeight = 0; private int scrollableLength = 0; - private SavedState mSavedState; + private ScrollSavedState mSavedState; private boolean isFirstLayout = true; private boolean scrollEnabled = true; @@ -186,7 +184,7 @@ public class VerticalScrollView extends NestedScrollView { this.mIsLayoutDirty = false; // Give a child focus if it needs it - if (this.mChildToScrollTo != null && HorizontalScrollView.isViewDescendantOf(this.mChildToScrollTo, this)) { + if (this.mChildToScrollTo != null && Utils.isViewDescendantOf(this.mChildToScrollTo, this)) { this.scrollToChild(this.mChildToScrollTo); } @@ -200,7 +198,7 @@ public class VerticalScrollView extends NestedScrollView { final int scrollRange = Math.max(0, childHeight - (bottom - top - this.getPaddingTop() - this.getPaddingBottom())); if (this.mSavedState != null) { - scrollY = mSavedState.scrollPosition; + scrollY = mSavedState.scrollOffsetFromStart; mSavedState = null; } @@ -232,7 +230,7 @@ public class VerticalScrollView extends NestedScrollView { @Override protected void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; + ScrollSavedState ss = (ScrollSavedState) state; super.onRestoreInstanceState(ss.getSuperState()); this.mSavedState = ss; this.requestLayout(); @@ -241,8 +239,8 @@ public class VerticalScrollView extends NestedScrollView { @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.scrollPosition = this.getScrollY(); + ScrollSavedState ss = new ScrollSavedState(superState); + ss.scrollOffsetFromStart = this.getScrollY(); return ss; }