为什么我的定制按钮有时显示不正确?

时间:2019-12-30 15:17:31

标签: react-native user-interface expo

我在React-Native中使用定制的六角形按钮有一个非常特殊的问题。我使用the shapes of React-Native处的技术来制作这些按钮。我的按钮有时看起来像这样:

Hexagon button with the letter k in the middle and a black line below it.

有时黑线位于字母上方。我用来制作这些按钮的方法是中间的一个矩形,顶部和底部的一个三角形。似乎显示了一条线,其中三角形与矩形相交,但是只有一个三角形或另一个三角形且仅用于一行按钮。全屏显示如下:

full image of the app screen

有时它仅是中间行,有时它将是顶部和底部行,而中间则可以。它同时出现在Android和iOS上,并且似乎与屏幕尺寸有关。我对为什么不是每个按钮都不会出现而只弄乱一两行感到如此困惑。在某些情况下,取决于屏幕尺寸,它可能会很好。

这是我的自定义六角形按钮的代码:

import React, { useState, useEffect } from 'react';
import { View, StyleSheet, TouchableOpacity, Text, Dimensions } from 'react-native';


const HexagonButton = props => {
    //Variables for scaling Hex button font.
    let minPortraitWidth = 29.09;//Based on width of 320
    let minLandscapeWidth = 35.5;//Based on width of 568
    let maxPortraitWidth = 93.09;//Based on width of 1024
    let maxLandscapeWidth = 85.375;//Based on width of 1366
    let minFont = 14;
    let maxFont = 35;
    let maxButtonSpace = 16;
    let minButtonSpace = 11;


    let startMinWidth;
    let startMaxWidth;
    let startSpacing;

    if (Dimensions.get('window').width > Dimensions.get('window').height) {
        startSpacing = maxButtonSpace;
        startMinWidth = minLandscapeWidth;
        startMaxWidth = maxLandscapeWidth;
    }
    else {
        startSpacing = minButtonSpace;
        startMinWidth = minPortraitWidth;
        startMaxWidth = maxPortraitWidth;
    }

    const [buttonWidth, setButtonWidth] = useState(Dimensions.get('window').width / startSpacing);
    const [buttonHeight, setButtonHeight] = useState((Dimensions.get('window').width / startSpacing) * 0.60);
    const [minWidth, setMinWidth] = useState(startMinWidth);
    const [maxWidth, setMaxWidth] = useState(startMaxWidth);


    //Handle screen rotate
    useEffect(() => {
        const updateLayout = () => {
            if (Dimensions.get('window').width > Dimensions.get('window').height) {//Landscape Mode
                setMinWidth(minLandscapeWidth);
                setMaxWidth(maxLandscapeWidth);

                setButtonWidth(Dimensions.get('window').width / maxButtonSpace);//Make space for 16 hexagons so we have extra space. 13 buttons per row
                setButtonHeight((Dimensions.get('window').width / maxButtonSpace) * 0.60)// Button height is 60% of button width
            }
            else {//Portrait Mode
                setMinWidth(minPortraitWidth);
                setMaxWidth(maxPortraitWidth);

                setButtonWidth(Dimensions.get('window').width / minButtonSpace);//Make space for 11 hexagons so we have extra space. 9 buttons per row
                setButtonHeight((Dimensions.get('window').width / minButtonSpace) * 0.60)// Button height is 60% of button width
            }


        };

        Dimensions.addEventListener('change', updateLayout);

        return () => {
            Dimensions.removeEventListener('change', updateLayout);
        };
    });


    return (
        <TouchableOpacity
            style={{
                width: buttonWidth,
                height: buttonHeight
            }}
            accessibilityRole="none"
            >

            <View style={[styles.hexagonBefore, {
                top: -1 * (buttonHeight * 0.45),
                borderLeftWidth: buttonWidth * 0.5,
                borderRightWidth: buttonWidth * 0.5,
                borderBottomWidth: buttonHeight * 0.45
            }]} />

            <View style={styles.hexagonInner}>
                <Text
                    style={{
                        fontSize: Math.floor(minFont + (maxFont - minFont) * ((buttonWidth - minWidth) / (maxWidth - minWidth)))//This equation scales my font
                    }}>
                    {props.children}
                </Text>
            </View>

            <View style={[styles.hexagonAfter, {
                bottom: -1 * (buttonHeight * 0.45),
                borderLeftWidth: buttonWidth * 0.5,
                borderRightWidth: buttonWidth * 0.5,
                borderTopWidth: buttonHeight * 0.45
            }]} />
        </TouchableOpacity>
    );
};



