Преглед на файлове

BottomTab badge is applied

Guy Carmeli преди 7 години
родител
ревизия
7dd444cb09

+ 10
- 3
lib/android/app/src/main/java/com/reactnativenavigation/parse/BottomTabOptions.java Целия файл

9
         if (json == null) return options;
9
         if (json == null) return options;
10
 
10
 
11
         options.title = TextParser.parse(json, "title");
11
         options.title = TextParser.parse(json, "title");
12
-        if (!json.has("icon")) {
13
-            throw new RuntimeException("BottomTab must have an icon");
12
+        if (json.has("icon")) {
13
+            options.icon = TextParser.parse(json.optJSONObject("icon"), "uri");
14
         }
14
         }
15
-        options.icon = TextParser.parse(json.optJSONObject("icon"), "uri");
15
+        options.badge = TextParser.parse(json, "badge");
16
         options.testId = TextParser.parse(json, "testID");
16
         options.testId = TextParser.parse(json, "testID");
17
         return options;
17
         return options;
18
     }
18
     }
20
     public Text title = new NullText();
20
     public Text title = new NullText();
21
     public Text icon = new NullText();
21
     public Text icon = new NullText();
22
     public Text testId = new NullText();
22
     public Text testId = new NullText();
23
+    public Text badge = new NullText();
23
 
24
 
24
     void mergeWith(final BottomTabOptions other) {
25
     void mergeWith(final BottomTabOptions other) {
25
         if (other.title.hasValue()) {
26
         if (other.title.hasValue()) {
28
         if (other.icon.hasValue()) {
29
         if (other.icon.hasValue()) {
29
             icon = other.icon;
30
             icon = other.icon;
30
         }
31
         }
32
+        if (other.badge.hasValue()) {
33
+            badge = other.badge;
34
+        }
31
     }
35
     }
32
 
36
 
33
     void mergeWithDefault(final BottomTabOptions defaultOptions) {
37
     void mergeWithDefault(final BottomTabOptions defaultOptions) {
37
         if (!icon.hasValue()) {
41
         if (!icon.hasValue()) {
38
             icon = defaultOptions.icon;
42
             icon = defaultOptions.icon;
39
         }
43
         }
44
+        if (!badge.hasValue()) {
45
+            badge = defaultOptions.badge;
46
+        }
40
     }
47
     }
41
 }
48
 }

+ 25
- 0
lib/android/app/src/main/java/com/reactnativenavigation/presentation/BottomTabOptionsPresenter.java Целия файл

1
+package com.reactnativenavigation.presentation;
2
+
3
+import android.support.annotation.IntRange;
4
+
5
+import com.reactnativenavigation.parse.BottomTabOptions;
6
+import com.reactnativenavigation.parse.Options;
7
+import com.reactnativenavigation.views.BottomTabs;
8
+
9
+public class BottomTabOptionsPresenter {
10
+    private BottomTabs bottomTabs;
11
+
12
+    public BottomTabOptionsPresenter(BottomTabs bottomTabs) {
13
+        this.bottomTabs = bottomTabs;
14
+    }
15
+
16
+    public void present(Options options, @IntRange(from = 0) int bottomTabIndex) {
17
+        applyBottomTabOptions(options.bottomTabOptions, bottomTabIndex);
18
+    }
19
+
20
+    private void applyBottomTabOptions(BottomTabOptions options, int bottomTabIndex) {
21
+        if (options.badge.hasValue()) {
22
+            bottomTabs.setBadge(bottomTabIndex, options.badge);
23
+        }
24
+    }
25
+}

+ 22
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java Целия файл

3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.graphics.Color;
4
 import android.graphics.Color;
5
 import android.graphics.drawable.Drawable;
5
 import android.graphics.drawable.Drawable;
6
+import android.support.annotation.IntRange;
6
 import android.support.annotation.NonNull;
7
 import android.support.annotation.NonNull;
7
 import android.view.ViewGroup;
8
 import android.view.ViewGroup;
8
 import android.widget.RelativeLayout;
9
 import android.widget.RelativeLayout;
13
 import com.reactnativenavigation.parse.BottomTabsOptions;
14
 import com.reactnativenavigation.parse.BottomTabsOptions;
14
 import com.reactnativenavigation.parse.Options;
15
 import com.reactnativenavigation.parse.Options;
15
 import com.reactnativenavigation.parse.Text;
16
 import com.reactnativenavigation.parse.Text;
17
+import com.reactnativenavigation.presentation.BottomTabOptionsPresenter;
16
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
18
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
17
 import com.reactnativenavigation.utils.ImageLoader;
19
 import com.reactnativenavigation.utils.ImageLoader;
18
 import com.reactnativenavigation.utils.UiUtils;
20
 import com.reactnativenavigation.utils.UiUtils;
19
 import com.reactnativenavigation.views.BottomTabs;
21
 import com.reactnativenavigation.views.BottomTabs;
22
+import com.reactnativenavigation.views.ReactComponent;
20
 
23
 
21
 import java.util.ArrayList;
24
 import java.util.ArrayList;
22
 import java.util.Collection;
25
 import java.util.Collection;
50
 		return root;
53
 		return root;
51
 	}
54
 	}
52
 
55
 
