Pārlūkot izejas kodu

Additional work on BottomTabs

Guy Carmeli 8 gadus atpakaļ
vecāks
revīzija
80b11fb522

+ 42
- 31
android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java Parādīt failu

6
 import android.widget.RelativeLayout;
6
 import android.widget.RelativeLayout;
7
 
7
 
8
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
8
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
9
-import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
10
 import com.reactnativenavigation.params.ActivityParams;
9
 import com.reactnativenavigation.params.ActivityParams;
11
 import com.reactnativenavigation.params.ScreenParams;
10
 import com.reactnativenavigation.params.ScreenParams;
12
 import com.reactnativenavigation.params.TitleBarButtonParams;
11
 import com.reactnativenavigation.params.TitleBarButtonParams;
25
     private final AppCompatActivity activity;
24
     private final AppCompatActivity activity;
26
     private ActivityParams params;
25
     private ActivityParams params;
27
     private BottomTabs bottomTabs;
26
     private BottomTabs bottomTabs;
28
-    private ArrayList<ScreenStack> screenStacks;
27
+    private ScreenStack[] screenStacks;
29
     private int currentStackIndex = 0;
28
     private int currentStackIndex = 0;
30
 
29
 
31
     public BottomTabsLayout(AppCompatActivity activity, ActivityParams params) {
30
     public BottomTabsLayout(AppCompatActivity activity, ActivityParams params) {
32
         super(activity);
31
         super(activity);
33
         this.activity = activity;
32
         this.activity = activity;
34
         this.params = params;
33
         this.params = params;
35
-        screenStacks = new ArrayList<>();
34
+        screenStacks = new ScreenStack[(params.tabParams.size())];
36
         createLayout();
35
         createLayout();
37
     }
36
     }
38
 
37
 
45
     private void createBottomTabs() {
44
     private void createBottomTabs() {
46
         bottomTabs = new BottomTabs(getContext());
45
         bottomTabs = new BottomTabs(getContext());
47
         setBottomTabsStyle();
46
         setBottomTabsStyle();
48
-        addTabs();
47
+        bottomTabs.addTabs(params.tabParams, this);
49
     }
48
     }
50
 
49
 
51
     private void addBottomTabsToScreen() {
50
     private void addBottomTabsToScreen() {
55
     }
54
     }
56
 
55
 
57
     private void addInitialScreen() {
56
     private void addInitialScreen() {
58
-        addView(getFirstScreenStack());
57
+        createAndAddScreenStack(0);
59
     }
58
     }
60
 
59
 
61
     private void setBottomTabsStyle() {
60
     private void setBottomTabsStyle() {
66
 //        bottomTabs.setAccentColor(getColor(style, TAB_STYLE_SELECTED_COLOR, DEFAULT_TAB_SELECTED_COLOR));
65
 //        bottomTabs.setAccentColor(getColor(style, TAB_STYLE_SELECTED_COLOR, DEFAULT_TAB_SELECTED_COLOR));
67
     }
66
     }
68
 
67
 
69
-    private void addTabs() {
70
-        for (ScreenParams screenParams : params.tabParams) {
71
-            ScreenStack stack = new ScreenStack(activity, screenParams);
72
-            screenStacks.add(stack);
73
-
74
-            AHBottomNavigationItem item = new AHBottomNavigationItem(screenParams.title, screenParams.tabIcon,
75
-                    Color.GRAY);
76
-            bottomTabs.addItem(item);
77
-            bottomTabs.setOnTabSelectedListener(this);
78
-        }
79
-    }
80
-
81
     @Override
68
     @Override
82
     public View asView() {
69
     public View asView() {
83
         return this;
70
         return this;
85
 
72
 
86
     @Override
73
     @Override
87
     public boolean onBackPressed() {
74
     public boolean onBackPressed() {
88
-        return false;
75
+        if (getCurrentScreenStack().canPop()) {
76
+            getCurrentScreenStack().pop();
77
+            return true;
78
+        } else {
79
+            return false;
80
+        }
89
     }
81
     }
90
 
82
 
91
     @Override
83
     @Override
92
     public void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
84
     public void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
93
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
85
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
94
-            screenStacks.get(i).setTopBarVisible(screenInstanceId, hidden, animated);
86
+            screenStacks[i].setTopBarVisible(screenInstanceId, hidden, animated);
95
         }
87
         }
96
     }
88
     }
97
 
89
 
98
     @Override
90
     @Override
