【问题标题】:Aligning buttons in toolbar using flex使用 flex 对齐工具栏中的按钮
【发布时间】:2018-04-16 07:15:43
【问题描述】:

我是 react native 的新手,我真的被困在对齐两个工具栏按钮两天了!我需要使用 flex 将它们放在工具栏的右侧。但是,我不能那样做。代码如下:

export default class ToolbarHorizontal extends Component {

  // component prop types
  static propTypes = {
    items: React.PropTypes.arrayOf(React.PropTypes.shape({
      active: React.PropTypes.bool,
      name: React.PropTypes.string.isRequired,
      imageSourceActive: React.PropTypes.number.isRequired,
      imageSourceInactive: React.PropTypes.number.isRequired,
      onOpen: PropTypes.func,
    })).isRequired,
    toolbarActiveItem: React.PropTypes.string.isRequired,
    forcedPath: React.PropTypes.bool,
    forcedPathImageSource: React.PropTypes.number,
    tintColor: React.PropTypes.string,
  };

  constructor(props) {
    super();
    this.toolbarActiveIndex = props.items.map((el) => el.name).indexOf(props.toolbarActiveItem);
  }

  render() {
    const { items } = this.props;
    let { toolbarActiveItem } = this.props;
    let { forcedPath } = this.props;
    let { forcedPathImageSource } = this.props;
    let { tintColor } = this.props;
    tintColor = (tintColor) ? tintColor : '#000'; // default value is black
    return (
      <View style={styles.container} >
        <ScrollView
          horizontal={true}
          collapsable={true}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          style={styles.scroller}
        >
   <View style={styles.componentContainer}>
        { items.map((item, index) => {
            let active = (item.active !== undefined) ? item.active : true; // default value is true
            if (active) {
              return(
                <View key={item.id} style={styles.imageContianer}>
                  {(toolbarActiveItem == item.name) &&
                    <View style={styles.insideImageContainer}>
                      <Image
                        source={item.imageSourceSection}
                        style={styles.item}
                      />
                      <Text size={20} style={{color:tintColor, paddingRight:10}}>{!forcedPath ? item.description : null}</Text>
                    </View>
                  }
                </View>
              );
            }
          }
        )}


<View style={styles.buttomContainer}>
        { items.map((item, index) => {
            //console.log('toolbarActiveItem == item.name:', toolbarActiveItem, '==', item.name);
            let active = (item.active !== undefined) ? item.active : true; // default value is true
            if (active && (!forcedPath || item.isVisibleWhenForcedPath)) {
              return(
                <View key={item.id} >
                  {item.isTouchable && forcedPath && index > 0 &&
                    <Image
                      source={forcedPathImageSource}
                      style={styles.forcedPathImage}
                    />
                  }
                  {item.isTouchable &&
                    <TouchableOpacity onPress={() => {
                      if (!forcedPath) { // when forcedPath, buttons are never touchable
                        if (toolbarActiveItem != item.name) {
                          item.onOpen(item.name);
                          toolbarActiveItem = item.name;
                        }
                        else
                        { // already on opened page, go back if button is pressed again
                          this.props.navigation.goBack();
                        }
                      }
                    }}>
                      {forcedPath &&
                        <Image
                          source={(toolbarActiveItem == item.name) ? item.imageSourceForcedPathActive : index > this.toolbarActiveIndex ? item.imageSourceForcedPathTobevisited : item.imageSourceForcedPathVisited}
                          style={styles.item}
                        />
                      }
                      {!forcedPath &&
                        <Image
                          source={(toolbarActiveItem == item.name) ? item.imageSourceActive : item.imageSourceInactive}
                          style={styles.item}
                        />
                      }
                    </TouchableOpacity>
                  }
                </View>
              );
            }
          }
        )}
          </View>
        </View>

        </ScrollView>
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex:0.16,
    flexDirection:'row' ,

    //backgroundColor: 'transparent',
  },
  componentContainer: {
    flex:1,
    flexDirection:'row',
    alignContent:'center',
    alignItems: 'center',

  },
  imageContianer: {
    flex:1,
    flexDirection:'row',
    alignContent:'center',
    alignItems:'center',

  },
  buttomContainer: {
    flex:1,
    flexDirection:'row',
  //  backgroundColor: '#9b59b6' ,
  },
insideImageContainer: {
  flex:1,
  alignItems:'center',
  flexDirection:'row',
},

  scroller: {
    marginHorizontal: 0,
    marginVertical: 10,
  },
  item: {
    width: 60,
    height: 60,
    //marginRight: 5,
    margin: 2,
  },
  forcedPathImage: {
    flex: 1,
    width: 24,
    height: 36,
    resizeMode: 'contain',
  },
});

事实上,问题在于,flex 值的任何更改都不适用于insideImageContainerimageContianer。你能帮我解决这个问题吗? 提前致谢。

【问题讨论】:

  • 尝试在按钮左侧的元素上设置marginRight: 'auto'
  • @JonKoops:感谢您的回答,很抱歉我的问题很长。不幸的是,什么都没有发生,一切都和以前一样。
  • @JonKoops:你还有什么想法吗?
  • 也许您可以提供更简洁的组件结构版本。很难重现这一点,因为它有很多不相关的逻辑。也许可以使用纯 HTML 和 CSS 的简化版本?
  • 尝试从buttomContainer 中删除flex:1。然后componentContainer 应该增长到填满空间,buttomContainer 应该被推到右边。目前,他们每个人都试图填满一半的行。

标签: react-native flexbox react-native-flexbox


【解决方案1】:

至少这应该是你所需要的:

Toolbar = () => <View style={styles.container}>
  <View style={styles.componentContainer}>
    <Text>Icon</Text>
    <Text>Title</Text>
  </View>
  <View style={styles.buttomContainer}>
    <Text>Button1</Text>
    <Text>Button2</Text>
  </View>
</View> 

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row'
  },
  componentContainer: {
    flex: 1,
    flexDirection: 'row'
  },
  buttomContainer: {
    flexDirection: 'row'
  }
});

See this running in Expo

使用 flex 布局时要考虑的事情是:哪个组件应该占用空闲空间?给该组件一个flex: 1 属性。 (如果多个组件应该共享相同的空间,请在它们之间拆分 flex)。

在这种情况下,您不希望您的buttomContainer(错字?)比它需要的大。您希望componentContainer 尽可能地增长(弯曲)并将buttomContainer 向右推。

【讨论】:

  • 这是一个很好的答案,但是我的代码秘密地不能那样工作。谢谢,我投了赞成票。 :)
  • 感谢您的支持。如果你能重现你在世博会上遇到的问题,我很乐意再看看。
  • 这无法运行(尝试在零食中“点击播放”,或通过 expo 应用程序在手机上运行) - 您需要添加一些其他项目文件或剪切去掉一些与问题无关的东西。
  • 根据您的模板代码,它终于可以工作了。非常感谢。 :)
猜你喜欢
  • 1970-01-01
  • 2015-04-02
  • 2020-12-01
  • 1970-01-01
  • 2014-09-13
  • 2016-04-22
  • 2023-03-06
  • 1970-01-01
  • 2021-02-18
相关资源
最近更新 更多