浏览代码

TopBar component Android cont

* Clear text when component is used in title
* Measure title component to first child's width
Guy Carmeli 6 年前
父节点
当前提交
4f545a7aa1

+ 7
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/TitleOptions.java 查看文件

@@ -2,7 +2,9 @@ package com.reactnativenavigation.parse;
2 2
 
3 3
 import android.graphics.Typeface;
4 4
 import android.support.annotation.Nullable;
5
+import android.util.Log;
5 6
 
7
+import com.reactnativenavigation.BuildConfig;
6 8
 import com.reactnativenavigation.parse.params.Color;
7 9
 import com.reactnativenavigation.parse.params.Fraction;
8 10
 import com.reactnativenavigation.parse.params.NullColor;
@@ -45,6 +47,11 @@ public class TitleOptions {
45 47
         options.component = TextParser.parse(json, "component");
46 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 55
         return options;
49 56
     }
50 57
 

+ 1
- 4
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TitleBarReactViewController.java 查看文件

@@ -3,7 +3,6 @@ package com.reactnativenavigation.viewcontrollers;
3 3
 import android.app.Activity;
4 4
 
5 5
 import com.reactnativenavigation.parse.Options;
6
-import com.reactnativenavigation.parse.TitleOptions;
7 6
 import com.reactnativenavigation.utils.CompatUtils;
8 7
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
9 8
 import com.reactnativenavigation.views.titlebar.TitleBarReactViewCreator;
@@ -12,7 +11,6 @@ public class TitleBarReactViewController extends ViewController<TitleBarReactVie
12 11
 
13 12
     private final TitleBarReactViewCreator reactViewCreator;
14 13
     private String componentName;
15
-    private TitleOptions.Alignment alignment;
16 14
 
17 15
     public TitleBarReactViewController(Activity activity, TitleBarReactViewCreator reactViewCreator) {
18 16
         super(activity, CompatUtils.generateViewId() + "", new Options());
@@ -29,8 +27,7 @@ public class TitleBarReactViewController extends ViewController<TitleBarReactVie
29 27
 
30 28
     }
31 29
 
32
-    public void setComponent(String componentName, TitleOptions.Alignment alignment) {
30
+    public void setComponent(String componentName) {
33 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 查看文件

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

+ 16
- 2
lib/android/app/src/main/java/com/reactnativenavigation/views/titlebar/TitleBar.java 查看文件

@@ -7,6 +7,7 @@ import android.graphics.Typeface;
7 7
 import android.support.annotation.Nullable;
8 8
 import android.support.v7.widget.Toolbar;
9 9
 import android.util.Log;
10
+import android.view.Gravity;
10 11
 import android.view.View;
11 12
 import android.view.ViewGroup;
12 13
 import android.widget.TextView;
@@ -22,6 +23,9 @@ import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
22 23
 import java.util.ArrayList;
23 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 29
 @SuppressLint("ViewConstructor")
26 30
 public class TitleBar extends Toolbar {
27 31
     private final ReactViewCreator buttonCreator;
@@ -48,8 +52,8 @@ public class TitleBar extends Toolbar {
48 52
     }
49 53
 
50 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 59
     public void setBackgroundColor(Color color) {
@@ -146,4 +150,14 @@ public class TitleBar extends Toolbar {
146 150
         }
147 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 查看文件

@@ -12,4 +12,12 @@ public class TitleBarReactView extends ReactView {
12 12
     public TitleBarReactView(Context context, ReactInstanceManager reactInstanceManager, String componentId, String componentName) {
13 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 查看文件

@@ -1,6 +1,8 @@
1 1
 package com.reactnativenavigation.viewcontrollers;
2 2
 
3 3
 import android.app.Activity;
4
+import android.support.v7.widget.Toolbar;
5
+import android.view.Gravity;
4 6
 import android.view.ViewGroup;
5 7
 
6 8
 import com.reactnativenavigation.BaseTest;
@@ -14,6 +16,7 @@ import com.reactnativenavigation.views.titlebar.TitleBar;
14 16
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
15 17
 
16 18
 import org.junit.Test;
19
+import org.mockito.ArgumentCaptor;
17 20
 
18 21
 import java.util.ArrayList;
19 22
 import java.util.Arrays;
@@ -24,7 +27,6 @@ import java.util.Map;
24 27
 
25 28
 import static org.assertj.core.api.Java6Assertions.assertThat;
26 29
 import static org.mockito.ArgumentMatchers.any;
27
-import static org.mockito.ArgumentMatchers.eq;
28 30
 import static org.mockito.Mockito.spy;
29 31
 import static org.mockito.Mockito.times;
30 32
 import static org.mockito.Mockito.verify;
@@ -128,10 +130,28 @@ public class TitleBarTest extends BaseTest {
128 130
     }
129 131
 
130 132
     @Test
131
-    public void setComponent_addsComponentToTitleBar() {
133
+    public void setComponent_addsComponentToTitleBar() throws Exception {
132 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 157
     private List<Button> leftButton(Button leftButton) {

+ 4
- 8
playground/src/screens/CustomTopBar.js 查看文件

@@ -19,7 +19,7 @@ class CustomTopBar extends Component {
19 19
   render() {
20 20
     return (
21 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 23
           <Text style={styles.text}>Press Me</Text>
24 24
         </TouchableOpacity>
25 25
       </View>
@@ -32,16 +32,12 @@ module.exports = CustomTopBar;
32 32
 const styles = StyleSheet.create({
33 33
   container: {
34 34
     flex: 1,
35
+    flexDirection: 'column',
35 36
     justifyContent: 'center',
36
-    alignItems: 'center',
37
-    backgroundColor: 'white'
38
-  },
39
-  button: {
40
-    alignSelf: 'center',
41
-    backgroundColor: 'green'
37
+    alignSelf: 'center'
42 38
   },
43 39
   text: {
44 40
     alignSelf: 'center',
45
-    color: 'black'
41
+    color: 'black',
46 42
   }
47 43
 });

+ 10
- 7
playground/src/screens/OptionsScreen.js 查看文件

@@ -23,6 +23,8 @@ class OptionsScreen extends Component {
23 23
           fontSize: 16,
24 24
           fontFamily: 'HelveticaNeue-Italic',
25 25
           largeTitle: false,
26
+          component: 'navigation.playground.CustomTopBar',
27
+          alignment: 'center'
26 28
         },
27 29
         ...Platform.select({
28 30
           android: { drawBehind: true },
@@ -41,13 +43,13 @@ class OptionsScreen extends Component {
41 43
             testID: CUSTOM_BUTTON2,
42 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 54
         leftButtons: [{
53 55
           id: BUTTON_LEFT,
@@ -99,6 +101,7 @@ class OptionsScreen extends Component {
99 101
   render() {
100 102
     return (
101 103
       <View style={styles.root}>
104
+        <View style={{width: 2, height: 2, backgroundColor: 'red', alignSelf: 'center'}}/>
102 105
         <Text style={styles.h1} testID={testIDs.OPTIONS_SCREEN_HEADER}>{`Options Screen`}</Text>
103 106
         <Button title='Dynamic Options' testID={testIDs.DYNAMIC_OPTIONS_BUTTON} onPress={this.onClickDynamicOptions} />
104 107
         <Button title='Show Top Bar' testID={testIDs.SHOW_TOP_BAR_BUTTON} onPress={this.onClickShowTopBar} />