99
     public void setTitleBarTitle(String screenInstanceId, String title) {
91
     public void setTitleBarTitle(String screenInstanceId, String title) {
100
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
92
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
101
-            screenStacks.get(i).setTitleBarTitle(screenInstanceId, title);
93
+            screenStacks[i].setTitleBarTitle(screenInstanceId, title);
102
         }
94
         }
103
     }
95
     }
104
 
96
 
105
     @Override
97
     @Override
106
     public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
98
     public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
107
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
99
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
108
-            screenStacks.get(i).setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
100
+            screenStacks[i].setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
109
         }
101
         }
110
     }
102
     }
111
 
103
 
112
     @Override
104
     @Override
113
     public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
105
     public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
114
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
106
         for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
115
-            screenStacks.get(i).setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButtonParams);
107
+            screenStacks[i].setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButtonParams);
116
         }
108
         }
117
     }
109
     }
118
 
110
 
137
         currentScreenStack.destroy();
129
         currentScreenStack.destroy();
138
         removeView(currentScreenStack);
130
         removeView(currentScreenStack);
139
 
131
 
140
-        ScreenStack newStack = new ScreenStack(activity, params);
141
-        screenStacks.set(currentStackIndex, newStack);
132
+        ScreenStack newStack = new ScreenStack(getContext(), params);
133
+        screenStacks[currentStackIndex] = newStack;
142
         addView(newStack, 0, new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
134
         addView(newStack, 0, new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
143
     }
135
     }
144
 
136
 
145
     @Override
137
     @Override
146
     public void destroy() {
138
     public void destroy() {
147
-
139
+        for (ScreenStack screenStack : screenStacks) {
140
+            screenStack.destroy();
141
+            removeView(screenStack);
142
+        }
143
+        screenStacks = null;
148
     }
144
     }
149
 
145
 
150
     @Override
146
     @Override
151
     public void onTabSelected(int position, boolean wasSelected) {
147
     public void onTabSelected(int position, boolean wasSelected) {
152
-        removeView(getCurrentScreenStack());
153
-        addView(screenStacks.get(position), 0, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
148
+        removeCurrentStack();
149
+
150
+        ScreenStack newStack = screenStacks[position];
151
+        if (newStack == null) {
152
+            createAndAddScreenStack(position);
153
+        } else {
154
+            addView(newStack, 0, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
155
+            newStack.preventMountAfterReatachedToWindow();
156
+        }
154
         currentStackIndex = position;
157
         currentStackIndex = position;
155
     }
158
     }
156
 
159
 
157
-    private ScreenStack getCurrentScreenStack() {
158
-        return screenStacks.get(currentStackIndex);
160
+    private void createAndAddScreenStack(int position) {
161
+        ScreenStack newStack = new ScreenStack(getContext(), params.tabParams.get(position));
162
+        screenStacks[position] = newStack;
163
+        addView(newStack, 0, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
159
     }
164
     }
160
 
165
 
161
-    private ScreenStack getFirstScreenStack() {
162
-        return screenStacks.get(0);
166
+    private void removeCurrentStack() {
167
+        ScreenStack currentScreenStack = getCurrentScreenStack();
168
+        currentScreenStack.preventUnmountOnDetachedFromWindow();
169
+        removeView(currentScreenStack);
170
+    }
171
+
172
+    private ScreenStack getCurrentScreenStack() {
173
+        return screenStacks[currentStackIndex];
163
     }
174
     }
164
 }
175
 }

+ 8
- 2
android/app/src/main/java/com/reactnativenavigation/react/ReactViewHacks.java Parādīt failu

10
     }
10
     }
11
 
11
 
12
     /**
12
     /**
13
-     * Must be called before view is removed from screen inorder to ensure onDetachedFromScreen is properly
14
-     * executed and componentWillUnmount is called
13
+     * Side effect: prevents JS components constructor from being called
15
      */
14
      */
16
     public static void ensureUnmountOnDetachedFromWindow(ReactRootView view) {
15
     public static void ensureUnmountOnDetachedFromWindow(ReactRootView view) {
17
         ReflectionUtils.setField(view, "mAttachScheduled", false);
16
         ReflectionUtils.setField(view, "mAttachScheduled", false);
18
     }
17
     }
19
 
18
 
19
+    /**
20
+     * Side effect: ensures unmount will be called
21
+     */
22
+    public static void preventMountAfterReattachedToWindow(ReactRootView view) {
23
+        ReflectionUtils.setField(view, "mAttachScheduled", false);
24
+    }
25
+
20
 }
