Browse Source

More work on TopBar background component

Guy Carmeli 6 years ago
parent
commit
7fe85fa02f

+ 6
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/TopBarBackgroundOptions.java View File

19
         options.color = ColorParser.parse(json, "color");
19
         options.color = ColorParser.parse(json, "color");
20
         options.component = TextParser.parse(json, "component");
20
         options.component = TextParser.parse(json, "component");
21
 
21
 
22
+        if (options.component.hasValue()) {
23
+            options.color = new Color(android.graphics.Color.TRANSPARENT);
24
+        }
25
+
22
         return options;
26
         return options;
23
     }
27
     }
24
 
28
 
27
 
31
 
28
     void mergeWith(final TopBarBackgroundOptions other) {
32
     void mergeWith(final TopBarBackgroundOptions other) {
29
         if (other.color.hasValue()) color = other.color;
33
         if (other.color.hasValue()) color = other.color;
34
+        if (other.component.hasValue()) component = other.component;
30
     }
35
     }
31
 
36
 
32
     void mergeWithDefault(TopBarBackgroundOptions defaultOptions) {
37
     void mergeWithDefault(TopBarBackgroundOptions defaultOptions) {
33
         if (!color.hasValue()) color = defaultOptions.color;
38
         if (!color.hasValue()) color = defaultOptions.color;
39
+        if (!component.hasValue()) component = defaultOptions.component;
34
     }
40
     }
35
 }
41
 }

+ 1
- 0
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java View File

40
         if (options.title.text.hasValue()) topBar.setTitle(options.title.text.get());
40
         if (options.title.text.hasValue()) topBar.setTitle(options.title.text.get());
41
         if (options.title.component.hasValue()) topBar.setComponent(options.title.component.get(), options.title.alignment);
41
         if (options.title.component.hasValue()) topBar.setComponent(options.title.component.get(), options.title.alignment);
42
         topBar.setBackgroundColor(options.background.color);
42
         topBar.setBackgroundColor(options.background.color);
43
+        topBar.setBackgroundComponent(options.background.component);
43
         topBar.setTitleTextColor(options.title.color);
44
         topBar.setTitleTextColor(options.title.color);
44
         topBar.setTitleFontSize(options.title.fontSize);
45
         topBar.setTitleFontSize(options.title.fontSize);
45
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
46
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());

+ 12
- 7
lib/android/app/src/main/java/com/reactnativenavigation/views/TopBar.java View File

13
 import android.widget.RelativeLayout;
13
 import android.widget.RelativeLayout;
14
 import android.widget.TextView;
14
 import android.widget.TextView;
15
 
15
 
16
-import com.reactnativenavigation.R;
17
 import com.reactnativenavigation.anim.AnimationListener;
16
 import com.reactnativenavigation.anim.AnimationListener;
18
 import com.reactnativenavigation.anim.TopBarAnimator;
17
 import com.reactnativenavigation.anim.TopBarAnimator;
19
 import com.reactnativenavigation.anim.TopBarCollapseBehavior;
18
 import com.reactnativenavigation.anim.TopBarCollapseBehavior;
20
 import com.reactnativenavigation.interfaces.ScrollEventListener;
19
 import com.reactnativenavigation.interfaces.ScrollEventListener;
21
 import com.reactnativenavigation.parse.AnimationOptions;
20
 import com.reactnativenavigation.parse.AnimationOptions;
22
 import com.reactnativenavigation.parse.TitleOptions;
21
 import com.reactnativenavigation.parse.TitleOptions;
23
-import com.reactnativenavigation.parse.TopBarBackgroundOptions;
24
 import com.reactnativenavigation.parse.params.Button;
22
 import com.reactnativenavigation.parse.params.Button;
25
 import com.reactnativenavigation.parse.params.Color;
23
 import com.reactnativenavigation.parse.params.Color;
26
 import com.reactnativenavigation.parse.params.Fraction;
24
 import com.reactnativenavigation.parse.params.Fraction;
27
 import com.reactnativenavigation.parse.params.Number;
25
 import com.reactnativenavigation.parse.params.Number;
26
+import com.reactnativenavigation.parse.params.Text;
28
 import com.reactnativenavigation.utils.CompatUtils;
27
 import com.reactnativenavigation.utils.CompatUtils;
29
 import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
28
 import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
30
 import com.reactnativenavigation.viewcontrollers.TitleBarReactViewController;
29
 import com.reactnativenavigation.viewcontrollers.TitleBarReactViewController;
48
     private RelativeLayout root;
47
     private RelativeLayout root;
49
     private StackLayout parentView;
48
     private StackLayout parentView;
50
     private TopBarBackgroundViewCreator topBarBackgroundViewCreator;
