-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This pr adds support for changing tab initialisation mode. Currently bottom tabs are attached together and consequently, their corresponding react root views are created and rendered. This adds lots of stress on the js thread and hiders app start time. To mitigate this issue, this pr adds support for three modes * `together` (default, current behaviour) - all tabs are loaded together, adding unnecessary load on the js thread as we're loading invisible views, which leads to increased app start time. * `afterInitialTab` - Initial tab is loaded first. After it is rendered, other tabs are loaded as well. This should shave a few hunderdish ms from app start time. Since other tabs are loaded after the initial tab is visible, the ui might be unresponsive for a few hunderdish ms as multiple root views (which are typically complex) are being created and attached to hierarchy at once. * `onSwitchToTab` - initial tab is loaded. Other tabs are loaded when switching to them (tab click or programmatically). While this won't stress js thread after initial tab is rendered, there will be a flicker when entering a tab for the first time as it's ui isn't ready.
- Loading branch information
Showing
29 changed files
with
547 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
lib/android/app/src/main/java/com/reactnativenavigation/parse/TabsAttachMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.reactnativenavigation.parse; | ||
|
||
public enum TabsAttachMode { | ||
TOGETHER, | ||
AFTER_INITIAL_TAB, | ||
ON_SWITCH_TO_TAB, | ||
UNDEFINED; | ||
|
||
public static TabsAttachMode fromString(String mode) { | ||
switch (mode) { | ||
case "together": | ||
return TOGETHER; | ||
case "afterInitialTab": | ||
return AFTER_INITIAL_TAB; | ||
case "onSwitchToTab": | ||
return ON_SWITCH_TO_TAB; | ||
default: | ||
return UNDEFINED; | ||
} | ||
} | ||
|
||
public boolean hasValue() { | ||
return this != UNDEFINED; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...p/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/AfterInitialTab.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.reactnativenavigation.viewcontrollers.bottomtabs; | ||
|
||
import android.view.*; | ||
|
||
import com.reactnativenavigation.parse.*; | ||
import com.reactnativenavigation.presentation.*; | ||
import com.reactnativenavigation.viewcontrollers.*; | ||
|
||
import java.util.*; | ||
|
||
import static com.reactnativenavigation.utils.CollectionUtils.filter; | ||
import static com.reactnativenavigation.utils.CollectionUtils.forEach; | ||
|
||
public class AfterInitialTab extends AttachMode { | ||
private final Runnable attachOtherTabs; | ||
|
||
public AfterInitialTab(ViewGroup parent, List<ViewController> tabs, BottomTabsPresenter presenter, Options resolved) { | ||
super(parent, tabs, presenter, resolved); | ||
attachOtherTabs = () -> forEach(otherTabs(), this::attach); | ||
} | ||
|
||
@Override | ||
public void attach() { | ||
initialTab.addOnAppearedListener(attachOtherTabs); | ||
attach(initialTab); | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
initialTab.removeOnAppearedListener(attachOtherTabs); | ||
} | ||
|
||
private List<ViewController> otherTabs() { | ||
return filter(tabs, t -> t != initialTab); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
...id/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/AttachMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.reactnativenavigation.viewcontrollers.bottomtabs; | ||
|
||
import android.support.annotation.*; | ||
import android.view.*; | ||
import android.widget.*; | ||
|
||
import com.reactnativenavigation.parse.*; | ||
import com.reactnativenavigation.presentation.*; | ||
import com.reactnativenavigation.viewcontrollers.*; | ||
|
||
import java.util.*; | ||
|
||
import static android.view.ViewGroup.LayoutParams.*; | ||
|
||
public abstract class AttachMode { | ||
protected final ViewGroup parent; | ||
protected final BottomTabsPresenter presenter; | ||
protected final List<ViewController> tabs; | ||
final ViewController initialTab; | ||
private final Options resolved; | ||
|
||
|
||
public static AttachMode get(ViewGroup parent, List<ViewController> tabs, BottomTabsPresenter presenter, Options resolved) { | ||
switch (resolved.bottomTabsOptions.tabsAttachMode) { | ||
case AFTER_INITIAL_TAB: | ||
return new AfterInitialTab(parent, tabs, presenter, resolved); | ||
case ON_SWITCH_TO_TAB: | ||
return new OnSwitchToTab(parent, tabs, presenter, resolved); | ||
case UNDEFINED: | ||
case TOGETHER: | ||
default: | ||
return new Together(parent, tabs, presenter, resolved); | ||
} | ||
} | ||
|
||
AttachMode(ViewGroup parent, List<ViewController> tabs, BottomTabsPresenter presenter, Options resolved) { | ||
this.parent = parent; | ||
this.tabs = tabs; | ||
this.presenter = presenter; | ||
this.resolved = resolved; | ||
initialTab = tabs.get(resolved.bottomTabsOptions.currentTabIndex.get(0)); | ||
} | ||
|
||
public abstract void attach(); | ||
|
||
public void destroy() { | ||
|
||
} | ||
|
||
public void onTabSelected(ViewController tab) { | ||
|
||
} | ||
|
||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) | ||
public void attach(ViewController tab) { | ||
ViewGroup view = tab.getView(); | ||
view.setLayoutParams(new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); | ||
presenter.applyLayoutParamsOptions(resolved, tabs.indexOf(tab)); | ||
view.setVisibility(tab == initialTab ? View.VISIBLE : View.INVISIBLE); | ||
parent.addView(view); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
...rc/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAttacher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.reactnativenavigation.viewcontrollers.bottomtabs; | ||
|
||
import android.support.annotation.VisibleForTesting; | ||
import android.view.ViewGroup; | ||
|
||
import com.reactnativenavigation.parse.Options; | ||
import com.reactnativenavigation.presentation.BottomTabsPresenter; | ||
import com.reactnativenavigation.viewcontrollers.ViewController; | ||
|
||
import java.util.List; | ||
|
||
public class BottomTabsAttacher { | ||
private final List<ViewController> tabs; | ||
private final BottomTabsPresenter presenter; | ||
@VisibleForTesting | ||
AttachMode attachStrategy; | ||
|
||
public BottomTabsAttacher(List<ViewController> tabs, BottomTabsPresenter presenter) { | ||
this.tabs = tabs; | ||
this.presenter = presenter; | ||
} | ||
|
||
void init(ViewGroup parent, Options resolved) { | ||
attachStrategy = AttachMode.get(parent, tabs, presenter, resolved); | ||
} | ||
|
||
void attach() { | ||
attachStrategy.attach(); | ||
} | ||
|
||
public void destroy() { | ||
attachStrategy.destroy(); | ||
} | ||
|
||
void onTabSelected(ViewController tab) { | ||
attachStrategy.onTabSelected(tab); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.