用React Native实现组件叠加

3

我试图实现以下效果(标题组件位于标题图片中间上方,正文组件在下方):

desired UI layout

但目前我所能做的最好的方式似乎是利用Modal组件进行覆盖。然而,这并不是最佳选择,因为当用户向后滑动到Feed时,模态框会有延迟退出。有什么想法可以使用视图实现这种布局吗?
这是我的代码:
var React = require('react-native');
var {
    View, 
    Image,
    StyleSheet,
    Text, 
    Modal,  
    ScrollView,
    AsyncStorage
} = React;

//additional libraries
var Parse = require('parse/react-native');
//var Reflux = require('reflux');

//dynamic component references
var Api = require('../../utils/api');

//libraries 


//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
var HTMLView = require('react-native-htmlview');
var ImageButton = require('../../common/imageButton');

module.exports = React.createClass({ 
    componentDidMount: function() {
    }, 
    componentWillMount: function() {
        Parse.User.currentAsync()
            .then((user) => { this.setState({user: user}); })
    },  
    getInitialState: function() {
        return {
            entry: null, 
        }
    },
    render: function() {
        return (
            <ScrollView contentContainerStyle={styles.container}>
                <View style={[styles.header, this.border('red')]}>
                    <Image source={{uri:'http://blameebro.com/wp-content/uploads/2015/07/kdot-alright-video.png' }} style={[styles.entryImage]}>
                        <Modal
                          animated={false}
                          transparent={true}
                          visible={true}>
                             <View style={[styles.headerTopRow, this.border('yellow'), styles.overlay]}>
                                <Text style={styles.titleText}>These 3 Black Comedians Are Finally Being Honored For The Ways They Paved & The History They Made</Text>
                            </View>
                        </Modal>
                    </Image>
                </View>
                <View style={[styles.footer, this.border('blue')]}>
                    <View style={[styles.footerTopRow, this.border('red')]}>
                        <View style={styles.group}>
                            <ImageButton
                                style={[styles.btn]}
                                resizeMode={'contain'}
                                onPress={this.onPressSite}
                                source={require('../../img/globe-details.png')} />
                            <Text style={styles.sideText}>codeblackreport.com</Text>
                        </View>
                        <View style={styles.group}>
                            <ImageButton
                                style={[styles.btn]}
                                resizeMode={'contain'}
                                onPress={this.onPressFave}
                                source={require('../../img/check-details.png')} />
                            <Text style={styles.sideText}>2.6k favorites</Text>
                        </View>
                    </View>
                    <Image 
                        style={[styles.loginBar]}
                        resizeMode={'contain'}
                        source={require('../../img/login_bar_3x.png')} />
                    <View style={[styles.content, this.border('blue')]}>
                        <HTMLView
                            style={{backgroundColor:'color'}}
                            value={'<p>A <a href="http://www.benedelman.org/publications/airbnb-guest-discrimination-2015-12-09.pdf">working paper</a> (pdf) from Harvard Business School released Wednesday found “widespread discrimination” by hosts against people with black-sounding names seeking home rentals, <a href="http://www.nytimes.com/2015/12/12/business/discrimination-by-airbnb-hosts-is-widespread-report-says.html">reports the New York Times</a>.</p>'}
                            stylesheet={styles_two} />
                    </View>
                </View>
            </ScrollView>
        );
    }, 
    border: function(color) {
        return {
          //borderColor: color, 
          //borderWidth: 4,
        } 
     },
     onPressFave: function() {

     }, 
     onPressSite: function() {

     }, 

});

var styles_two = StyleSheet.create({
    p: {
        color:'white', 
        fontSize: 12, 
        fontWeight: '200', 
        fontFamily: 'arial', 
    }
}); 