49
     private TopBarBackgroundViewCreator topBarBackgroundViewCreator;
50
+    private TopBarBackgroundView backgroundView;
51
 
51
 
52
     public TopBar(final Context context, ReactViewCreator buttonCreator, TitleBarReactViewCreator titleBarReactViewCreator, TopBarBackgroundViewCreator topBarBackgroundViewCreator, TopBarButtonController.OnClickListener onClickListener, StackLayout parentView) {
52
     public TopBar(final Context context, ReactViewCreator buttonCreator, TitleBarReactViewCreator titleBarReactViewCreator, TopBarBackgroundViewCreator topBarBackgroundViewCreator, TopBarButtonController.OnClickListener onClickListener, StackLayout parentView) {
53
         super(context);
53
         super(context);
104
         titleBar.setComponent(componentName, alignment);
104
         titleBar.setComponent(componentName, alignment);
105
     }
105
     }
106
 
106
 
107
-    public void setBackgroundComponent(TopBarBackgroundOptions options) {
108
-        if (options.component.hasValue()) {
109
-            TopBarBackgroundView background = topBarBackgroundViewCreator.create((Activity) getContext(), String.valueOf(CompatUtils.generateViewId()), options.component.get());
110
-            background.setId(R.id.topBarBackgroundComponent);
111
-            root.addView(background);
107
+    public void setBackgroundComponent(Text component) {
108
+        if (component.hasValue()) {
109
+            backgroundView = topBarBackgroundViewCreator.create((Activity) getContext(), String.valueOf(CompatUtils.generateViewId()), component.get());
110
+            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, getHeight());
111
+            root.addView(backgroundView, 0, lp);
112
         }
112
         }
113
     }
113
     }
114
 
114
 
202
     }
202
     }
203
 
203
 
204
     public void clear() {
204
     public void clear() {
205
+        if (backgroundView != null) {
206
+            backgroundView.destroy();
207
+            root.removeView(backgroundView);
208
+            backgroundView = null;
209
+        }
205
         titleBar.clear();
210
         titleBar.clear();
206
     }
211
     }
207
 
212
 

+ 1
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/titlebar/TitleBar.java View File

55
         clearTitle();
55
         clearTitle();
56
         reactViewController.setComponent(componentName);
56
         reactViewController.setComponent(componentName);
57
         addView(reactViewController.getView(), getComponentLayoutParams(alignment));
57
         addView(reactViewController.getView(), getComponentLayoutParams(alignment));
58
+        requestLayout();
58
     }
59
     }
59
 
60
 
60
     public void setBackgroundColor(Color color) {
61
     public void setBackgroundColor(Color color) {

+ 0
- 8
lib/android/app/src/main/java/com/reactnativenavigation/views/topbar/TopBarBackgroundView.java View File

12
     public TopBarBackgroundView(Context context, ReactInstanceManager reactInstanceManager, String componentId, String componentName) {
12
     public TopBarBackgroundView(Context context, ReactInstanceManager reactInstanceManager, String componentId, String componentName) {
13
         super(context, reactInstanceManager, componentId, componentName);
13
         super(context, reactInstanceManager, componentId, componentName);
14
     }
14
     }
15
-
16
-    @Override
17
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
18
-        super.onMeasure(
19
-                getChildCount() > 0 ? MeasureSpec.makeMeasureSpec(getChildAt(0).getWidth(), MeasureSpec.EXACTLY) : widthMeasureSpec,
20
-                heightMeasureSpec
21
-        );
22
-    }
23
 }
15
 }

+ 17
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/OptionsApplyingTest.java View File

14
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
14
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
15
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
15
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
16
 import com.reactnativenavigation.parse.Options;
16
 import com.reactnativenavigation.parse.Options;
17
+import com.reactnativenavigation.parse.TopBarBackgroundOptions;
17
 import com.reactnativenavigation.parse.params.Bool;
18
 import com.reactnativenavigation.parse.params.Bool;
18
 import com.reactnativenavigation.parse.params.Fraction;
19
 import com.reactnativenavigation.parse.params.Fraction;
19
 import com.reactnativenavigation.parse.params.Text;
20
 import com.reactnativenavigation.parse.params.Text;
21
+import com.reactnativenavigation.utils.ViewUtils;
22
+import com.reactnativenavigation.views.topbar.TopBarBackgroundView;
20
 
23
 
24
+import org.json.JSONObject;
21
 import org.junit.Test;
25
 import org.junit.Test;
22
 
26
 
23
 import javax.annotation.Nullable;
27
 import javax.annotation.Nullable;
177
             }
181
             }
178
         });
182
         });
179
     }
183
     }