const styles = StyleSheet.create({
    hexagonInner: {
        width: '100%',
        height: '100%',
        backgroundColor: '#ffec33',
        justifyContent: 'center',
        alignItems: 'center'
    },
    hexagonAfter: {
        position: 'absolute',
        left: 0,
        width: 0,
        height: 0,
        borderStyle: 'solid',
        borderLeftColor: 'transparent',
        borderRightColor: 'transparent',
        borderTopColor: '#ffec33'
    },
    hexagonBefore: {
        position: 'absolute',
        left: 0,
        width: 0,
        height: 0,
        borderStyle: 'solid',
        borderLeftColor: 'transparent',
        borderRightColor: 'transparent',
        borderBottomColor: '#ffec23'
    }
});



export default HexagonButton; 

这是主要布局的代码:

import React from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';

import HexButton from './HexagonButton';
import ModeButton from './ModeButton';

const PortraitLayout = props => {
    return (
        <View style={styles.screen}>
            <View style={styles.keyboardLayout}>
                <View style={styles.row}>
                    <HexButton>a</HexButton>
                    <HexButton>b</HexButton>
                    <HexButton>c</HexButton>
                    <HexButton>d</HexButton>
                    <HexButton>e</HexButton>
                    <HexButton>f</HexButton>
                    <HexButton>g</HexButton>
                    <HexButton>h</HexButton>
                    <HexButton>i</HexButton>
                </View>
                <View style={styles.row}>
                    <HexButton>j</HexButton>
                    <HexButton>k</HexButton>
                    <HexButton>l</HexButton>
                    <HexButton>m</HexButton>
                    <HexButton>n</HexButton>
                    <HexButton>o</HexButton>
                    <HexButton>p</HexButton>
                    <HexButton>q</HexButton>
                    <HexButton>r</HexButton>
                </View>
                <View style={styles.row}>
                    <HexButton>s</HexButton>
                    <HexButton>t</HexButton>
                    <HexButton>u</HexButton>
                    <HexButton>v</HexButton>
                    <HexButton>w</HexButton>
                    <HexButton>x</HexButton>
                    <HexButton>y</HexButton>
                    <HexButton>z</HexButton>
                </View>
            </View>


            <View style={styles.buttonLayout}>
                <ModeButton>
                    Phonics
                </ModeButton>
                <ModeButton>
                    Keyboard
                </ModeButton>
                <ModeButton>
                    Letter
                </ModeButton>
            </View>
        </View>
    );
};


const styles = StyleSheet.create({
    screen: {
        width: '100%',
        height: '100%',
        backgroundColor: '#1e1e19',
        justifyContent: 'center'
    },
    row: {
        justifyContent: 'space-between',
        flexDirection: 'row',
        marginVertical: '5%',
        marginHorizontal: '5%'
    },
    keyboardLayout: {
        height: '50%',
        width: '100%',
        justifyContent: 'center'
    },
    buttonLayout: {
        height: '50%',
        width: '100%',
        alignItems: 'center',
        justifyContent: 'flex-end'
    }
});


export default PortraitLayout; 

我已经为此工作了几天,这让我更加沮丧。如果有人可以帮助我弄清楚我在做什么错,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

只是

            borderBottomWidth: buttonHeight * 0.46,

在此区块

<View
        style={[
          styles.hexagonBefore,
          {
            top: -1 * (buttonHeight * 0.45),
            borderLeftWidth: buttonWidth * 0.5,
            borderRightWidth: buttonWidth * 0.5,
            borderBottomWidth: buttonHeight * 0.46,
          },
        ]}
      />

对我来说很好的工作