在React Native中,如何将一个视图放在另一个视图之上,其中一部分位于视图的边界之外?


74

我正在尝试使用React Native按照以下方式进行布局。

在此处输入图片说明

如何指定B相对于A的位置?

使用iOS Interface Builder和自动约束,可以非常明确地做到这一点,并且很容易。使用React Native如何实现这一目标还不是很明显。


2
zIndex: 100在我的情况下,一个简单的“浮动视图”对我有用。
lsimonetti

正确的组合zIndex:10以及负的利润marginTop:-15应能为您带来所需的收益。位置:“绝对”可能会在更大的屏幕上使事情变得混乱,请考虑到这一点,甚至可以避免。
鲍比·阿克斯

Answers:


85

将以下内容添加到“浮动”视图中

position: 'absolute'

您可能还需要添加顶部和左侧的值以进行定位

参见以下示例:https : //rnplay.org/apps/OjzcxQ/edit


9
同样重要的是view B必须view A在层次结构中紧随其后,因为目前没有zIndex支持。
zubko

2
如何在不同的显示器尺寸和纵横比下工作?
hitmaneidos

@hitmaneidos,你可以做底:-15。但是,如果B在2个视图之上(将下面的空白想象为视图C),则这不能解决问题。在这种情况下,视图B必须紧随A和C之后,并且A和C都具有可变的高度,如果不手动计算每个视图的高度,我就无法提出解决方案……
括号

67
真该死
用户

投票无效链接,很抱歉,这就是为什么您不链接到答案。
Keith Loughnane

21

上述解决方案不适用于我。我通过创建与父级具有相同背景色的View来解决此问题,并添加了负边距使图像向上移动。

<ScrollView style={{ backgroundColor: 'blue' }}>
  <View
    style={{
      width: '95%',
      paddingLeft: '5%',
      marginTop: 80,
      height: 800,
    }}>
    <View style={{ backgroundColor: 'white' }}>

      <Thumbnail square large source={{uri: uri}} style={{ marginTop: -30 }}/>
      <Text>Some Text</Text>
    </View>
  </View>
</ScrollView>

我得到了以下结果。

在此处输入图片说明


12

您可以zIndex用于将视图放置在另一个视图之上。它的工作方式类似于CSS z-index属性-具有较大zIndex外观的组件将显示在顶部。

您可以参考:布局道具

片段:

    <ScrollView>
          <StatusBar backgroundColor="black" barStyle="light-content" />
          <Image style={styles.headerImage} source={{ uri: "http://www.artwallpaperhi.com/thumbnails/detail/20140814/cityscapes%20buildings%20hong%20kong_www.artwallpaperhi.com_18.jpg" }}>
            <View style={styles.back}>
              <TouchableOpacity>
                <Icons name="arrow-back" size={25} color="#ffffff" />
              </TouchableOpacity>
            </View>
            <Image style={styles.subHeaderImage} borderRadius={55} source={{ uri: "https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Albert_Einstein_1947.jpg/220px-Albert_Einstein_1947.jpg" }} />
          </Image>

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: "white"
    },
    headerImage: {
        height: height(150),
        width: deviceWidth
    },
    subHeaderImage: {
        height: 110,
        width: 110,
        marginTop: height(35),
        marginLeft: width(25),
        borderColor: "white",
        borderWidth: 2,
        zIndex: 5
    },

9

您可以使用此OverlayContainer。诀窍是使用absolute100%大小。检查以下示例:

// @flow

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

type Props = {
  behind: React.Component,
  front: React.Component,
  under: React.Component
}

// Show something on top of other
export default class OverlayContainer extends React.Component<Props> {
  render() {
    const { behind, front, under } = this.props

    return (
      <View style={styles.container}>
        <View style={styles.center}>
          <View style={styles.behind}>
            {behind}
          </View>
          {front}
        </View>
        {under}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    height: '100%',
    justifyContent: 'center',
  },
  center: {
    width: '100%',
    height: '100%',
    alignItems: 'center',
    justifyContent: 'center',
  },
  behind: {
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    left: 0,
    top: 0,
    width: '100%',
    height: '100%'
  }
})

2
你确定你的意思height: 100,,而不是height: '100%',
ssc

我什至不记得去年在这里发表评论,但似乎(至少)第二次此答案对我很有帮助-再次非常感谢!:-)就我而言,front视图是一个Animated.View; 我必须删除alignItems: 'center' from styles.center`,否则它不会显示。
ssc

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


export default class App extends Component {
  render() {
    return (
       <View>// you need to wrap the two Views an another View
          <View style={styles.box1}></View>
          <View style={styles.box2}></View>
       </View> 
    );
  }
}

const styles = StyleSheet.create({
  box1:{
    height:100,
    width:100,
    backgroundColor:'red'
  },
  box2:{
    height:100,
    width:100,
    backgroundColor:'green',
    position: 'absolute',
    top:10,
    left:30

  },
});

3

您可以使用react-native-view-overflow插件将视图放置在另一个视图之上。它的工作方式类似于CSS z-index属性。

import ViewOverflow from 'react-native-view-overflow';

<ViewOverflow />
    <View style={[styles2.cardBox, { marginTop: 50 }]}>
    <View style={[styles2.cardItem]} >
      <Text style={styles2.cardHeader}>userList</Text>
    </View>
      <View style={[styles2.cardContent]}>
        <Text style={styles2.text}>overflow: "visible"</Text>
      </View>
      <View style={[styles2.cardItemFooter]} >
        <Text style={styles2.cardTextFooter}>...</Text>
      </View>
    </View>
  </ViewOverflow>

const styles2 = StyleSheet.create({
  cardBox: {
    borderLeftWidth: 0,
    borderTopWidth: 0,
    backgroundColor: "transparent",
    borderWidth: 1,
    borderColor: "#d0d0d0",
    width: '94%',
    alignSelf: 'center',
    height: 200,
    position: "relative",
    borderRadius: 15,
    overflow: "visible" // doesn't do anything
  },
  cardContent: {
    textAlign: "right",
    backgroundColor: "transparent",
    marginTop: 15,
    alignSelf: 'flex-end',
    padding: 5,
  },
  cardHeader: {
    color: '#fff',
    fontFamily: 'Vazir',
    fontSize: 12
  },
  cardItem: {
    backgroundColor: "#3c4252",
    borderRadius: 3,
    position: "absolute",
    top: -10,
    right: -5,
    width: 50,
    height: 20,
    paddingRight: 5,
  },
})

3
感谢您对StackOverflow的贡献。为了获得更好的答案,请正确设置代码部分的格式,并为使用的必要方法添加说明或链接至文档。您还可以考虑放置可通过jsFiddle执行的代码段。
Sudheesh Singanamalla 18/09/11

2

实现此目的的最简单方法是负余量。

const deviceWidth = RN.Dimensions.get('window').width

a: {
  alignItems: 'center',
  backgroundColor: 'blue',
  width: deviceWidth,
},
b: {
  marginTop: -16,
  marginStart: 20,
},

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.