184
+
185
+    @Test
186
+    public void appliesTopBarComponent() throws Exception {
187
+        JSONObject json = new JSONObject();
188
+        json.put("component", "someComponent");
189
+        uut.options.topBarOptions.background = TopBarBackgroundOptions.parse(json);
190
+        uut.ensureViewIsCreated();
191
+        stackController.push(uut, new MockPromise());
192
+        uut.onViewAppeared();
193
+
194
+        assertThat(((ColorDrawable) stackController.getTopBar().getTitleBar().getBackground()).getColor()).isEqualTo(Color.TRANSPARENT);
195
+        assertThat(ViewUtils.findChildrenByClassRecursive(stackController.getTopBar(), TopBarBackgroundView.class)).isNotNull();
196
+    }
180
 }
197
 }

+ 31
- 10
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarBackgroundComponentTest.java View File

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
+import android.app.Activity;
3
 import android.util.Log;
4
 import android.util.Log;
5
+import android.view.ViewGroup;
4
 
6
 
5
 import com.reactnativenavigation.BaseTest;
7
 import com.reactnativenavigation.BaseTest;
6
 import com.reactnativenavigation.R;
8
 import com.reactnativenavigation.R;
7
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
9
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
8
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
10
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
9
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
11
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
10
-import com.reactnativenavigation.parse.TopBarBackgroundOptions;
11
 import com.reactnativenavigation.parse.params.Text;
12
 import com.reactnativenavigation.parse.params.Text;
12
-import com.reactnativenavigation.react.ReactView;
13
+import com.reactnativenavigation.utils.ViewUtils;
13
 import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
14
 import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
15
+import com.reactnativenavigation.views.topbar.TopBarBackgroundView;
14
 
16
 
15
 import org.junit.Test;
17
 import org.junit.Test;
16
 
18
 
17
 import static org.assertj.core.api.Java6Assertions.assertThat;
19
 import static org.assertj.core.api.Java6Assertions.assertThat;
18
 import static org.mockito.Mockito.spy;
20
 import static org.mockito.Mockito.spy;
21
+import static org.mockito.Mockito.times;
22
+import static org.mockito.Mockito.verify;
19
 
23
 
20
 public class TopBarBackgroundComponentTest extends BaseTest {
24
 public class TopBarBackgroundComponentTest extends BaseTest {
21
     private TopBar uut;
25
     private TopBar uut;
26
+    private TopBarBackgroundView backgroundView;
22
 
27
 
23
     @SuppressWarnings("Convert2Lambda")
28
     @SuppressWarnings("Convert2Lambda")
24
     @Override
29
     @Override
29
                 Log.i("TopBarTest", "onPress: " + buttonId);
34
                 Log.i("TopBarTest", "onPress: " + buttonId);
30
             }
35
             }
31
         });
36
         });
32
-        StackLayout parent = new StackLayout(newActivity(), new TopBarButtonCreatorMock(), new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), onClickListener);
33
-        uut = new TopBar(newActivity(), new TopBarButtonCreatorMock(), new TitleBarReactViewCreatorMock(), new TopBarBackgroundViewCreatorMock(), onClickListener, parent);
37
+        TopBarBackgroundViewCreatorMock backgroundViewCreator = new TopBarBackgroundViewCreatorMock() {
38
+            @Override
39
+            public TopBarBackgroundView create(Activity activity, String componentId, String componentName) {
40
+                backgroundView = spy(super.create(activity, componentId, componentName));
41
+                return backgroundView;
42
+            }
43
+        };
44
+        StackLayout parent = new StackLayout(newActivity(), new TopBarButtonCreatorMock(), new TitleBarReactViewCreatorMock(), backgroundViewCreator, onClickListener);
45
+        uut = new TopBar(newActivity(), new TopBarButtonCreatorMock(), new TitleBarReactViewCreatorMock(), backgroundViewCreator, onClickListener, parent);
34
         parent.addView(uut);
46
         parent.addView(uut);
35
     }
47
     }
36
 
48
 
37
     @Test
49
     @Test
38
     public void setBackgroundComponent() throws Exception {
50
     public void setBackgroundComponent() throws Exception {
39
-        TopBarBackgroundOptions options = new TopBarBackgroundOptions();
40
-        options.component = new Text("someComponent");
41
-        uut.setBackgroundComponent(options);
42
-        assertThat(ReactView.class.isAssignableFrom(uut.findViewById(R.id.topBarBackgroundComponent).getClass())).isTrue();
51
+        uut.getLayoutParams().height = 100;
52
+        uut.setBackgroundComponent(new Text("someComponent"));
53
+        TopBarBackgroundView background = (TopBarBackgroundView) ViewUtils.findChildrenByClassRecursive(uut, TopBarBackgroundView.class).get(0);
54
+        assertThat(background).isNotNull();
55
+        assertThat(background.getLayoutParams().width).isEqualTo(ViewGroup.LayoutParams.MATCH_PARENT);
56
+        assertThat(background.getLayoutParams().height).isEqualTo(uut.getHeight());
43
     }
57
     }
