Browse Source

TopBar component Android cont

* Clear text when component is used in title
* Measure title component to first child's width
Guy Carmeli 6 years ago
parent
commit
4f545a7aa1

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

2
 
2
 
3
 import android.graphics.Typeface;
3
 import android.graphics.Typeface;
4
 import android.support.annotation.Nullable;
4
 import android.support.annotation.Nullable;
5
+import android.util.Log;
5
 
6
 
7
+import com.reactnativenavigation.BuildConfig;
6
 import com.reactnativenavigation.parse.params.Color;
8
 import com.reactnativenavigation.parse.params.Color;
7
 import com.reactnativenavigation.parse.params.Fraction;
9
 import com.reactnativenavigation.parse.params.Fraction;
8
 import com.reactnativenavigation.parse.params.NullColor;
10
 import com.reactnativenavigation.parse.params.NullColor;
45
         options.component = TextParser.parse(json, "component");
47
         options.component = TextParser.parse(json, "component");
46
         options.alignment = Alignment.fromString(TextParser.parse(json, "alignment").get(""));
48
         options.alignment = Alignment.fromString(TextParser.parse(json, "alignment").get(""));
47
 
49
 
50
+        if (options.component.hasValue() && options.text.hasValue()) {
51
+            if (BuildConfig.DEBUG) Log.w("RNN", "A screen can't use both text and component - clearing text.");
52
+            options.text = new NullText();
53
+        }
54
+
48
         return options;
55
         return options;
49
     }
56
     }
50
 
57
 

+ 1
- 4
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TitleBarReactViewController.java View File

3
 import android.app.Activity;
3
 import android.app.Activity;
4
 
4
 
5
 import com.reactnativenavigation.parse.Options;
5
 import com.reactnativenavigation.parse.Options;
6
-import com.reactnativenavigation.parse.TitleOptions;
7
 import com.reactnativenavigation.utils.CompatUtils;
6
 import com.reactnativenavigation.utils.CompatUtils;
8
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
7
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
9
 import com.reactnativenavigation.views.titlebar.TitleBarReactViewCreator;
8
 import com.reactnativenavigation.views.titlebar.TitleBarReactViewCreator;
12
 
11
 
13
     private final TitleBarReactViewCreator reactViewCreator;
12
     private final TitleBarReactViewCreator reactViewCreator;
14
     private String componentName;
13
     private String componentName;
15
-    private TitleOptions.Alignment alignment;
16
 
14
 
17
     public TitleBarReactViewController(Activity activity, TitleBarReactViewCreator reactViewCreator) {
15
     public TitleBarReactViewController(Activity activity, TitleBarReactViewCreator reactViewCreator) {
18
         super(activity, CompatUtils.generateViewId() + "", new Options());
16
         super(activity, CompatUtils.generateViewId() + "", new Options());
29
 
27
 
30
     }
28
     }
31
 
29
 
32
-    public void setComponent(String componentName, TitleOptions.Alignment alignment) {
30
+    public void setComponent(String componentName) {
33
         this.componentName = componentName;
31
         this.componentName = componentName;
34
-        this.alignment = alignment;
35
     }
32
     }
36
 }
33
 }

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java View File

15
 import com.reactnativenavigation.utils.CompatUtils;
15
 import com.reactnativenavigation.utils.CompatUtils;
16
 import com.reactnativenavigation.utils.StringUtils;
16
 import com.reactnativenavigation.utils.StringUtils;
17
 import com.reactnativenavigation.utils.Task;
17
 import com.reactnativenavigation.utils.Task;
18
+import com.reactnativenavigation.utils.UiUtils;
18
 import com.reactnativenavigation.views.Component;
19
 import com.reactnativenavigation.views.Component;
19
 
20
 
20
 public abstract class ViewController<T extends ViewGroup> implements ViewTreeObserver.OnGlobalLayoutListener {
21
 public abstract class ViewController<T extends ViewGroup> implements ViewTreeObserver.OnGlobalLayoutListener {
201
         }
202
         }
202
     }
203
     }
203
 
204
 
205
+    public void runOnPreDraw(Task<T> task) {
206
+        UiUtils.runOnPreDrawOnce(getView(), () -> task.run(getView()));
207
+    }
208
+
204
     public abstract void sendOnNavigationButtonPressed(String buttonId);
209
     public abstract void sendOnNavigationButtonPressed(String buttonId);
205
 
210
 