53
-	@Override
56
+    @Override
57
+    public void applyOptions(Options options, ReactComponent childComponent) {
58
+        int tabIndex = findTabContainingComponent(childComponent);
59
+        if (tabIndex >= 0) new BottomTabOptionsPresenter(bottomTabs).present(options, tabIndex);
60
+    }
61
+
62
+    @Override
54
 	public boolean handleBack() {
63
 	public boolean handleBack() {
55
 		return !tabs.isEmpty() && tabs.get(bottomTabs.getCurrentItem()).handleBack();
64
 		return !tabs.isEmpty() && tabs.get(bottomTabs.getCurrentItem()).handleBack();
56
 	}
65
 	}
69
 		this.tabs = tabs;
78
 		this.tabs = tabs;
70
 		getView();
79
 		getView();
71
 		for (int i = 0; i < tabs.size(); i++) {
80
 		for (int i = 0; i < tabs.size(); i++) {
81
+		    tabs.get(i).setParentController(this);
72
 			createTab(i, tabs.get(i).options.bottomTabOptions, tabs.get(i).options.bottomTabsOptions);
82
 			createTab(i, tabs.get(i).options.bottomTabOptions, tabs.get(i).options.bottomTabsOptions);
73
 		}
83
 		}
74
 		selectTabAtIndex(0);
84
 		selectTabAtIndex(0);
113
 
123
 
114
 	@Override
124
 	@Override
115
 	public void mergeOptions(Options options) {
125
 	public void mergeOptions(Options options) {
126
+        this.options.mergeWith(options);
116
         if (options.bottomTabsOptions.currentTabIndex != NO_INT_VALUE) {
127
         if (options.bottomTabsOptions.currentTabIndex != NO_INT_VALUE) {
117
             selectTabAtIndex(options.bottomTabsOptions.currentTabIndex);
128
             selectTabAtIndex(options.bottomTabsOptions.currentTabIndex);
118
         }
129
         }
153
 		}
164
 		}
154
 		return false;
165
 		return false;
155
 	}
166
 	}
167
+
168
+	@IntRange(from = -1)
169
+    private int findTabContainingComponent(ReactComponent component) {
170
+        for (int i = 0; i < tabs.size(); i++) {
171
+            if (tabs.get(i).containsComponent(component)) {
172
+                return i;
173
+            }
174
+        }
175
+        return -1;
176
+    }
156
 }
177
 }

+ 11
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ParentController.java Целия файл

44
 		return null;
44
 		return null;
45
 	}
45
 	}
46
 
46
 
47
+	@Override
48
+    public boolean containsComponent(ReactComponent component) {
49
+        if (super.containsComponent(component)) {
50
+            return true;
51
+        }
52
+        for (ViewController child : getChildControllers()) {
53
+            if (child.containsComponent(component)) return true;
54
+        }
55
+        return false;
56
+    }
57
+
47
     public void applyOptions(Options options, ReactComponent childComponent) {
58
     public void applyOptions(Options options, ReactComponent childComponent) {
48
 
59
 
49
     }
60
     }

+ 1
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java Целия файл

37
     @Override
37
     @Override
38
     public void applyOptions(Options options, ReactComponent component) {
38
     public void applyOptions(Options options, ReactComponent component) {
39
         stackLayout.applyOptions(options, component);
39
         stackLayout.applyOptions(options, component);
40
+        applyOnParentController(parentController -> ((ParentController) parentController).applyOptions(options, component));
40
     }
41
     }
41
 
42
 
42
     @Override
43
     @Override

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java Целия файл

126
         return isSameId(id) ? this : null;
126
         return isSameId(id) ? this : null;
127
     }
127
     }
128
 
128
 
129
+    public boolean containsComponent(ReactComponent component) {
130
+        return getView().equals(component);
131
+    }
132
+
129
     public void onViewAppeared() {
133
     public void onViewAppeared() {
130
         isShown = true;
134
         isShown = true;
131
         applyOnParentController(parentController -> {
135
         applyOnParentController(parentController -> {

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/BottomTabs.java Целия файл

25
         if (testId.hasValue()) getViewAtPosition(index).setTag(testId.get());
25
         if (testId.hasValue()) getViewAtPosition(index).setTag(testId.get());
26
         if (testId.hasValue()) getViewAtPosition(index).setContentDescription(testId.get());
26
         if (testId.hasValue()) getViewAtPosition(index).setContentDescription(testId.get());
27
     }
27
     }
28
+
29
+    public void setBadge(int bottomTabIndex, Text badge) {
30
+        setNotification(badge.get(), bottomTabIndex);
31
+    }
28
 }
32
 }

+ 9
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java Целия файл

62
         uut.setTabs(tabs);
62
         uut.setTabs(tabs);
63
     }
63
     }
64
 
64
 
65
+    @Test
66
+    public void setTab_controllerIsSetAsParent() throws Exception {
67
+        List<ViewController> tabs = createTabs();
68
+        uut.setTabs(tabs);
69
+        for (ViewController tab : tabs) {
70
+            assertThat(tab.getParentController()).isEqualTo(uut);
71
+        }
72
+    }
73
+
65
     @Test
74
     @Test
66
     public void setTabs_AddAllViews() throws Exception {
75
     public void setTabs_AddAllViews() throws Exception {
67
         List<ViewController> tabs = createTabs();
76
         List<ViewController> tabs = createTabs();