44
 
58
 
45
     @Test
59
     @Test
46
     public void setBackgroundComponent_doesNotSetIfNoComponentIsDefined() throws Exception {
60
     public void setBackgroundComponent_doesNotSetIfNoComponentIsDefined() throws Exception {
47
-        TopBarBackgroundOptions options = new TopBarBackgroundOptions();
48
-        uut.setBackgroundComponent(options);
61
+        uut.setBackgroundComponent(new Text("someComponent"));
49
         assertThat(uut.findViewById(R.id.topBarBackgroundComponent)).isNull();
62
         assertThat(uut.findViewById(R.id.topBarBackgroundComponent)).isNull();
50
     }
63
     }
64
+
65
+    @Test
66
+    public void clear_componentIsDestroyed() throws Exception {
67
+        uut.setBackgroundComponent(new Text("someComponent"));
68
+        uut.clear();
69
+        verify(backgroundView, times(1)).destroy();
70
+        assertThat(backgroundView.getParent()).isNull();
71
+    }
51
 }
72
 }

+ 3
- 0
playground/src/screens/OptionsScreen.js View File

24
           fontFamily: 'HelveticaNeue-Italic',
24
           fontFamily: 'HelveticaNeue-Italic',
25
           largeTitle: false
25
           largeTitle: false
26
         },
26
         },
27
+        background: {
28
+          component: 'TopBarBackground'
29
+        },
27
         ...Platform.select({
30
         ...Platform.select({
28
           android: { drawBehind: true },
31
           android: { drawBehind: true },
29
           ios: { drawBehind: false, }
32
           ios: { drawBehind: false, }

+ 41
- 0
playground/src/screens/TopBarBackground.js View File

1
+const React = require('react');
2
+const { Component } = require('react');
3
+const {
4
+  StyleSheet,
5
+  View
6
+} = require('react-native');
7
+
8
+class TopBarBackground extends Component {
9
+
10
+  constructor(props) {
11
+    super(props);
12
+    this.state = {};
13
+    this.dots = new Array(55).fill('').map((ignored, i) => <View key={'dot' + i} style={styles.dot}/>);
14
+  }
15
+
16
+  render() {
17
+    return (
18
+      <View style={styles.container}>
19
+        {this.dots}
20
+      </View>
21
+    );
22
+  }
23
+}
24
+
25
+module.exports = TopBarBackground;
26
+
27
+const styles = StyleSheet.create({
28
+  container: {
29
+    flex: 1,
30
+    flexDirection: 'row',
31
+    backgroundColor: '#e0e0e0',
32
+    flexWrap: 'wrap'
33
+  },
34
+  dot: {
35
+    height: 16,
36
+    width: 16,
37
+    borderRadius: 8,
38
+    margin: 4,
39
+    backgroundColor: '#bbdefb'
40
+  }
41
+});

+ 2
- 0
playground/src/screens/index.js View File

21
 const BackHandlerModalScreen = require('./BackHandlerModalScreen');
21
 const BackHandlerModalScreen = require('./BackHandlerModalScreen');
22
 const CustomTextButton = require('./CustomTextButton');
22
 const CustomTextButton = require('./CustomTextButton');
23
 const CustomRoundedButton = require('./CustomRoundedButton');
23
 const CustomRoundedButton = require('./CustomRoundedButton');
24
+const TopBarBackground = require('./TopBarBackground');
24
 
25
 
25
 function registerScreens() {
26
 function registerScreens() {
26
   Navigation.registerComponent(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
27
   Navigation.registerComponent(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
45
   Navigation.registerComponent('navigation.playground.BackHandlerModalScreen', () => BackHandlerModalScreen);
46
   Navigation.registerComponent('navigation.playground.BackHandlerModalScreen', () => BackHandlerModalScreen);
46
   Navigation.registerComponent('CustomTextButton', () => CustomTextButton);
47
   Navigation.registerComponent('CustomTextButton', () => CustomTextButton);
47
   Navigation.registerComponent('CustomRoundedButton', () => CustomRoundedButton);
48
   Navigation.registerComponent('CustomRoundedButton', () => CustomRoundedButton);
49
+  Navigation.registerComponent('TopBarBackground', () => TopBarBackground);
48
 }
50
 }
49
 
51
 
50
 module.exports = {
52
 module.exports = {