206
     protected boolean isViewShown() {
211
     protected boolean isViewShown() {

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

7
 import android.support.annotation.Nullable;
7
 import android.support.annotation.Nullable;
8
 import android.support.v7.widget.Toolbar;
8
 import android.support.v7.widget.Toolbar;
9
 import android.util.Log;
9
 import android.util.Log;
10
+import android.view.Gravity;
10
 import android.view.View;
11
 import android.view.View;
11
 import android.view.ViewGroup;
12
 import android.view.ViewGroup;
12
 import android.widget.TextView;
13
 import android.widget.TextView;
22
 import java.util.ArrayList;
23
 import java.util.ArrayList;
23
 import java.util.List;
24
 import java.util.List;
24
 
25
 
26
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
27
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
28
+
25
 @SuppressLint("ViewConstructor")
29
 @SuppressLint("ViewConstructor")
26
 public class TitleBar extends Toolbar {
30
 public class TitleBar extends Toolbar {
27
     private final ReactViewCreator buttonCreator;
31
     private final ReactViewCreator buttonCreator;
48
     }
52
     }
49
 
53
 
50
     public void setComponent(String componentName, TitleOptions.Alignment alignment) {
54
     public void setComponent(String componentName, TitleOptions.Alignment alignment) {
51
-        reactViewController.setComponent(componentName, alignment);
52
-        addView(reactViewController.getView(), ViewGroup.LayoutParams.WRAP_CONTENT, getHeight());
55
+        reactViewController.setComponent(componentName);
56
+        addView(reactViewController.getView(), getComponentLayoutParams(alignment));
53
     }
57
     }
54
 
58
 
55
     public void setBackgroundColor(Color color) {
59
     public void setBackgroundColor(Color color) {
146
         }
150
         }
147
         return null;
151
         return null;
148
     }
152
     }
153
+
154
+    public Toolbar.LayoutParams getComponentLayoutParams(TitleOptions.Alignment alignment) {
155
+        if (alignment == TitleOptions.Alignment.Fill) {
156
+            return new LayoutParams(MATCH_PARENT, getHeight());
157
+        } else {
158
+            LayoutParams lp = new LayoutParams(WRAP_CONTENT, getHeight());
159
+            lp.gravity = Gravity.CENTER;
160
+            return lp;
161
+        }
162
+    }
149
 }
163
 }

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

12
     public TitleBarReactView(Context context, ReactInstanceManager reactInstanceManager, String componentId, String componentName) {
12
     public TitleBarReactView(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
+    }
15
 }
23
 }

+ 24
- 4
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TitleBarTest.java View File

1
 package com.reactnativenavigation.viewcontrollers;
1
 package com.reactnativenavigation.viewcontrollers;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
+import android.support.v7.widget.Toolbar;
5
+import android.view.Gravity;
4
 import android.view.ViewGroup;
6
 import android.view.ViewGroup;
5
 
7
 
6
 import com.reactnativenavigation.BaseTest;
8
 import com.reactnativenavigation.BaseTest;
14
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
16
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
15
 
17
 
16
 import org.junit.Test;
18
 import org.junit.Test;
19
+import org.mockito.ArgumentCaptor;
17
 
20
 
18
 import java.util.ArrayList;
21
 import java.util.ArrayList;
19
 import java.util.Arrays;
22
 import java.util.Arrays;
24
 
27
 
25
 import static org.assertj.core.api.Java6Assertions.assertThat;
28
 import static org.assertj.core.api.Java6Assertions.assertThat;
26
 import static org.mockito.ArgumentMatchers.any;
29
 import static org.mockito.ArgumentMatchers.any;
27
-import static org.mockito.ArgumentMatchers.eq;
28
 import static org.mockito.Mockito.spy;
30
 import static org.mockito.Mockito.spy;
29
 import static org.mockito.Mockito.times;
31
 import static org.mockito.Mockito.times;
30
 import static org.mockito.Mockito.verify;
32
 import static org.mockito.Mockito.verify;
128
     }
130
     }
129
 
131
 
130
     @Test
132
     @Test
131
-    public void setComponent_addsComponentToTitleBar() {
133
+    public void setComponent_addsComponentToTitleBar() throws Exception {
132
         uut.setComponent("com.rnn.CustomView", TitleOptions.Alignment.Center);
134
         uut.setComponent("com.rnn.CustomView", TitleOptions.Alignment.Center);
133
-        final int height = uut.getHeight();
134
-        verify(uut, times(1)).addView(any(TitleBarReactView.class), eq(ViewGroup.LayoutParams.WRAP_CONTENT), eq(height));
135
+        verify(uut, times(1)).addView(any(TitleBarReactView.class));
136
+    }
137
+
138
+    @Test
139
+    public void setComponent_alignFill() throws Exception {
140
+        uut.setComponent("com.rnn.CustomView", TitleOptions.Alignment.Fill);
141
+        verify(uut, times(1)).getComponentLayoutParams(TitleOptions.Alignment.Fill);
142
+        ArgumentCaptor<Toolbar.LayoutParams> lpCaptor = ArgumentCaptor.forClass(Toolbar.LayoutParams.class);
143
+        verify(uut, times(1)).addView(any(TitleBarReactView.class), lpCaptor.capture());
144
+        assertThat(lpCaptor.getValue().width == ViewGroup.LayoutParams.MATCH_PARENT);
145
+    }
146
+
147
+    @Test
148
+    public void setComponent_alignCenter() throws Exception {
149
+        uut.setComponent("com.rnn.CustomView", TitleOptions.Alignment.Center);
150
+        verify(uut, times(1)).getComponentLayoutParams(TitleOptions.Alignment.Center);
151
+        ArgumentCaptor<Toolbar.LayoutParams> lpCaptor = ArgumentCaptor.forClass(Toolbar.LayoutParams.class);
152
+        verify(uut, times(1)).addView(any(TitleBarReactView.class), lpCaptor.capture());
153
+        assertThat(lpCaptor.getValue().width == ViewGroup.LayoutParams.WRAP_CONTENT);
154
+        assertThat(lpCaptor.getValue().gravity == Gravity.CENTER);
135
     }
155
     }
