【问题标题】:Problem with Handling different screen sizes in Android-React native在 Android-React 本机中处理不同屏幕尺寸的问题
【发布时间】:2020-03-06 07:15:14
【问题描述】:

我对为应用处理不同尺寸的屏幕感到有些困惑。

在 android 中有一个名为 dp 的单元似乎可以处理屏幕尺寸和分辨率的变化。我希望当我使用这个单位而不是像素时,我会在每个屏幕上看到相同大小的component(如按钮,...)。例如,大小为 20dp 的按钮在所有屏幕上的大小必须相同。

在我读到的文章中,React-Native 也使用 dp 作为其主要单元。所以在这里期待同样的事情,但它没有像我预期的那样工作。带有20dp 的按钮在不同的屏幕上看起来不一样。

还有一些文章展示了如何处理不同的屏幕尺寸,尽管他们说 RN 使用 dp,但他们使用一些算术逻辑将其组件缩放到每个屏幕尺寸。

例如const scaleX = Dimension.getWidth() / baseWdith=> 简化代码

流程是,我们制作一个带有特定基本屏幕的 UI,让它看起来像我们想要的样子,然后我们稍后在新屏幕中缩放组件。

我的问题是 dp 单位不应该做同样的事情!?为什么 RN 不自己处理自动缩放?如果有名为 dp 的东西来管理屏幕尺寸比例,那么他们为什么要手动缩放?

【问题讨论】:

  • 因为不幸的是 dp 没有这样做。查看该项目自述文件中的图片:github.com/intuit/sdp 我不知道 react native 是做什么的,但根据您发布的内容,我认为它会在运行时计算屏幕的比例并重新计算视图的宽度和高度.不完全确定 react native 但 android 的 dp 是一个谎言。使用 dp 处理多个屏幕的唯一方法是在 res/ 中为不同大小创建不同的 dimens.xml,但 dp“听起来”就像 android 框架在后台处理的那样,它不会

标签: android react-native user-interface


【解决方案1】:

在 RN 中,我们不使用 dp 作为缩放单位。我们必须做自己的逻辑来管理不同的屏幕尺寸。我用百分比缩放创建了自己的缩放机制。 下面是计算不同屏幕大小的常用函数

 import { Dimensions, PixelRatio } from 'react-native';
const screenWidth = Dimensions.get('window').width;
const screenHeight = Dimensions.get('window').height;
const widthDP = widthPercent => {
    // Convert string input to decimal number
    const elemWidth = parseFloat(widthPercent);
    return PixelRatio.roundToNearestPixel(screenWidth * elemWidth / 100);
};
const heightDP = heightPercent => {
    // Convert string input to decimal number
    const elemHeight = parseFloat(heightPercent);
    return PixelRatio.roundToNearestPixel(screenHeight * elemHeight / 100);
};