26
 }

+ 2
- 0
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java Parādīt failu

131
 
131
 
132
     public abstract void preventUnmountOnDetachedFromWindow();
132
     public abstract void preventUnmountOnDetachedFromWindow();
133
 
133
 
134
+    public abstract void preventMountAfterReattachedToWindow();
135
+
134
     public String getScreenInstanceId() {
136
     public String getScreenInstanceId() {
135
         return screenParams.screenInstanceId;
137
         return screenParams.screenInstanceId;
136
     }
138
     }

+ 18
- 0
android/app/src/main/java/com/reactnativenavigation/screens/ScreenStack.java Parādīt failu

135
             pop();
135
             pop();
136
         }
136
         }
137
     }
137
     }
138
+
139
+    public void preventUnmountOnDetachedFromWindow() {
140
+        for (Screen screen : stack) {
141
+            screen.preventUnmountOnDetachedFromWindow();
142
+        }
143
+    }
144
+
145
+    public void ensureUnmountOnDetachedFromWindow() {
146
+        for (Screen screen : stack) {
147
+            screen.ensureUnmountOnDetachedFromWindow();
148
+        }
149
+    }
150
+
151
+    public void preventMountAfterReatachedToWindow() {
152
+        for (Screen screen : stack) {
153
+            screen.preventMountAfterReattachedToWindow();
154
+        }
155
+    }
138
 }
156
 }

+ 5
- 0
android/app/src/main/java/com/reactnativenavigation/screens/SingleScreen.java Parādīt failu

43
     public void preventUnmountOnDetachedFromWindow() {
43
     public void preventUnmountOnDetachedFromWindow() {
44
         contentView.preventUnmountOnDetachedFromWindow();
44
         contentView.preventUnmountOnDetachedFromWindow();
45
     }
45
     }
46
+
47
+    @Override
48
+    public void preventMountAfterReattachedToWindow() {
49
+        contentView.preventMountAfterReattachedToWindow();
50
+    }
46
 }
51
 }

+ 6
- 0
android/app/src/main/java/com/reactnativenavigation/screens/TabbedScreen.java Parādīt failu

75
         }
75
         }
76
     }
76
     }
77
 
77
 
78
+    @Override
79
+    public void preventMountAfterReattachedToWindow() {
80
+        for (ContentView contentView : contentViews) {
81
+            contentView.preventMountAfterReattachedToWindow();
82
+        }
83
+    }
78
 
84
 
79
     public class ContentViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSelectedListener, ViewPager.OnPageChangeListener {
85
     public class ContentViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSelectedListener, ViewPager.OnPageChangeListener {
80
 
86
 

+ 14
- 0
android/app/src/main/java/com/reactnativenavigation/views/BottomTabs.java Parādīt failu

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
 import android.content.Context;
3
 import android.content.Context;
4
+import android.graphics.Color;
4
 
5
 
5
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
6
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
7
+import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
8
+import com.reactnativenavigation.params.ScreenParams;
9
+
10
+import java.util.List;
6
 
11
 
7
 public class BottomTabs extends AHBottomNavigation {
12
 public class BottomTabs extends AHBottomNavigation {
8
     public BottomTabs(Context context) {
13
     public BottomTabs(Context context) {
9
         super(context);
14
         super(context);
10
     }
15
     }
16
+
17
+    public void addTabs(List<ScreenParams> params, OnTabSelectedListener onTabSelectedListener) {
18
+        for (ScreenParams screenParams : params) {
19
+            AHBottomNavigationItem item = new AHBottomNavigationItem(screenParams.title, screenParams.tabIcon,
20
+                    Color.GRAY);
21
+            addItem(item);
22
+            setOnTabSelectedListener(onTabSelectedListener);
23
+        }
24
+    }
11
 }
25
 }

+ 4
- 0
android/app/src/main/java/com/reactnativenavigation/views/ContentView.java Parādīt failu

49
     public void ensureUnmountOnDetachedFromWindow() {
49
     public void ensureUnmountOnDetachedFromWindow() {
50
         ReactViewHacks.ensureUnmountOnDetachedFromWindow(this);
50
         ReactViewHacks.ensureUnmountOnDetachedFromWindow(this);
51
     }
51
     }
52
+
53
+    public void preventMountAfterReattachedToWindow() {
54
+        ReactViewHacks.preventMountAfterReattachedToWindow(this);
55
+    }
52
 }
56
 }