Ver código fonte

Support centering title and changing its font on Android

This commit adds support for the following style properties:
titleBarTitleFontFamily - string, font name in assets
titleBarTitleTextCentered - boolean, default is false
Guy Carmeli 7 anos atrás
pai
commit
86f397b782

+ 12
- 1
android/app/src/main/java/com/reactnativenavigation/params/BaseTitleBarButtonParams.java Ver arquivo

@@ -25,9 +25,20 @@ public class BaseTitleBarButtonParams {
25 25
     public ShowAsAction showAsAction;
26 26
     public boolean enabled = true;
27 27
 
28
-    public void setColorFromScreenStyle(StyleParams.Color titleBarButtonColor) {
28
+    public void setStyleFromScreen(StyleParams styleParams) {
29
+        setColorFromScreenStyle(styleParams.titleBarButtonColor);
30
+    }
31
+
32
+    private void setColorFromScreenStyle(StyleParams.Color titleBarButtonColor) {
29 33
         if (!color.hasColor() && titleBarButtonColor.hasColor()) {
30 34
             color = titleBarButtonColor;
31 35
         }
32 36
     }
37
+
38
+    public StyleParams.Color getColor() {
39
+        if (enabled) {
40
+            return color;
41
+        }
42
+        return disabledColor.hasColor() ? disabledColor : AppStyle.appStyle.titleBarDisabledButtonColor;
43
+    }
33 44
 }

+ 27
- 2
android/app/src/main/java/com/reactnativenavigation/params/StyleParams.java Ver arquivo

@@ -1,8 +1,11 @@
1 1
 package com.reactnativenavigation.params;
2 2
 
3
+import android.graphics.Typeface;
3 4
 import android.os.Bundle;
4 5
 import android.support.annotation.ColorInt;
5 6
 
7
+import com.reactnativenavigation.utils.TypefaceLoader;
8
+
6 9
 public class StyleParams {
7 10
     public static class Color {
8 11
         @ColorInt
@@ -41,6 +44,28 @@ public class StyleParams {
41 44
         }
42 45
     }
43 46
 
47
+    public static class Font {
48
+        private Typeface typeface;
49
+
50
+        public Font(String font) {
51
+            typeface = new TypefaceLoader(font).getTypeFace();
52
+        }
53
+
54
+        public Font() {
55
+        }
56
+
57
+        public boolean hasFont() {
58
+            return typeface != null;
59
+        }
60
+
61
+        public Typeface get() {
62
+            if (typeface == null) {
63
+                throw new RuntimeException("Font undefined");
64
+            }
65
+            return typeface;
66
+        }
67
+    }
68
+
44 69
     public Orientation orientation;
45 70
     public Color statusBarColor;
46 71
     public Color contextualMenuStatusBarColor;
@@ -62,7 +87,7 @@ public class StyleParams {
62 87
     public Color titleBarSubtitleColor;
63 88
     public Color titleBarButtonColor;
64 89
     public Color titleBarDisabledButtonColor;
65
-    public String titleBarTitleFont;
90
+    public Font titleBarTitleFont;
66 91
     public boolean titleBarTitleTextCentered;
67 92
     public boolean backButtonHidden;
68 93
 
@@ -88,7 +113,7 @@ public class StyleParams {
88 113
     public boolean forceTitlesDisplay;
89 114
     public Color bottomTabBadgeTextColor;
90 115
     public Color bottomTabBadgeBackgroundColor;
91
-    public String bottomTabFontFamily;
116
+    public Font bottomTabFontFamily;
92 117
 
93 118
     public Color navigationBarColor;
94 119
 }

+ 5
- 15
android/app/src/main/java/com/reactnativenavigation/params/TitleBarButtonParams.java Ver arquivo

@@ -1,22 +1,12 @@
1 1
 package com.reactnativenavigation.params;
2 2
 
3 3
 public class TitleBarButtonParams extends BaseTitleBarButtonParams {
4
-    public String eventId;
5
-    public StyleParams.Color color;
6
-    public StyleParams.Color disabledColor;
7
-    public boolean enabled = true;
4
+    public StyleParams.Font font;
8 5
     public String hint;
9 6
 
10
-    public void setColorFromScreenStyle(StyleParams.Color titleBarButtonColor) {
11
-        if (!color.hasColor() && titleBarButtonColor.hasColor()) {
12
-            color = titleBarButtonColor;
13
-        }
14
-    }
15
-
16
-    public StyleParams.Color getColor() {
17
-        if (enabled) {
18
-            return color;
19
-        }
20
-        return disabledColor.hasColor() ? disabledColor : AppStyle.appStyle.titleBarDisabledButtonColor;
7
+    @Override
8
+    public void setStyleFromScreen(StyleParams styleParams) {
9
+        super.setStyleFromScreen(styleParams);
10
+        font = styleParams.titleBarTitleFont;
21 11
     }
22 12
 }

+ 13
- 4
android/app/src/main/java/com/reactnativenavigation/params/parsers/StyleParamsParser.java Ver arquivo

@@ -43,7 +43,7 @@ public class StyleParamsParser {
43 43
         result.titleBarSubtitleColor = getColor("titleBarSubtitleColor", getDefaultSubtitleBarColor());
44 44
         result.titleBarButtonColor = getColor("titleBarButtonColor", getTitleBarButtonColor());
45 45
         result.titleBarDisabledButtonColor = getColor("titleBarDisabledButtonColor", getTitleBarDisabledButtonColor());
46
-        result.titleBarTitleFont = params.getString("titleBarTitleFont", "");
46
+        result.titleBarTitleFont = getFont("titleBarTitleFontFamily", getDefaultTitleTextFontFamily());
47 47
         result.titleBarTitleTextCentered = getBoolean("titleBarTitleTextCentered", false);
48 48
         result.backButtonHidden = getBoolean("backButtonHidden", getDefaultBackButtonHidden());
49 49
         result.topTabsHidden = getBoolean("topTabsHidden", getDefaultTopTabsHidden());
@@ -75,7 +75,7 @@ public class StyleParamsParser {
75 75
         result.navigationBarColor = getColor("navigationBarColor", getDefaultNavigationColor());
76 76
         result.forceTitlesDisplay = getBoolean("forceTitlesDisplay", getDefaultForceTitlesDisplay());
77 77
 
78
-        result.bottomTabFontFamily = params.getString("bottomTabFontFamily", getDefaultBottomTabFontFamily());
78
+        result.bottomTabFontFamily = getFont("bottomTabFontFamily", getDefaultBottomTabsFontFamily());
79 79
 
80 80
         return result;
81 81
     }
@@ -229,8 +229,12 @@ public class StyleParamsParser {
229 229
         return AppStyle.appStyle == null ? new StyleParams.Color() : AppStyle.appStyle.statusBarColor;
230 230
     }
231 231
 
232
-    private String getDefaultBottomTabFontFamily() {
233
-        return AppStyle.appStyle == null ? "sans-serif" : AppStyle.appStyle.bottomTabFontFamily;
232
+    private StyleParams.Font getDefaultBottomTabsFontFamily() {
233
+        return AppStyle.appStyle == null ? new StyleParams.Font() : AppStyle.appStyle.bottomTabFontFamily;
234
+    }
235
+
236
+    private StyleParams.Font getDefaultTitleTextFontFamily() {
237
+        return AppStyle.appStyle == null ? new StyleParams.Font() : AppStyle.appStyle.titleBarTitleFont;
234 238
     }
235 239
 
236 240
     private boolean getBoolean(String key, boolean defaultValue) {
@@ -246,6 +250,11 @@ public class StyleParamsParser {
246 250
         }
247 251
     }
248 252
 
253
+    private StyleParams.Font getFont(String titleBarTitleFontFamily, StyleParams.Font defaultFont) {
254
+        StyleParams.Font font = new StyleParams.Font(params.getString(titleBarTitleFontFamily));
255
+        return font.hasFont() ? font : defaultFont;
256
+    }
257
+
249 258
     private int getInt(String key, int defaultValue) {
250 259
         return params.containsKey(key) ? params.getInt(key) : defaultValue;
251 260
     }

+ 3
- 3
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java Ver arquivo

@@ -111,7 +111,7 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
111 111
     private void addTitleBarButtons() {
112 112
         setButtonColorFromScreen(screenParams.rightButtons);
113 113
         if (screenParams.leftButton != null) {
114
-            screenParams.leftButton.setColorFromScreenStyle(screenParams.styleParams.titleBarButtonColor);
114
+            screenParams.leftButton.setStyleFromScreen(screenParams.styleParams);
115 115
         }
116 116
         topBar.addTitleBarAndSetButtons(screenParams.rightButtons,
117 117
                 screenParams.leftButton,
@@ -205,7 +205,7 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
205 205
 
206 206
     public void setTitleBarLeftButton(String navigatorEventId, LeftButtonOnClickListener backButtonListener,
207 207
                                       TitleBarLeftButtonParams titleBarLeftButtonParams) {
208
-        titleBarLeftButtonParams.setColorFromScreenStyle(styleParams.titleBarButtonColor);
208
+        titleBarLeftButtonParams.setStyleFromScreen(styleParams);
209 209
         topBar.setTitleBarLeftButton(navigatorEventId,
210 210
                 backButtonListener,
211 211
                 titleBarLeftButtonParams,
@@ -229,7 +229,7 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
229 229
         }
230 230
 
231 231
         for (TitleBarButtonParams titleBarButtonParam : titleBarButtonParams) {
232
-            titleBarButtonParam.setColorFromScreenStyle(screenParams.styleParams.titleBarButtonColor);
232
+            titleBarButtonParam.setStyleFromScreen(screenParams.styleParams);
233 233
         }
234 234
     }
235 235
 

+ 55
- 0
android/app/src/main/java/com/reactnativenavigation/utils/TypefaceLoader.java Ver arquivo

@@ -0,0 +1,55 @@
1
+package com.reactnativenavigation.utils;
2
+
3
+import android.content.res.AssetManager;
4
+import android.graphics.Typeface;
5
+import android.support.annotation.NonNull;
6
+import android.widget.TextView;
7
+
8
+import com.reactnativenavigation.NavigationApplication;
9
+
10
+import java.io.IOException;
11
+import java.util.Arrays;
12
+import java.util.HashMap;
13
+import java.util.List;
14
+import java.util.Map;
15
+
16
+public class TypefaceLoader {
17
+    private static final Map<String, Typeface> typefaceRegistry = new HashMap<>();
18
+
19
+    private String fontFamilyName;
20
+
21
+    public TypefaceLoader(String fontFamilyName) {
22
+        this.fontFamilyName = fontFamilyName;
23
+    }
24
+
25
+    public void load(@NonNull TextView view) {
26
+        Typeface result = getTypeFace();
27
+        view.setTypeface(result);
28
+    }
29
+
30
+    public Typeface getTypeFace() {
31
+        if (typefaceRegistry.containsKey(fontFamilyName)) {
32
+            return typefaceRegistry.get(fontFamilyName);
33
+        }
34
+        Typeface result = load(fontFamilyName);
35
+        typefaceRegistry.put(fontFamilyName, result);
36
+        return result;
37
+    }
38
+
39
+    private Typeface load(String fontFamilyName) {
40
+        AssetManager assets = NavigationApplication.instance.getAssets();
41
+        try {
42
+            List<String> fonts = Arrays.asList(assets.list("fonts"));
43
+            if (fonts.contains(fontFamilyName + ".ttf")) {
44
+                return Typeface.createFromAsset(assets, "fonts/" + fontFamilyName + ".ttf");
45
+            }
46
+
47
+            if (fonts.contains(fontFamilyName + ".otf")) {
48
+                return Typeface.createFromAsset(assets, "fonts/" + fontFamilyName + ".otf");
49
+            }
50
+        } catch (IOException e) {
51
+            e.printStackTrace();
52
+        }
53
+        return Typeface.create(fontFamilyName, Typeface.NORMAL);
54
+    }
55
+}

+ 7
- 0
android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java Ver arquivo

@@ -80,6 +80,13 @@ public class ViewUtils {
80 80
         return metrics.heightPixels;
81 81
     }
82 82
 
83
+    public static float getScreenWidth() {
84
+        WindowManager wm = (WindowManager) NavigationApplication.instance.getSystemService(Context.WINDOW_SERVICE);
85
+        DisplayMetrics metrics = new DisplayMetrics();
86
+        wm.getDefaultDisplay().getMetrics(metrics);
87
+        return metrics.widthPixels;
88
+    }
89
+
83 90
     private static int compatGenerateViewId() {
84 91
         for (; ; ) {
85 92
             final int result = viewId.get();

+ 4
- 29
android/app/src/main/java/com/reactnativenavigation/views/BottomTabs.java Ver arquivo

@@ -1,9 +1,7 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3 3
 import android.content.Context;
4
-import android.content.res.AssetManager;
5 4
 import android.graphics.Color;
6
-import android.graphics.Typeface;
7 5
 import android.text.TextUtils;
8 6
 
9 7
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
@@ -14,8 +12,6 @@ import com.reactnativenavigation.params.ScreenParams;
14 12
 import com.reactnativenavigation.params.StyleParams;
15 13
 import com.reactnativenavigation.utils.ViewUtils;
16 14
 
17
-import java.io.IOException;
18
-import java.util.Arrays;
19 15
 import java.util.List;
20 16
 
21 17
 public class BottomTabs extends AHBottomNavigation {
@@ -28,7 +24,7 @@ public class BottomTabs extends AHBottomNavigation {
28 24
         setId(ViewUtils.generateViewId());
29 25
         createVisibilityAnimator();
30 26
         setStyle();
31
-        setFontFamily(context);
27
+        setFontFamily();
32 28
     }
33 29
 
34 30
     public void addTabs(List<ScreenParams> params, OnTabSelectedListener onTabSelectedListener) {
@@ -125,30 +121,9 @@ public class BottomTabs extends AHBottomNavigation {
125 121
                AppStyle.appStyle.bottomTabBadgeBackgroundColor.hasColor();
126 122
     }
127 123
 
128
-    private boolean hasBottomTabFontFamily() {
129
-        return AppStyle.appStyle.bottomTabFontFamily != null;
130
-    }
131
-
132
-    private void setFontFamily(Context context) {
133
-        if (hasBottomTabFontFamily()) {
134
-
135
-            AssetManager assetManager = context.getAssets();
136
-            String fontFamilyName = AppStyle.appStyle.bottomTabFontFamily;
137
-
138
-            Typeface typeFace = null;
139
-            try {
140
-                boolean hasAsset = Arrays.asList(assetManager.list("fonts")).contains(fontFamilyName);
141
-                typeFace = hasAsset ?
142
-                        Typeface.createFromAsset(assetManager, "fonts/".concat(fontFamilyName))
143
-                        :
144
-                        Typeface.create(fontFamilyName, Typeface.NORMAL);
145
-            } catch (IOException e) {
146
-                e.printStackTrace();
147
-            }
148
-
149
-            if (typeFace != null) {
150
-                setTitleTypeface(typeFace);
151
-            }
124
+    private void setFontFamily() {
125
+        if (AppStyle.appStyle.bottomTabFontFamily.hasFont()) {
126
+            setTitleTypeface(AppStyle.appStyle.bottomTabFontFamily.get());
152 127
         }
153 128
     }
154 129
 }

+ 22
- 35
android/app/src/main/java/com/reactnativenavigation/views/TitleBar.java Ver arquivo

@@ -3,16 +3,12 @@ package com.reactnativenavigation.views;
3 3
 import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5 5
 import android.content.Context;
6
-import android.graphics.Point;
7
-import android.graphics.Typeface;
8 6
 import android.graphics.drawable.Drawable;
9 7
 import android.support.annotation.Nullable;
10 8
 import android.support.v7.widget.ActionMenuView;
11 9
 import android.support.v7.widget.Toolbar;
12
-import android.view.Display;
13 10
 import android.view.Menu;
14 11
 import android.view.View;
15
-import android.view.WindowManager;
16 12
 import android.view.animation.AccelerateDecelerateInterpolator;
17 13
 import android.view.animation.AccelerateInterpolator;
18 14
 import android.widget.TextView;
@@ -29,7 +25,6 @@ public class TitleBar extends Toolbar {
29 25
     private static final int TITLE_VISIBILITY_ANIMATION_DURATION = 320;
30 26
     private LeftButton leftButton;
31 27
     private ActionMenuView actionMenuView;
32
-    private boolean titleBarTitleTextCentered;
33 28
 
34 29
     public TitleBar(Context context) {
35 30
         super(context);
@@ -38,17 +33,6 @@ public class TitleBar extends Toolbar {
38 33
     @Override
39 34
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
40 35
         super.onLayout(changed, l, t, r, b);
41
-
42
-        if (titleBarTitleTextCentered) {
43
-            WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
44
-            Display display = windowManager.getDefaultDisplay();
45
-            Point screenSize = new Point();
46
-            display.getSize(screenSize);
47
-
48
-            int[] location = new int[2];
49
-            getTitleView().getLocationOnScreen(location);
50
-            getTitleView().setTranslationX(getTitleView().getTranslationX() + (-location[0] + screenSize.x / 2 - getTitleView().getWidth() / 2));
51
-        }
52 36
     }
53 37
 
54 38
     @Override
@@ -89,13 +73,31 @@ public class TitleBar extends Toolbar {
89 73
     }
90 74
 
91 75
     public void setStyle(StyleParams params) {
92
-        titleBarTitleTextCentered = params.titleBarTitleTextCentered;
93 76
         setVisibility(params.titleBarHidden ? GONE : VISIBLE);
94 77
         setTitleTextColor(params);
95 78
         setTitleTextFont(params);
96 79
         setSubtitleTextColor(params);
97 80
         colorOverflowButton(params);
98 81
         setBackground(params);
82
+        centerTitle(params);
83
+    }
84
+
85
+    private void centerTitle(final StyleParams params) {
86
+        final View titleView = getTitleView();
87
+        ViewUtils.runOnPreDraw(titleView, new Runnable() {
88
+            @Override
89
+            public void run() {
90
+                if (params.titleBarTitleTextCentered) {
91
+                    if (titleView != null) {
92
+                        int[] location = new int[2];
93
+                        titleView.getLocationOnScreen(location);
94
+                        titleView.setTranslationX(titleView.getTranslationX() + (-location[0] + ViewUtils.getScreenWidth() / 2 - titleView.getWidth() / 2));
95
+                    }
96
+
97
+                }
98
+
99
+            }
100
+        });
99 101
     }
100 102
 
101 103
     private void colorOverflowButton(StyleParams params) {
@@ -126,28 +128,13 @@ public class TitleBar extends Toolbar {
126 128
     }
127 129
 
128 130
     protected void setTitleTextFont(StyleParams params) {
129
-        if (params.titleBarTitleFont == null || params.titleBarTitleFont.isEmpty()) {
131
+        if (params.titleBarTitleFont.hasFont()) {
130 132
             return;
131 133
         }
132
-
133 134
         View titleView = getTitleView();
134
-
135
-        if (titleView == null || !(titleView instanceof TextView)) {
136
-            return;
137
-        }
138
-
139
-        Typeface typeface = null;
140
-
141
-        try {
142
-            typeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + params.titleBarTitleFont + ".ttf");
143
-        } catch (RuntimeException re) {
144
-            try {
145
-                typeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + params.titleBarTitleFont + ".otf");
146
-            } catch (RuntimeException re2) {
147
-                return;
148
-            }
135
+        if (titleView instanceof TextView) {
136
+            ((TextView) titleView).setTypeface(params.titleBarTitleFont.get());
149 137
         }
150
-        ((TextView) titleView).setTypeface(typeface);
151 138
     }
152 139
 
153 140
     protected void setSubtitleTextColor(StyleParams params) {

+ 19
- 2
android/app/src/main/java/com/reactnativenavigation/views/TitleBarButton.java Ver arquivo

@@ -33,6 +33,7 @@ class TitleBarButton implements MenuItem.OnMenuItemClickListener {
33 33
         item.setEnabled(buttonParams.enabled);
34 34
         setIcon(item);
35 35
         setColor();
36
+        setFont();
36 37
         item.setOnMenuItemClickListener(this);
37 38
         return item;
38 39
     }
@@ -69,6 +70,14 @@ class TitleBarButton implements MenuItem.OnMenuItemClickListener {
69 70
         });
70 71
     }
71 72
 
73
+    private void setFont() {
74
+        if (buttonParams.font == null) {
75
+            return;
76
+        }
77
+        ArrayList<View> buttons = findActualTextViewInMenuByLabel();
78
+        setTextFontForFoundButtonViews(buttons);
79
+    }
80
+
72 81
     @NonNull
73 82
     private ArrayList<View> findActualTextViewInMenuByLabel() {
74 83
         ArrayList<View> outViews = new ArrayList<>();
@@ -76,12 +85,20 @@ class TitleBarButton implements MenuItem.OnMenuItemClickListener {
76 85
         return outViews;
77 86
     }
78 87
 
79
-    private void setTextColorForFoundButtonViews(ArrayList<View> outViews) {
80
-        for (View button : outViews) {
88
+    private void setTextColorForFoundButtonViews(ArrayList<View> buttons) {
89
+        for (View button : buttons) {
81 90
             ((TextView) button).setTextColor(buttonParams.getColor().getColor());
82 91
         }
83 92
     }
84 93
 
94
+    private void setTextFontForFoundButtonViews(ArrayList<View> buttons) {
95
+        for (View button : buttons) {
96
+            if (buttonParams.font.hasFont()) {
97
+                ((TextView) button).setTypeface(buttonParams.font.get());
98
+            }
99
+        }
100
+    }
101
+
85 102
     private boolean hasIcon() {
86 103
         return buttonParams.icon != null;
87 104
     }

+ 1
- 1
src/deprecated/platformSpecificDeprecated.android.js Ver arquivo

@@ -154,7 +154,7 @@ function convertStyleParams(originalStyleObject) {
154 154
     titleBarSubtitleColor: processColor(originalStyleObject.navBarSubtitleColor),
155 155
     titleBarButtonColor: processColor(originalStyleObject.navBarButtonColor),
156 156
     titleBarDisabledButtonColor: processColor(originalStyleObject.titleBarDisabledButtonColor),
157
-    titleBarTitleFont: originalStyleObject.navBarTitleFont,
157
+    titleBarTitleFontFamily: originalStyleObject.navBarTextFontFamily,
158 158
     titleBarTitleTextCentered: originalStyleObject.navBarTitleTextCentered,
159 159
     backButtonHidden: originalStyleObject.backButtonHidden,
160 160
     topTabsHidden: originalStyleObject.topTabsHidden,