Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android support topbar title font scaling #7904

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import android.content.Context;

import com.reactnativenavigation.options.params.Bool;
import com.reactnativenavigation.options.params.Fraction;
import com.reactnativenavigation.options.params.NullBool;
import com.reactnativenavigation.options.params.NullFraction;
import com.reactnativenavigation.options.params.NullNumber;
import com.reactnativenavigation.options.params.NullText;
Expand All @@ -15,6 +17,7 @@
import com.reactnativenavigation.options.parsers.NumberParser;
import com.reactnativenavigation.options.parsers.TextParser;
import com.reactnativenavigation.options.parsers.TypefaceLoader;
import com.reactnativenavigation.options.parsers.BoolParser;

import org.json.JSONObject;

Expand All @@ -32,6 +35,7 @@ public static TitleOptions parse(Context context, TypefaceLoader typefaceManager
options.alignment = Alignment.fromString(TextParser.parse(json, "alignment").get(""));
options.height = NumberParser.parse(json, "height");
options.topMargin = NumberParser.parse(json, "topMargin");
options.allowFontScaling = BoolParser.parse(json, "allowFontScaling");

return options;
}
Expand All @@ -44,6 +48,7 @@ public static TitleOptions parse(Context context, TypefaceLoader typefaceManager
public ComponentOptions component = new ComponentOptions();
public Number height = new NullNumber();
public Number topMargin = new NullNumber();
public Bool allowFontScaling = new NullBool();

void mergeWith(final TitleOptions other) {
if (other.text.hasValue()) {
Expand All @@ -61,6 +66,7 @@ void mergeWith(final TitleOptions other) {
if (other.component.hasValue()) component = other.component;
if (other.height.hasValue()) height = other.height;
if (other.topMargin.hasValue()) topMargin = other.topMargin;
if (other.allowFontScaling.hasValue()) allowFontScaling = other.allowFontScaling;
}

void mergeWithDefault(TitleOptions defaultOptions) {
Expand All @@ -72,5 +78,6 @@ void mergeWithDefault(TitleOptions defaultOptions) {
component.mergeWithDefault(defaultOptions.component);
if (!height.hasValue()) height = defaultOptions.height;
if (!topMargin.hasValue()) topMargin = defaultOptions.topMargin;
if (!allowFontScaling.hasValue()) allowFontScaling = defaultOptions.allowFontScaling;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ private void mergeTopBarOptions(TopBarOptions resolveOptions, Options toMerge, S
topBar.setTitleTextColor(resolveOptions.title.color.get());
if (resolveOptions.title.fontSize.hasValue())
topBar.setTitleFontSize(resolveOptions.title.fontSize.get());
if (resolveOptions.title.allowFontScaling.hasValue())
topBar.setTitleAllowFontScaling(resolveOptions.title.allowFontScaling.isTrue());
if (resolveOptions.title.font.hasValue())
topBar.setTitleTypeface(typefaceLoader, resolveOptions.title.font);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.reactnativenavigation.options.LayoutDirection;
import com.reactnativenavigation.options.SubtitleOptions;
import com.reactnativenavigation.options.TitleOptions;
import com.reactnativenavigation.options.params.Bool;
import com.reactnativenavigation.options.params.Number;
import com.reactnativenavigation.options.params.ThemeColour;
import com.reactnativenavigation.options.parsers.TypefaceLoader;
Expand Down Expand Up @@ -192,6 +193,10 @@ public void setTitleFontSize(double size) {
titleAndButtonsContainer.setTitleFontSize((float) size);
}

public void setTitleAllowFontScaling(boolean enabled) {
titleAndButtonsContainer.setTitleAllowFontScaling(enabled);
}

public void setTitleTypeface(TypefaceLoader typefaceLoader, FontOptions font) {
if (typefaceLoader != null)
titleAndButtonsContainer.setTitleTypeface(typefaceLoader, font);
Expand Down Expand Up @@ -352,6 +357,7 @@ public void applyTitleOptions(TitleOptions titleOptions, TypefaceLoader typeface
final double DEFAULT_TITLE_FONT_SIZE = 18;
this.setTitle(titleOptions.text.get(""));
this.setTitleFontSize(titleOptions.fontSize.get(DEFAULT_TITLE_FONT_SIZE));
this.setTitleAllowFontScaling(titleOptions.allowFontScaling.isTrue());
this.setTitleTextColor(titleOptions.color.get(DEFAULT_TITLE_COLOR));
this.setTitleTypeface(typefaceLoader, titleOptions.font);
this.setTitleAlignment(titleOptions.alignment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class TitleAndButtonsContainer(context: Context) : ViewGroup(context) {

fun setTitleFontSize(size: Float) = titleSubTitleBar.setTitleFontSize(size)

fun setTitleAllowFontScaling(enabled: Boolean) = titleSubTitleBar.setTitleAllowFontScaling(enabled)

fun setTitleTypeface(typefaceLoader: TypefaceLoader, font: FontOptions) = titleSubTitleBar.setTitleTypeface(typefaceLoader, font)

fun setSubtitleTypeface(typefaceLoader: TypefaceLoader, font: FontOptions) = titleSubTitleBar.setSubtitleTypeface(typefaceLoader, font)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class TitleSubTitleLayout(context: Context) : LinearLayout(context) {

private val titleTextView = SingleLineTextView(context, DEFAULT_TITLE_FONT_SIZE_DP)
private val subTitleTextView = SingleLineTextView(context, DEFAULT_SUBTITLE_FONT_SIZE_DP)
private var titleAllowFontScaling = false
private var titleFontSize = DEFAULT_TITLE_FONT_SIZE_DP

init {
this.orientation = VERTICAL
Expand Down Expand Up @@ -46,7 +48,16 @@ class TitleSubTitleLayout(context: Context) : LinearLayout(context) {
}
}

fun setTitleFontSize(size: Float) = titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size)
fun setTitleFontSize(size: Float) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For it to make sense from the perspective of options, I didn't find a way to set units without setting font size. Using titleTextView.textSize returns scaled font size, so need to have the absolute font size somewhere

val unit = if(this.titleAllowFontScaling) TypedValue.COMPLEX_UNIT_SP else TypedValue.COMPLEX_UNIT_DIP
this.titleFontSize = size
titleTextView.setTextSize(unit, size)
}

fun setTitleAllowFontScaling(enabled: Boolean) {
this.titleAllowFontScaling = enabled
this.setTitleFontSize(this.titleFontSize)
}

fun setSubtitleFontSize(size: Float) = subTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size)

Expand Down Expand Up @@ -101,4 +112,4 @@ class TitleSubTitleLayout(context: Context) : LinearLayout(context) {
fun getSubTitleTxtView(): TextView {
return this.subTitleTextView
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import com.reactnativenavigation.fakes.IconResolverFake
import com.reactnativenavigation.mocks.*
import com.reactnativenavigation.options.*
import com.reactnativenavigation.options.params.*
import com.reactnativenavigation.options.params.Number
import com.reactnativenavigation.options.parsers.TypefaceLoader
import com.reactnativenavigation.react.CommandListenerAdapter
import com.reactnativenavigation.utils.*
Expand All @@ -36,7 +35,6 @@ import org.json.JSONObject
import org.junit.Test
import org.mockito.Mockito
import org.robolectric.shadows.ShadowLooper
import java.util.*
import kotlin.collections.ArrayList


Expand Down Expand Up @@ -495,6 +493,7 @@ class StackPresenterTest : BaseTest() {
parent.mergeOptions(parentOptions)
val defaultOptions = Options()
defaultOptions.topBar.title.fontSize = Fraction(9.0)
defaultOptions.topBar.title.allowFontScaling = Bool(true);
uut.defaultOptions = defaultOptions
val toMerge = Options()
toMerge.topBar.title.text = Text("New Title")
Expand All @@ -503,6 +502,7 @@ class StackPresenterTest : BaseTest() {
assertThat(title).isNotNull()
assertThat(title.typeface).isEqualTo(SOME_TYPEFACE)
verify(topBar).setTitleFontSize(9.0)
verify(topBar).setTitleAllowFontScaling(true)
verify(topBar).setTitleTextColor(Color.RED)
}

Expand Down Expand Up @@ -531,6 +531,7 @@ class StackPresenterTest : BaseTest() {
fun mergeChildOptions_resolvedTitleFontOptionsAreApplied() {
val defaultOptions = Options()
defaultOptions.topBar.title.fontSize = Fraction(9.0)
defaultOptions.topBar.title.allowFontScaling = Bool(false)
uut.defaultOptions = defaultOptions
val resolvedOptions = Options()
resolvedOptions.topBar.title.font.fontFamily = Text(SOME_FONT_FAMILY)
Expand All @@ -542,6 +543,7 @@ class StackPresenterTest : BaseTest() {
assertThat(title).isNotNull()
assertThat(title.typeface).isEqualTo(SOME_TYPEFACE)
verify(topBar).setTitleFontSize(9.0)
verify(topBar).setTitleAllowFontScaling(false)
verify(topBar).setTitleTextColor(Color.RED)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.reactnativenavigation.views

import android.app.Activity
import android.graphics.Color
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
Expand All @@ -23,12 +24,14 @@ import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat
import org.junit.Test
import org.mockito.Mockito
import org.mockito.Mockito.times
import org.robolectric.annotation.Config
import kotlin.math.roundToInt
import kotlin.test.assertFalse

private const val UUT_WIDTH = 1000
private const val UUT_HEIGHT = 100

@Config(sdk = [30])
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

textSizeUnit is not available before api level 30

class TitleAndButtonsContainerTest : BaseTest() {
lateinit var uut: TitleAndButtonsContainer
private lateinit var activity: Activity
Expand Down Expand Up @@ -448,7 +451,25 @@ class TitleAndButtonsContainerTest : BaseTest() {
assertThat(getTitleSubtitleView().getSubTitleTxtView().currentTextColor).isEqualTo(Color.YELLOW)
}

@Test
fun `setTitleAllowFontScaling - when using default value, should have font size units set to DIP`() {
assertThat(getTitleSubtitleView().getTitleTxtView().textSizeUnit).isEqualTo(TypedValue.COMPLEX_UNIT_DIP)
}

@Test
fun `setTitleAllowFontScaling - when set to true, should set font size units to SP`() {
assertThat(getTitleSubtitleView().getTitleTxtView().textSizeUnit).isEqualTo(TypedValue.COMPLEX_UNIT_DIP)
uut.setTitleAllowFontScaling(true)
assertThat(getTitleSubtitleView().getTitleTxtView().textSizeUnit).isEqualTo(TypedValue.COMPLEX_UNIT_SP)
}

@Test
fun `setTitleAllowFontScaling - when set to false, should set font size units to DIP`() {
uut.setTitleAllowFontScaling(true)
assertThat(getTitleSubtitleView().getTitleTxtView().textSizeUnit).isEqualTo(TypedValue.COMPLEX_UNIT_SP)
uut.setTitleAllowFontScaling(false)
assertThat(getTitleSubtitleView().getTitleTxtView().textSizeUnit).isEqualTo(TypedValue.COMPLEX_UNIT_DIP)
}

@Test
fun getTitle_returnCurrentTextInTitleTextView() {
Expand Down
1 change: 1 addition & 0 deletions lib/src/interfaces/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ export interface OptionsTopBarTitle {
* Font size
*/
fontSize?: number;
allowFontScaling?: boolean;
/**
* Text color
*/
Expand Down
21 changes: 21 additions & 0 deletions playground/src/screens/StackScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const {
STACK_COMMANDS_BTN,
SET_ROOT_NAVIGATION_TAB,
POP_BTN,
PUSH_TITLE_WITH_FONT_SCALING,
} = testIDs;

export default class StackScreen extends React.Component<NavigationProps> {
Expand Down Expand Up @@ -65,6 +66,11 @@ export default class StackScreen extends React.Component<NavigationProps> {
testID={PUSH_TITLE_WITH_SUBTITLE}
onPress={this.pushTitleWithSubtitle}
/>
<Button
label="Push Title With Font Scaling"
testID={PUSH_TITLE_WITH_FONT_SCALING}
onPress={this.pushTitleWithFontScaling}
/>
<Button label="Set Stack Root" testID={SET_STACK_ROOT_BTN} onPress={this.setStackRoot} />
<Button
label="Set Stack Root With ID"
Expand Down Expand Up @@ -133,6 +139,21 @@ export default class StackScreen extends React.Component<NavigationProps> {
},
});

pushTitleWithFontScaling = () =>
Navigation.push(this, {
component: {
name: Screens.Stack,
options: {
topBar: {
title: {
text: 'Title with font scaling',
allowFontScaling: true,
},
},
},
},
});

search = () => Navigation.push(this, Screens.Search);

setStackRoot = () =>
Expand Down
1 change: 1 addition & 0 deletions playground/src/testIDs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const testIDs = {
CUSTOM_BACK_BTN: 'CUSTOM_BACK_BUTTON',
PUSH_CUSTOM_BACK_BTN: 'PUSH_CUSTOM_BACK_BTN',
PUSH_TITLE_WITH_SUBTITLE: 'PUSH_TITLE_WITH_SUBTITLE',
PUSH_TITLE_WITH_FONT_SCALING: 'PUSH_TITLE_WITH_FONT_SCALING',
TOPBAR_ID: 'TOPBAR_ID',
BACK_BUTTON: 'BACK_BUTTON',
TOGGLE_BACK: 'TOGGLE_BACK',
Expand Down