var styles = StyleSheet.create({
    container: {
        flex: 1, 
        alignItems: 'center', 
        justifyContent: 'center',
        backgroundColor: 'transparent', 
    }, 
    footer: {
        flex: 2,
        backgroundColor: '#222222',  
        height: window.height/3.5,
        width: window.width, 
        alignItems: 'center', 
    }, 
    header: {
        flex: 1, 
    }, 
    entryImage: {
        height: window.height/3,
        width: window.width, 
    }, 
    loginBar: {
        width: (window.width/1.3)/1.8, 
        height: (70/553)*((window.width/1.3)/1.8),
        marginTop: -10,
    },
    barHolder: {
        backgroundColor: "#222222", 
    }, 
    content:  {
        flex: 5,
        marginLeft: window.width/40,
        marginRight: window.width/40,
        marginTop: window.height/40, 
    },  
    headerTopRow: {
        width: window.width/1.2, 
        backgroundColor: '#1C1C1A', 
        alignItems: 'flex-end', 
        alignSelf: 'center', 
        opacity: 0.6, 
        marginTop: (window.height/3)*(4/5), 
    }, 
    footerTopRow: {
        flex: 1, 
        flexDirection: "row", 
        justifyContent: 'space-around', 
        width: window.width, 
        height: window.height/15, 
        marginTop: (window.height/10), 
    }, 
    group: {
        flexDirection: "row", 
        justifyContent: 'space-between', 
        alignItems: 'center', 
    }, 
    btn: {
        width: window.width/20,
        height: window.width/20,
    }, 
    sideText: {
        color:'white', 
        fontSize: 12, 
        fontFamily: 'arial', 
        margin: 10, 
        alignSelf: 'center', 
    }, 
    titleText: {
        fontFamily: 'Bebas Neue', 
        fontSize: 20, 
        padding: 6, 
        color: 'white', 
        letterSpacing: 1,
        textAlign: 'center'
    }, 
});

现在它的样子是这样的:

enter image description here


请展示你的代码。 - shim
很抱歉 - 我只是附加了我的代码编辑 - 尽管表面上看起来我已经做到了我想做的事情 - 但模态窗口以延迟的速度退出,用户向后滑动到反馈时留下了大约0.3秒钟的时间。 - Robert Tomas G IV
覆盖层是否像其他组件一样静态,还是像覆盖层一样具有过渡效果? - Nader Dabit
这是一个静态组件吗?如果这是一个静态组件,那么一个实用的解决方案就是使用绝对定位并使组件重叠。 - Stelios Voskos
@NaderDabit 是的,覆盖层应该是静态的,并且当用户向上滚动以查看内容时移动。 - Robert Tomas G IV
@SteliosVoskos 我对绝对定位和弹性盒子布局还比较陌生 - 你能提供一个例子吗? - Robert Tomas G IV
2个回答

1
这不就是你想要做的吗?

enter image description here

var {
  StyleSheet,
  View,
  Text,
  ScrollView,
  AppRegistry,
  Image,
} = React;

import Dimensions from 'Dimensions';
var windowWidth = Dimensions.get('window').width;
var windowHeight = Dimensions.get('window').height;

