Browse Source

[V2] Android topbar font family (#1882)

* android oreo overdraw fix

* apply top bar title color

* update readme

* update formatting

* merge v2

* navigation oprtions formatting

* font size props

* update test

* ci fix

* rm global variable

* font size

* update readme

* playground

* after merge fix

* typeface in progress

* presenter skeleton

* test fix

* rm presentation

* options presenter

* typeface

* readme

* test refactoring

* typeface loader tests
Roman Kozlov 7 years ago
parent
commit
8832a3a9d3

+ 1
- 1
README.md View File

@@ -72,7 +72,7 @@ Note:  v1 properties with names beginning with 'navBar' are replaced in v2 with
72 72
 |-----------------------|-----|--------|------------|------------|
73 73
 | topBarTextColor |   ✅    |    ✅     |     ✅        | Wix|
74 74
 | topBarTextFontSize    |   ✅    |    ✅      |     ✅        | Wix|
75
-| topBarTextFontFamily  |  ✅     |      ✅     |     [Contribute](/docs/docs/CONTRIBUTING.md)        | Wix |
75
+| topBarTextFontFamily  |  ✅     |      ✅     |             | Wix |
76 76
 | topBarBackgroundColor |  ✅     |  ✅       |     ✅         | Wix|
77 77
 | topBarButtonColor     |  ✅     |    ✅      |     [Contribute](/docs/docs/CONTRIBUTING.md)        | Wix|
78 78
 | topBarHidden          |   ✅    |   ✅      |     [Contribute](/docs/docs/CONTRIBUTING.md)        | Wix|

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

@@ -16,6 +16,7 @@ public class NavigationOptions {
16 16
 		result.topBarBackgroundColor = json.optInt("topBarBackgroundColor");
17 17
 		result.topBarTextColor = json.optInt("topBarTextColor");
18 18
 		result.topBarTextFontSize = (float) json.optDouble("topBarTextFontSize");
19
+		result.topBarTextFontFamily = json.optString("topBarTextFontFamily");
19 20
 
20 21
 		return result;
21 22
 	}
@@ -25,11 +26,13 @@ public class NavigationOptions {
25 26
 	@ColorInt
26 27
 	public int topBarTextColor;
27 28
 	public float topBarTextFontSize;
29
+	public String topBarTextFontFamily;
28 30
 
29 31
 	public void mergeWith(final NavigationOptions other) {
30 32
 		title = other.title;
31 33
 		topBarBackgroundColor = other.topBarBackgroundColor;
32 34
 		topBarTextColor = other.topBarTextColor;
33 35
 		topBarTextFontSize = other.topBarTextFontSize;
36
+		topBarTextFontFamily = other.topBarTextFontFamily;
34 37
 	}
35 38
 }

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

@@ -1,6 +1,7 @@
1 1
 package com.reactnativenavigation.presentation;
2 2
 
3 3
 import com.reactnativenavigation.parse.NavigationOptions;
4
+import com.reactnativenavigation.utils.TypefaceLoader;
4 5
 import com.reactnativenavigation.viewcontrollers.StackController;
5 6
 
6 7
 /**
@@ -21,6 +22,8 @@ public class OptionsPresenter {
21 22
 			controller.getTopBar().setBackgroundColor(options.topBarBackgroundColor);
22 23
 			controller.getTopBar().setTitleTextColor(options.topBarTextColor);
23 24
 			controller.getTopBar().setTitleFontSize(options.topBarTextFontSize);
25
+			TypefaceLoader typefaceLoader = new TypefaceLoader();
26
+			controller.getTopBar().setTitleTypeface(typefaceLoader.getTypeFace(controller.getActivity(), options.topBarTextFontFamily));
24 27
 		}
25 28
 	}
26 29
 }

+ 67
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/TypefaceLoader.java View File

@@ -0,0 +1,67 @@
1
+package com.reactnativenavigation.utils;
2
+
3
+import android.content.Context;
4
+import android.content.res.AssetManager;
5
+import android.graphics.Typeface;
6
+import android.support.annotation.Nullable;
7
+
8
+import java.io.IOException;
9
+import java.util.Arrays;
10
+import java.util.HashMap;
11
+import java.util.List;
12
+import java.util.Map;
13
+
14
+public class TypefaceLoader {
15
+	private static final Map<String, Typeface> typefaceCache = new HashMap<>();
16
+
17
+	public Typeface getTypeFace(Context context, String fontFamilyName) {
18
+		if (fontFamilyName == null) {
19
+			return null;
20
+		}
21
+		if (typefaceCache.containsKey(fontFamilyName)) {
22
+			return typefaceCache.get(fontFamilyName);
23
+		}
24
+		Typeface result = load(context, fontFamilyName);
25
+		typefaceCache.put(fontFamilyName, result);
26
+		return result;
27
+	}
28
+
29
+	private Typeface load(Context context, String fontFamilyName) {
30
+		Typeface typeface = getTypefaceFromAssets(context, fontFamilyName);
31
+		if (typeface != null) return typeface;
32
+
33
+		int style = getStyle(fontFamilyName);
34
+		return Typeface.create(fontFamilyName, style);
35
+	}
36
+
37
+	private int getStyle(String fontFamilyName) {
38
+		int style = Typeface.NORMAL;
39
+		if (fontFamilyName.toLowerCase().contains("bold")) {
40
+			style = Typeface.BOLD;
41
+		} else if (fontFamilyName.toLowerCase().contains("italic")) {
42
+			style = Typeface.ITALIC;
43
+		}
44
+		return style;
45
+	}
46
+
47
+	@Nullable
48
+	Typeface getTypefaceFromAssets(Context context, String fontFamilyName) {
49
+		try {
50
+			if (context != null) {
51
+				AssetManager assets = context.getAssets();
52
+				List<String> fonts = Arrays.asList(assets.list("fonts"));
53
+				if (fonts.contains(fontFamilyName + ".ttf")) {
54
+					return Typeface.createFromAsset(assets, "fonts/" + fontFamilyName + ".ttf");
55
+				}
56
+
57
+				if (fonts.contains(fontFamilyName + ".otf")) {
58
+					return Typeface.createFromAsset(assets, "fonts/" + fontFamilyName + ".otf");
59
+				}
60
+			}
61
+		} catch (IOException e) {
62
+			e.printStackTrace();
63
+		}
64
+		return null;
65
+	}
66
+}
67
+

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

@@ -29,7 +29,6 @@ public class ContainerViewController extends ViewController {
29 29
 	}
30 30
 
31 31
 	private final String containerName;
32
-	private OptionsPresenter optionsPresenter;
33 32
 
34 33
 	private final ContainerViewCreator viewCreator;
35 34
 	private final NavigationOptions navigationOptions;

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

@@ -1,6 +1,7 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3 3
 import android.app.Activity;
4
+import android.graphics.Typeface;
4 5
 import android.support.annotation.ColorInt;
5 6
 import android.support.annotation.Nullable;
6 7
 import android.support.design.widget.AppBarLayout;
@@ -37,6 +38,13 @@ public class TopBar extends AppBarLayout {
37 38
 		}
38 39
 	}
39 40
 
41
+	public void setTitleTypeface(Typeface typeface) {
42
+		TextView titleTextView = getTitleTextView();
43
+		if (titleTextView != null) {
44
+			titleTextView.setTypeface(typeface);
45
+		}
46
+	}
47
+
40 48
 	public TextView getTitleTextView() {
41 49
 		return findTextView(titleBar);
42 50
 	}

+ 2
- 0
lib/android/app/src/test/java/com/reactnativenavigation/parse/NavigationOptionsTest.java View File

@@ -21,12 +21,14 @@ public class NavigationOptionsTest extends BaseTest {
21 21
 		json.put("topBarBackgroundColor", 0xff123456);
22 22
 		json.put("topBarTextColor", 0xff123456);
23 23
 		json.put("topBarTextFontSize", 18);
24
+		json.put("topBarTextFontFamily", "HelveticaNeue-CondensedBold");
24 25
 
25 26
 		NavigationOptions result = NavigationOptions.parse(json);
26 27
 		assertThat(result.title).isEqualTo("the title");
27 28
 		assertThat(result.topBarBackgroundColor).isEqualTo(0xff123456);
28 29
 		assertThat(result.topBarTextColor).isEqualTo(0xff123456);
29 30
 		assertThat(result.topBarTextFontSize).isEqualTo(18);
31
+		assertThat(result.topBarTextFontFamily).isEqualTo("HelveticaNeue-CondensedBold");
30 32
 	}
31 33
 
32 34
 	@Test

+ 66
- 0
lib/android/app/src/test/java/com/reactnativenavigation/utils/TypefaceLoaderTest.java View File

@@ -0,0 +1,66 @@
1
+package com.reactnativenavigation.utils;
2
+
3
+import android.content.Context;
4
+import android.graphics.Typeface;
5
+import android.test.mock.MockContext;
6
+
7
+import com.reactnativenavigation.BaseTest;
8
+
9
+import org.junit.Test;
10
+import org.mockito.Mockito;
11
+
12
+import java.io.IOException;
13
+
14
+import static org.assertj.core.api.Java6Assertions.assertThat;
15
+
16
+/**
17
+ * Created by romanko on 9/19/17.
18
+ */
19
+
20
+public class TypefaceLoaderTest extends BaseTest {
21
+
22
+	@Test
23
+	public void loadTypefaceNoAssets() {
24
+		Context context = new MockContext();
25
+		TypefaceLoader mockedLoader = Mockito.spy(TypefaceLoader.class);
26
+		Mockito.doReturn(null).when(mockedLoader).getTypefaceFromAssets(context, "Helvetica-Bold");
27
+
28
+		Typeface typeface = mockedLoader.getTypeFace(context, "Helvetica-Bold");
29
+		assertThat(typeface).isNotNull();
30
+		assertThat(typeface.getStyle()).isEqualTo(Typeface.BOLD);
31
+	}
32
+
33
+	@Test
34
+	public void loadTypefaceWithAssets() {
35
+		Context context = new MockContext();
36
+		TypefaceLoader mockedLoader = Mockito.spy(TypefaceLoader.class);
37
+		Mockito.doReturn(Typeface.create("Helvetica-Italic", Typeface.ITALIC)).when(mockedLoader).getTypefaceFromAssets(context, "Helvetica-Italic");
38
+
39
+		Typeface typeface = mockedLoader.getTypeFace(context, "Helvetica-Italic");
40
+		assertThat(typeface).isNotNull();
41
+		assertThat(typeface.getStyle()).isEqualTo(Typeface.ITALIC);
42
+	}
43
+
44
+	@Test
45
+	public void loadTypefaceWrongName() {
46
+		Context context = new MockContext();
47
+		TypefaceLoader mockedLoader = Mockito.spy(TypefaceLoader.class);
48
+		Mockito.doReturn(null).when(mockedLoader).getTypefaceFromAssets(context, "Some-name");
49
+
50
+		Typeface typeface = mockedLoader.getTypeFace(context, "Some-name");
51
+		assertThat(typeface).isNotNull();
52
+		assertThat(typeface.getStyle()).isEqualTo(Typeface.NORMAL);
53
+	}
54
+
55
+	@Test
56
+	public void loadTypefaceNull() {
57
+		Context context = new MockContext();
58
+		TypefaceLoader mockedLoader = Mockito.spy(TypefaceLoader.class);
59
+		Mockito.doReturn(null).when(mockedLoader).getTypefaceFromAssets(context, null);
60
+
61
+		Typeface typeface = mockedLoader.getTypeFace(context, null);
62
+		assertThat(typeface).isNull();
63
+	}
64
+}
65
+
66
+