Files
react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java
T
Misha Greenberg 9f5bdd7b49 Size height of Android Text component based on includeFontPadding style
Summary:
Overview -

This PR resolves the issue described in #14606. This PR makes Text components take into account the includeFontPadding property when calculating their size.

Background -

Currently, on Android, when includeFontPadding is set to false, the React Text component does not adjust its height. This makes it difficult to lay out other components at a precise spacing relative to a Text component.

iOS calculates the height of a UILabel based on the font's descent + ascent.

Android lets you choose whether to calculate the height of a TextView based on the font's top + bottom (includeFontPadding=true) or ascent + descent (includeFontPadding=false).

In order for a text component to be the same size on iOS and Android (relative to the rest of the layout in points and dips), one should set includeFontPadding=false on Android - but the React Text component needs to take this property into account when sizing itself for this to work.

Please see this stack overflow post for a visual explanation of the difference between a font's ascent/descent and top/bottom - https://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font

Testing -

Please see the attached screenshots to see the height difference of a Text component with this PR when includeFontPadding is true vs false.

The font I am using has an ascent + descent = em-size so that the height of the Text component will be equal to the font-size for a single line of text. This is to clearly show the additional height that includeFontPadding=true adds to the Text component.

For Text components that are styled in the same way,

When includeFontPadding=true, height = ~29.714 dips
When includeFontPadding=false, height= 24 dips

<img width="342" alt="includefontpaddingtrue" src="https://user-images.githubusercontent.com/1437344/27299391-3eec9de0-54fa-11e7-81d5-d0aeb40e8e27.png">

<img width="346" alt="includefontpaddingfalse" src="https://user-images.githubusercontent.com/1437344/27299401-45c95248-54fa-11e7-98d7-17dd152d3cb8.png">
Closes https://github.com/facebook/react-native/pull/14609

Reviewed By: AaaChiuuu

Differential Revision: D5587602

Pulled By: achen1

fbshipit-source-id: 6d2f12ba72ec7462676645519cd27820279278eb
2017-08-18 15:31:01 -07:00