var Main = React.createClass ({

  render() {

    return (
      <View style={styles.container}>
        <ScrollView style={styles.container} >
            <Image
                style={styles.entry}
                source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
              />
            <View style={styles.title}>
                <Text style={styles.text}>These 3 Black Comedians Are Finally Being Honored For The Ways They Paved & The History They Made</Text>
            </View>
            <Text style={styles.text}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas a metus vel nibh scelerisque tempor. Sed quis condimentum sem. Fusce malesuada ipsum blandit, consectetur risus non, sodales nulla. Aenean rhoncus erat nec metus dictum vulputate. Proin diam lectus, scelerisque a porttitor ut, pellentesque at ipsum. Nunc ut odio magna. In condimentum, dolor sit amet mollis suscipit, erat quam ornare risus, nec vulputate libero augue vitae augue. Nam bibendum in ante in vestibulum. Etiam leo dolor, egestas sit amet nulla et, auctor volutpat metus. Sed vel mauris vitae tellus vestibulum ullamcorper. Aliquam hendrerit sit amet ipsum sagittis ultricies.

Proin consequat, mi in tincidunt rutrum, augue lacus vehicula magna, eget dapibus dui neque non velit. Proin semper enim est, vitae molestie metus fermentum at. Maecenas a convallis metus. Nam bibendum tempor nunc eu rhoncus. Ut rutrum est vitae leo accumsan viverra. Nullam ex justo, hendrerit in placerat at, convallis et orci. Morbi quis convallis sapien, quis tempor dui. Maecenas tristique augue quis viverra volutpat. Donec vel nisi at dolor blandit porttitor ut non urna.

Nulla facilisi. Sed vel gravida velit, elementum vehicula lacus. Praesent luctus eget neque eget vehicula. Vestibulum diam urna, sagittis at velit at, fermentum luctus arcu. Sed sapien arcu, pellentesque a lorem quis, varius porttitor mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam rhoncus sollicitudin pretium. Aliquam eleifend turpis in posuere pellentesque. Vivamus viverra maximus lacus, sit amet cursus elit lobortis gravida. Quisque mollis velit quis dictum convallis. Vivamus non lectus auctor, blandit diam eu, lobortis odio. Nulla id pulvinar nulla.

Morbi et ex sagittis, pharetra dui ut, viverra augue. In commodo, libero nec pulvinar luctus, metus justo accumsan nisi, et congue dolor est a mauris. Mauris lacinia mi porta felis commodo, id finibus neque ullamcorper. Mauris ac ex at eros aliquam rutrum. Aenean venenatis quis neque non facilisis. Ut auctor, risus in laoreet bibendum, magna leo mollis turpis, a convallis mauris lorem sed nunc. Nulla et urna blandit, maximus lacus non, egestas sem. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

Integer in justo in erat euismod volutpat. Nam eleifend auctor ornare. Sed commodo felis sed diam mattis vulputate. Nam cursus placerat nunc. Aliquam sem nunc, fringilla sagittis lorem quis, pulvinar rhoncus erat. Integer venenatis, nibh sed vulputate facilisis, mi eros aliquam neque, ac consectetur leo augue id lorem. Mauris efficitur aliquet neque sed sagittis. Donec et sapien nisl.</Text>

        </ScrollView>

      </View>
    );
  }
});

var styles = StyleSheet.create({
    container: {
        backgroundColor: "#444",
        flex: 1
    },
    text:{
        color: "white",
        margin: 16,
        fontSize: 16,
    },
    title:{
        backgroundColor: "rgba(0, 0, 0, .6)",
        marginHorizontal: 30,
        marginTop: -45,
    },
    entry: {
        height: windowHeight/3,
        width: windowWidth, 
    }


});

谢谢!您有没有想过如何在图片上复制一个低透明度的覆盖层,而不影响重叠的文本?我已经在这里解决了一段时间的问题:https://dev59.com/e1sW5IYBdhLWcg3w0Z8j - Robert Tomas G IV

0
你尝试过在标题上使用负边距吗?
<View style={[styles.header, this.border('red')]}>
    <Image source={{uri:'http://blameebro.com/wp-content/uploads/2015/07/kdot-alright-video.png' }} style={[styles.entryImage]}/>
     <View style={[styles.headerTopRow, this.border('yellow'), styles.overlay]}>
        <Text style={styles.titleText}>These 3 Black Comedians Are Finally Being Honored For The Ways They Paved & The History They Made</Text>
    </View>
</View>

然后在样式中:

headerTopRow: {
    marginTop: -50, 
}, 

是的,那只会使包含文本的视图向上移动而不是向下。 - Robert Tomas G IV
您可以将标题放置在其下方的视图中,然后使用负边距将其向上移动。 - Dan G Nelson
但是视图仍将位于下一个视图开始正文内容之下 - 两者都需要重叠图像和正文内容。 - Robert Tomas G IV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接