您可以在任何屏幕中使用以下这些功能

  const style = StyleSheet.create({
    container: {
        padding: 2,
        width: widthDP('69.60%'),
        height: heightDP('100%),
    },
    textStyle: {
        textAlign: "center",
        fontSize: widthDP('3.70%'),
        color: '#000000',
    },
})

您可以使用下面的示例表进行 dp 到百分比的转换

 HEIGHT:

5:heightDP('0.80%'),
7:heightDP('1.05%'),
8:heightDP('1.2%')
9:heightDP('1.35%'),
10: heightDP('1.5%'),
11:heightDP('1.60%'),
12:heightDP('1.8%'),
14:heightDP('2.12%'),
15:heightDP('2.25%'),
17:heightDP('2.50%'),
18:heightDP('2.65%'),
19:heightDP('2.80%'),
20: heightDP('2.95%') //
22:heightDP('3.25%'),
24:heightDP('3.5%'),,
25:heightDP('3.66%'),
29:heightDP('4.27%'),
30:heightDP('4.4%'),
31:heightDP('4.58%')
33:heightDP('4.25%'),
35:heightDP('5.15%')
36: heightDP('5.30%')//
39:heightDP('5.75%'),
40:heightDP('5.9%'),
42:heightDP('6.2%'),
48:heightDP('7%'),
50:heightDP('7.35%'),
52:heightDP('7.62%')//
55:heightDP('8.10%'),
64:heightDP('9.40%'),
65:heightDP('9.52%'),
66:heightDP('9.66%'),
67:heightDP('9.80%')
71.6:heightDP('10.50%')
72:heightDP('10.55%')//
76:heightDP('11.15%'),
83:heightDP('12.20%')//
90:heightDP('13.19%'),
91:heightDP('13.35%'),
105:heightDP('15.36%')
109:heightDP('16.00%'),
123:heightDP('18%')
136.7:heightDP('20%')
140:heightDP('20.50%')//
174:heightDP('25.5%'),
190:heightDP('27.88%'),
194:heightDP('28.42%'),
209:heightDP('30.59%')
222:heightDP('32.50%')
224:heightDP('32.80%')//
230:heightDP('33.70%'),
246:heightDP('36%'),
265:heightDP('38.8%'),

328heightDP('48%')
334:heightDP('49%')//
341:heightDP('50%')//
344:heightDP('50.40%')
348:heightDP('51%')
355:heightDP('52%')
409:heightDP('60%'),
423:heightDP('62%')
434:heightDP('63.55%'),


WIDTH:


5:widthDP('1.25%'),
7:widthDP('1.80%')v
8:widthDP('1.99%'),
9:widthDP('2.2%'),
10:widthDP('2.5%'),
12:widthDP('3.0%'),
13:widthDP('3.2%'),
14:widthDP('3.5%'),
15:widthDP('3.70%'), 
16:widthDP('3.90%')//
17:widthDP('4.20%'),
18:widthDP('4%'),
18:widthDP('4.4%'),
20:widthDP('4.83%'),
22:widthDP('5.4%'),
24:widthDP('5.8%'),
26:widthDP('6.40%'),
29:widthDP('7.1%'),
30:widthDP('7.30%'),    
39:widthDP('9.50%'),
40:widthDP('9.80%')
44:widthDP('10.70%'),
45:widthDP('11.00%'),
48:widthDP('11.70%')//
60:widthDP('14.50%')
64:widthDP('15.65%'),
68.5:widthDP('16.7%')
70:widthDP('17.2%')

72:widthDP('17.55%')

75:widthDP('18.30%')
76:widthDP('18.65%')
80: widthDP('22%')
273:widthDP('66.40%'),
286:widthDP('69.60%'),
315:widthDP('76.70%'),
335:widthDP('81.5%'),

WidthDP(1)= 4.190476190476191

HeightDP(1)= 6.857142857142857

【讨论】:

  • 我不确定为什么您使用roundToNearestPixel 的答案未标记为正确答案。该解决方案是唯一对我有用的解决方案,至少在 Android 上是这样。
【解决方案2】:

UPD

感谢您的回答。 1-您可以使用此样式共享一个 sn-p 代码吗 2-似乎对于 IOS 其逻辑像素和对于 android dp。检查stackoverflow.com/questions/34493372/… 3-为什么没有同时缩放宽度和高度。我的意思是真正的缩放需要根据两个方向进行缩放

  1. 完成,我已经更新了答案。
  2. 像素在样式内部使用,但您可以重新计算它,例如:

    style={{ borderWidth: 1 / PixelRatio.get() }}
    

    另外,您可以使用PixelRatio 方法编写自己的缩放函数

  3. 一切正常

    imageContainer: ViewStyle = {
        height: scaleHeight(63),
        width: scaleWidth(63),
        borderRadius: scaleWidth(63 / 2),
        backgroundColor: R.color.white,
        alignItems: 'center',
        justifyContent: 'center',
    };
    

原创

我的问题是 dp 单元不应该做同样的事情吗!?为什么 RN 不自己处理自动缩放?如果有一个名为 dp 的东西来管理屏幕尺寸比率,那么他们为什么要手动缩放?

1) 在 RN 中它只是像素 2)不能说 3)您可以使用百分比,但它不是像素完美设计的好解决方案

