react-native-navigation的迁移库

ScreenStack.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package com.reactnativenavigation.screens;
  2. import android.animation.LayoutTransition;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.widget.FrameLayout;
  5. import com.reactnativenavigation.params.ScreenParams;
  6. import com.reactnativenavigation.params.TitleBarButtonParams;
  7. import com.reactnativenavigation.params.TitleBarLeftButtonParams;
  8. import com.reactnativenavigation.views.TitleBarBackButtonListener;
  9. import java.util.List;
  10. import java.util.Stack;
  11. import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
  12. // TODO there's really no reason for ScreenStack to extend FrameLayout. All screens can be added to parent.
  13. public class ScreenStack extends FrameLayout implements TitleBarBackButtonListener {
  14. private final AppCompatActivity activity;
  15. private Stack<Screen> stack = new Stack<>();
  16. public ScreenStack(AppCompatActivity activity, ScreenParams initialScreenParams) {
  17. super(activity);
  18. this.activity = activity;
  19. setLayoutTransition(new LayoutTransition());
  20. pushInitialScreen(initialScreenParams);
  21. }
  22. private void pushInitialScreen(ScreenParams initialScreenParams) {
  23. addScreen(initialScreenParams);
  24. }
  25. public void push(ScreenParams screenParams) {
  26. Screen previous = stack.peek();
  27. addScreen(screenParams);
  28. removePreviousWithoutUnmount(previous);
  29. }
  30. private void addScreen(ScreenParams screenParams) {
  31. Screen screen = ScreenFactory.create(activity, screenParams, this);
  32. addView(screen, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
  33. stack.push(screen);
  34. }
  35. private void removePreviousWithoutUnmount(Screen previous) {
  36. previous.preventUnmountOnDetachedFromWindow();
  37. removeView(previous);
  38. }
  39. public void pop() {
  40. if (!canPop()) {
  41. throw new RuntimeException("Can't pop ScreenStack of size " + getStackSize());
  42. }
  43. Screen toRemove = stack.pop();
  44. Screen previous = stack.peek();
  45. readdPrevious(previous);
  46. toRemove.ensureUnmountOnDetachedFromWindow();
  47. removeView(toRemove);
  48. }
  49. private void readdPrevious(Screen previous) {
  50. addView(previous, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
  51. previous.preventMountAfterReattachedToWindow();
  52. }
  53. public void popToRoot() {
  54. while (canPop()) {
  55. pop();
  56. }
  57. }
  58. public void destroy() {
  59. for (Screen screen : stack) {
  60. screen.ensureUnmountOnDetachedFromWindow();
  61. removeView(screen);
  62. }
  63. stack.clear();
  64. }
  65. public int getStackSize() {
  66. return stack.size();
  67. }
  68. public boolean canPop() {
  69. return getStackSize() > 1;
  70. }
  71. public void setTopBarVisible(String screenInstanceId, boolean visible, boolean animate) {
  72. Screen screen = findScreenByScreenInstanceId(screenInstanceId);
  73. if (screen != null) {
  74. screen.setTopBarVisible(visible, animate);
  75. }
  76. }
  77. public Screen findScreenByScreenInstanceId(String screenInstanceId) {
  78. if (stack.isEmpty()) {
  79. return null;
  80. }
  81. for (Screen screen : stack) {
  82. if (screen.getScreenInstanceId().equals(screenInstanceId)) {
  83. return screen;
  84. }
  85. }
  86. return null;
  87. }
  88. public void setTitleBarTitle(String screenInstanceId, String title) {
  89. Screen screen = findScreenByScreenInstanceId(screenInstanceId);
  90. if (screen != null) {
  91. screen.setTitleBarTitle(title);
  92. }
  93. }
  94. public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
  95. Screen screen = findScreenByScreenInstanceId(screenInstanceId);
  96. if (screen != null) {
  97. screen.setTitleBarRightButtons(navigatorEventId, titleBarButtons);
  98. }
  99. }
  100. public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
  101. Screen screen = findScreenByScreenInstanceId(screenInstanceId);
  102. if (screen != null) {
  103. screen.setTitleBarLeftButton(navigatorEventId, this, titleBarLeftButtonParams);
  104. }
  105. }
  106. @Override
  107. public void onTitleBarBackPress() {
  108. if (canPop()) {
  109. pop();
  110. }
  111. }
  112. public void preventUnmountOnDetachedFromWindow() {
  113. for (Screen screen : stack) {
  114. screen.preventUnmountOnDetachedFromWindow();
  115. }
  116. }
  117. public void ensureUnmountOnDetachedFromWindow() {
  118. for (Screen screen : stack) {
  119. screen.ensureUnmountOnDetachedFromWindow();
  120. }
  121. }
  122. public void preventMountAfterReatachedToWindow() {
  123. for (Screen screen : stack) {
  124. screen.preventMountAfterReattachedToWindow();
  125. }
  126. }
  127. }