Skip to content

Commit

Permalink
fix(android): performance issue with deeply nested views as of 7.5.0 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jquick-axway authored and lokeshchdhry committed Oct 3, 2019
1 parent 599b223 commit 057dad3
Showing 1 changed file with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -94,6 +95,13 @@ public enum LayoutArrangement {
*/
private int childFillHeight = -1;

/**
* The last window insets object received by the onApplyWindowInsets() method.
* This object is immutable. Will be null if not received yet or has been cleared.
* Note: This references an Android 5.0 class. Do NOT access it in older Android OS versions.
*/
private WindowInsets previousInsets;

private WeakReference<TiViewProxy> proxy;

// We need these two constructors for backwards compatibility with modules
Expand Down Expand Up @@ -464,6 +472,13 @@ public WindowInsets onApplyWindowInsets(WindowInsets insets)
return null;
}

// Do not propagate given insets to child views unless the insets have changed.
// This greatly improves performance if we have deeply nested views since each view will trigger a relayout.
if (insets.equals(this.previousInsets)) {
return insets;
}
this.previousInsets = insets;

// Apply insets to all child views and don't let them consume given insets.
// We must do this since a "composite" layout supports overlapping views.
final int childCount = getChildCount();
Expand All @@ -476,6 +491,49 @@ public WindowInsets onApplyWindowInsets(WindowInsets insets)
return insets;
}

/**
* Requests parent view (and the parent's parent) to redispatch system insets to all child views.
* This method should be called when dynamically adding views that have setFitsSystemWindows() set to true.
*/
@Override
public void requestApplyInsets()
{
// The super class' method is only supported on Android 5.0 and higher.
if (Build.VERSION.SDK_INT < 20) {
return;
}

// Clear last stored insets and then request parent to redispatch system insets to all child views.
this.previousInsets = null;
super.requestApplyInsets();
}

/**
* Requests parent view (and the parent's parent) to redispatch system insets to all child views.
* This method should be called when dynamically adding views that have setFitsSystemWindows() set to true.
*/
@Override
public void requestFitSystemWindows()
{
// Clear last stored insets and then request parent to redispatch system insets to all child views.
if (Build.VERSION.SDK_INT >= 20) {
this.previousInsets = null;
}
super.requestFitSystemWindows();
}

/** Called when this view has been detached/removed from the activity window. */
@Override
protected void onDetachedFromWindow()
{
super.onDetachedFromWindow();

// Clear last stored insets received by the onApplyWindowInsets() method.
if (Build.VERSION.SDK_INT >= 20) {
this.previousInsets = null;
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
Expand Down

0 comments on commit 057dad3

Please sign in to comment.