它在我的项目中是如何工作的

此脚本用于生产,一切正常;

对于缩放尺寸,我使用 'scaleWidth' 和 'scaleHeight'

对于缩放距离,例如状态栏和某些内容之间的距离,我使用 'scaleY'

import { Dimensions } from 'react-native';
import DeviceInfo from 'react-native-device-info';

const IPHONE6_SCREEN_WIDTH = 375;
const IPHONE6_SCREEN_HEIGHT = 667;

export const isTablet = DeviceInfo.getDeviceType() !== 'Handset';

export const scaleWidth = (width: number) => {
    if (isTablet) {
        return width;
    }
    return Dimensions.get('screen').width / IPHONE6_SCREEN_WIDTH * width;
};

export const scaleHeight = (height: number) => {
    if (isTablet) {
        return height;
    }
    return Dimensions.get('screen').width / IPHONE6_SCREEN_WIDTH * height;
};

export const scaleX = scaleWidth;

export const scaleY = (height: number) =>
Dimensions.get('screen').height / IPHONE6_SCREEN_HEIGHT * height;

export const scaleFont = scaleWidth;

例子:

textStyle: TextStyle = {
    fontFamily: R.font.montserratBold,
    fontSize: scaleFont(14),
    lineHeight: scaleHeight(18),
    letterSpacing: scaleWidth(1.75),
    color: R.color.white,
};

smallButtonStyle: ViewStyle = {
    ...this.buttonStyle,
    height: scaleHeight(36),
};

smallTextStyle: TextStyle = {
    ...this.textStyle,
    fontSize: scaleFont(12),
    lineHeight: scaleHeight(15),
    letterSpacing: 0,
    marginHorizontal: scaleWidth(10),
};

正如我之前所说,我使用 scaleY 来表示屏幕上的垂直距离。 示例:

render() {
    const { loginRequestState } = this.props;

    return (
        <HideKeyboardView>
            <KeyboardAwareScrollView
                style={styles.mainContentView()}
                contentInsetAdjustmentBehavior={'never'}
                enableOnAndroid
                contentInset={{ bottom: R.constant.botNavBarPlaceholderHeight }}
            >
                <LinkedText
                    text={R.string.signUp.title}
                    onPress={this.goToSignUp}
                    insets={{ top: scaleY(23) }}
                    alignToEnd
                />
                <Title
                    text={R.string.signIn.title}
                    insets={{ top: scaleY(36) }}
                />
                <SignInButton
                    onPress={this.handleMyElevation}
                    icon={R.image.icon.myElevationLogo}
                    insets={{ top: scaleHeight(30) }}
                    signInVariant={'myElevation'}
                />
                <SeparatorWithText
                    insets={{ top: scaleY(40) }}
                    text={R.string.global.or}
                />
                {this.renderForm()}
            </KeyboardAwareScrollView>

            <SafeAreaView style={styles.container}>
                <FlexView />
                <BotNavPlaceholder
                    toScreen={'signUp'}
                    onPress={this.goToSignUp}
                />
            </SafeAreaView>
            <TransparentLoadingView
                isVisible={loginRequestState === 'progress'}
            />
        </HideKeyboardView>
    );
}

【讨论】:

  • 感谢您的回答。 1-您可以使用它共享一个 sn-p 代码来设置样式吗 2-对于 IOS 来说它的逻辑像素和对于 android dp 来说似乎是这样。检查stackoverflow.com/questions/34493372/… 3-为什么没有同时缩放宽度和高度。我的意思是真正的缩放需要根据两个方向进行缩放
  • @no_fate 如果可以,请看一下。 stackoverflow.com/questions/61875092/…,可以的话请看一下。
猜你喜欢
  • 2015-11-18
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多