136
 
156
 
137
     private List<Button> leftButton(Button leftButton) {
157
     private List<Button> leftButton(Button leftButton) {

+ 4
- 8
playground/src/screens/CustomTopBar.js View File

19
   render() {
19
   render() {
20
     return (
20
     return (
21
       <View style={styles.container}>
21
       <View style={styles.container}>
22
-        <TouchableOpacity stye={styles.button} onPress={() => Alert.alert(this.props.title, 'Thanks for that :)')}>
22
+        <TouchableOpacity onPress={() => Alert.alert(this.props.title, 'Thanks for that :)')}>
23
           <Text style={styles.text}>Press Me</Text>
23
           <Text style={styles.text}>Press Me</Text>
24
         </TouchableOpacity>
24
         </TouchableOpacity>
25
       </View>
25
       </View>
32
 const styles = StyleSheet.create({
32
 const styles = StyleSheet.create({
33
   container: {
33
   container: {
34
     flex: 1,
34
     flex: 1,
35
+    flexDirection: 'column',
35
     justifyContent: 'center',
36
     justifyContent: 'center',
36
-    alignItems: 'center',
37
-    backgroundColor: 'white'
38
-  },
39
-  button: {
40
-    alignSelf: 'center',
41
-    backgroundColor: 'green'
37
+    alignSelf: 'center'
42
   },
38
   },
43
   text: {
39
   text: {
44
     alignSelf: 'center',
40
     alignSelf: 'center',
45
-    color: 'black'
41
+    color: 'black',
46
   }
42
   }
47
 });
43
 });

+ 10
- 7
playground/src/screens/OptionsScreen.js View File

23
           fontSize: 16,
23
           fontSize: 16,
24
           fontFamily: 'HelveticaNeue-Italic',
24
           fontFamily: 'HelveticaNeue-Italic',
25
           largeTitle: false,
25
           largeTitle: false,
26
+          component: 'navigation.playground.CustomTopBar',
27
+          alignment: 'center'
26
         },
28
         },
27
         ...Platform.select({
29
         ...Platform.select({
28
           android: { drawBehind: true },
30
           android: { drawBehind: true },
41
             testID: CUSTOM_BUTTON2,
43
             testID: CUSTOM_BUTTON2,
42
             component: 'CustomRoundedButton'
44
             component: 'CustomRoundedButton'
43
           },
45
           },
44
-          {
45
-            id: BUTTON_ONE,
46
-            testID: BUTTON_ONE,
47
-            title: 'One',
48
-            buttonFontSize: 28,
49
-            buttonColor: 'red'
50
-          }
46
+          // {
47
+          //   id: BUTTON_ONE,
48
+          //   testID: BUTTON_ONE,
49
+          //   title: 'One',
50
+          //   buttonFontSize: 28,
51
+          //   buttonColor: 'red'
52
+          // }
51
         ],
53
         ],
52
         leftButtons: [{
54
         leftButtons: [{
53
           id: BUTTON_LEFT,
55
           id: BUTTON_LEFT,
99
   render() {
101
   render() {
100
     return (
102
     return (
101
       <View style={styles.root}>
103
       <View style={styles.root}>
104
+        <View style={{width: 2, height: 2, backgroundColor: 'red', alignSelf: 'center'}}/>
102
         <Text style={styles.h1} testID={testIDs.OPTIONS_SCREEN_HEADER}>{`Options Screen`}</Text>
105
         <Text style={styles.h1} testID={testIDs.OPTIONS_SCREEN_HEADER}>{`Options Screen`}</Text>
103
         <Button title='Dynamic Options' testID={testIDs.DYNAMIC_OPTIONS_BUTTON} onPress={this.onClickDynamicOptions} />
106
         <Button title='Dynamic Options' testID={testIDs.DYNAMIC_OPTIONS_BUTTON} onPress={this.onClickDynamicOptions} />
104
         <Button title='Show Top Bar' testID={testIDs.SHOW_TOP_BAR_BUTTON} onPress={this.onClickShowTopBar} />
107
         <Button title='Show Top Bar' testID={testIDs.SHOW_TOP_BAR_BUTTON} onPress={this.onClickShowTopBar} />