178 lines
6.8 KiB
Java

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.uimanager;
import java.util.Arrays;
import java.util.HashSet;
import com.facebook.react.bridge.ReadableMap;
/**
* Keys for props that need to be shared across multiple classes.
*/
public class ViewProps {
public static final String VIEW_CLASS_NAME = "RCTView";
// Layout only (only affect positions of children, causes no drawing)
// !!! Keep in sync with LAYOUT_ONLY_PROPS below
public static final String ALIGN_ITEMS = "alignItems";
public static final String ALIGN_SELF = "alignSelf";
public static final String ALIGN_CONTENT = "alignContent";
public static final String OVERFLOW = "overflow";
public static final String DISPLAY = "display";
public static final String BOTTOM = "bottom";
public static final String COLLAPSABLE = "collapsable";
public static final String FLEX = "flex";
public static final String FLEX_GROW = "flexGrow";
public static final String FLEX_SHRINK = "flexShrink";
public static final String FLEX_BASIS = "flexBasis";
public static final String FLEX_DIRECTION = "flexDirection";
public static final String FLEX_WRAP = "flexWrap";
public static final String HEIGHT = "height";
public static final String JUSTIFY_CONTENT = "justifyContent";
public static final String LEFT = "left";
public static final String MARGIN = "margin";
public static final String MARGIN_VERTICAL = "marginVertical";
public static final String MARGIN_HORIZONTAL = "marginHorizontal";
public static final String MARGIN_LEFT = "marginLeft";
public static final String MARGIN_RIGHT = "marginRight";
public static final String MARGIN_TOP = "marginTop";
public static final String MARGIN_BOTTOM = "marginBottom";
public static final String PADDING = "padding";
public static final String PADDING_VERTICAL = "paddingVertical";
public static final String PADDING_HORIZONTAL = "paddingHorizontal";
public static final String PADDING_LEFT = "paddingLeft";
public static final String PADDING_RIGHT = "paddingRight";
public static final String PADDING_TOP = "paddingTop";
public static final String PADDING_BOTTOM = "paddingBottom";
public static final String POSITION = "position";
public static final String RIGHT = "right";
public static final String TOP = "top";
public static final String WIDTH = "width";
public static final String MIN_WIDTH = "minWidth";
public static final String MAX_WIDTH = "maxWidth";
public static final String MIN_HEIGHT = "minHeight";
public static final String MAX_HEIGHT = "maxHeight";
public static final String ASPECT_RATIO = "aspectRatio";
// Props that sometimes may prevent us from collapsing views
public static final String POINTER_EVENTS = "pointerEvents";
// Props that affect more than just layout
public static final String ENABLED = "enabled";
public static final String BACKGROUND_COLOR = "backgroundColor";
public static final String COLOR = "color";
public static final String FONT_SIZE = "fontSize";
public static final String FONT_WEIGHT = "fontWeight";
public static final String FONT_STYLE = "fontStyle";
public static final String FONT_FAMILY = "fontFamily";
public static final String LINE_HEIGHT = "lineHeight";
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
public static final String NUMBER_OF_LINES = "numberOfLines";
public static final String ELLIPSIZE_MODE = "ellipsizeMode";
public static final String ON = "on";
public static final String RESIZE_MODE = "resizeMode";
public static final String RESIZE_METHOD = "resizeMethod";
public static final String TEXT_ALIGN = "textAlign";
public static final String TEXT_ALIGN_VERTICAL = "textAlignVertical";
public static final String TEXT_DECORATION_LINE = "textDecorationLine";
public static final String TEXT_BREAK_STRATEGY = "textBreakStrategy";
public static final String ALLOW_FONT_SCALING = "allowFontScaling";
public static final String INCLUDE_FONT_PADDING = "includeFontPadding";
public static final String BORDER_WIDTH = "borderWidth";
public static final String BORDER_LEFT_WIDTH = "borderLeftWidth";
public static final String BORDER_TOP_WIDTH = "borderTopWidth";
public static final String BORDER_RIGHT_WIDTH = "borderRightWidth";
public static final String BORDER_BOTTOM_WIDTH = "borderBottomWidth";
public static final String BORDER_RADIUS = "borderRadius";
public static final String BORDER_TOP_LEFT_RADIUS = "borderTopLeftRadius";
public static final String BORDER_TOP_RIGHT_RADIUS = "borderTopRightRadius";
public static final String BORDER_BOTTOM_LEFT_RADIUS = "borderBottomLeftRadius";
public static final String BORDER_BOTTOM_RIGHT_RADIUS = "borderBottomRightRadius";
public static final int[] BORDER_SPACING_TYPES = {
Spacing.ALL, Spacing.START, Spacing.END, Spacing.TOP, Spacing.BOTTOM
};
public static final int[] PADDING_MARGIN_SPACING_TYPES = {
Spacing.ALL, Spacing.VERTICAL, Spacing.HORIZONTAL, Spacing.START, Spacing.END, Spacing.TOP,
Spacing.BOTTOM
};
public static final int[] POSITION_SPACING_TYPES = {
Spacing.START, Spacing.END, Spacing.TOP, Spacing.BOTTOM
};
private static final HashSet<String> LAYOUT_ONLY_PROPS = new HashSet<>(
Arrays.asList(
ALIGN_SELF,
ALIGN_ITEMS,
COLLAPSABLE,
FLEX,
FLEX_BASIS,
FLEX_DIRECTION,
FLEX_GROW,
FLEX_SHRINK,
FLEX_WRAP,
JUSTIFY_CONTENT,
OVERFLOW,
ALIGN_CONTENT,
DISPLAY,
/* position */
POSITION,
RIGHT,
TOP,
BOTTOM,
LEFT,
/* dimensions */
WIDTH,
HEIGHT,
MIN_WIDTH,
MAX_WIDTH,
MIN_HEIGHT,
MAX_HEIGHT,
/* margins */
MARGIN,
MARGIN_VERTICAL,
MARGIN_HORIZONTAL,
MARGIN_LEFT,
MARGIN_RIGHT,
MARGIN_TOP,
MARGIN_BOTTOM,
/* paddings */
PADDING,
PADDING_VERTICAL,
PADDING_HORIZONTAL,
PADDING_LEFT,
PADDING_RIGHT,
PADDING_TOP,
PADDING_BOTTOM));
public static boolean isLayoutOnly(ReadableMap map, String prop) {
if (LAYOUT_ONLY_PROPS.contains(prop)) {
return true;
} else if (POINTER_EVENTS.equals(prop)) {
String value = map.getString(prop);
return "auto".equals(value) || "box-none".equals(value);
} else {
return false;
}
}
}