所以我在这里有一个稍微独特的案例,在弄清flexbox布局时遇到很多麻烦。我基本上有一个固定在顶部的“标头”(“ headerContainer”),然后是位于其下方的ScrollView,它包装了HTMLView容器(https://github.com/jsdf/react-native-htmlview)。
问题是ScrollView不会滚动到HTMLView内容的底部。我曾尝试在HTMLView中添加边距,但是我不得不滚动的额外内容似乎是可变的,因此有时我在滚动的内容和内容之间会有很大的差距。您还将看到,我在HTMLView下方有一个TouchableOpacity,而且距离ScrollView太远了。有关如何更改样式以使其正常工作的任何建议?
const visitWebsiteVersion = (url) => {
OutOfAppLinking(url)
}
const PostView = (props) => {
let postTypeName;
let postIcon;
switch (props.postType) {
case 'something1':
postTypeName = 'something1'
postIcon = <FontAwesome name={'bell'} size={20} color={gray500} style={styles.iconStyles}/>
break;
case 'something2':
postTypeName = 'Something2'
postIcon = <FontAwesome name={'newspaper-o'} size={15} color={gray500} style={styles.iconStyles}/>
break;
case 'something3':
postTypeName = 'Something3'
postIcon = <FontAwesome name={'book'} size={15} color={gray500} style={styles.iconStyles}/>
break;
case 'something4':
postTypeName = 'Something4'
postIcon = <FontAwesome name={'book'} size={15} color={gray500} style={styles.iconStyles}/>
break;
default:
postTypeName = ''
postIcon = ''
}
return(
<View style={styles.postContainer}>
<View style={styles.headerContainer}>
<View style={styles.headerTopRow}>
<View style={{flexDirection: 'row'}}>
{postIcon}
<Text style={styles.postType}>{postTypeName}</Text>
</View>
<Text style={styles.postDate}>{monthDayYearConversion(props.postDate)}</Text>
</View>
<Text style={styles.postTitle}>{props.title}</Text>
<View style={styles.headerBottomRow}>
<View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.authorName}>By {props.author.name}</Text>
</View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.subscriptionTitle}>{props.subscription}</Text>
</View>
</View>
</View>
</View>
<ScrollView
style={styles.scrollContainer}
showsVerticalScrollIndicator={false}
>
<HTMLView
value={props.content}
stylesheet={htmlContentStylesheet}
style={styles.contentContainer}
renderNode={htmlNodeRendering}
/>
<TouchableOpacity
onPress={() => visitWebsiteVersion(props.postLink)}
style={{...inContentButton}}
>
<Text style={{fontSize: 15, color: gray100}}>Read Website Version</Text>
</TouchableOpacity>
</ScrollView>
</View>
)
}
PostView.propTypes = {
postID: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
excerpt: PropTypes.string,
content: PropTypes.string.isRequired,
postDate: PropTypes.string.isRequired,
author: PropTypes.object.isRequired,
postType: PropTypes.string.isRequired,
subscription: PropTypes.string,
postLink: PropTypes.string.isRequired,
actionsToTake: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.array
]).isRequired
}
PostView.defaultProps = {
actionsToTake: false
}
const styles = StyleSheet.create({
postContainer: {
},
headerTopRow: {
flexDirection: 'row',
justifyContent: 'space-between'
},
headerBottomRow: {
flexDirection: 'row',
marginTop: 15,
backgroundColor: postHeaderGray,
marginBottom: -16,
marginRight: -15,
marginLeft: -15,
padding: 15,
borderColor: gray200,
borderTopWidth: 2
},
headerContainer: {
borderBottomWidth: 1,
borderColor: gray100,
shadowColor: '#000',
backgroundColor: gray100,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 1,
padding: 15
},
scrollContainer: {
...htmlContentScrollContainer
},
iconStyles: {
alignSelf: 'flex-start'
},
postTitle: {
...PostTitle,
fontSize: 25
},
postType: {
...MetaTitle,
marginLeft: 5
},
postDate: {
alignSelf: 'flex-end',
...MetaTitle
},
authorName: {
...MetaTitle,
flex: 1,
flexWrap: 'wrap'
},
authorImage: {
width: 75,
height: 75,
borderRadius: 35
},
subscriptionTitle: {
...MetaTitle,
flexWrap: 'wrap',
fontWeight: '700'
},
// This isn't the best solution but I think it will work for now
contentContainer: {
// marginBottom: 600
}
})
export default PostView
答案 0 :(得分:0)
好吧,我知道了!他们的关键是对ScrollView使用stickyHeaderIndices属性,然后将所有内容都考虑在内,并且我能够一直滚动到最底端。以下是有效的代码:
const visitWebsiteVersion = (url) => {
OutOfAppLinking(url)
}
const PostView = (props) => {
let postTypeName;
let postIcon;
switch (props.postType) {
case 'something1':
postTypeName = 'Something1'
postIcon = <FontAwesome name={'bell'} size={20} color={gray500} style={styles.iconStyles}/>
break;
case 'something2':
postTypeName = 'Something2'
postIcon = <FontAwesome name={'newspaper-o'} size={15} color={gray500} style={styles.iconStyles}/>
break;
case 'something3':
postTypeName = 'Something3'
postIcon = <FontAwesome name={'book'} size={15} color={gray500} style={styles.iconStyles}/>
break;
case 'something4':
postTypeName = 'Something4'
postIcon = <FontAwesome name={'book'} size={15} color={gray500} style={styles.iconStyles}/>
break;
default:
postTypeName = ''
postIcon = ''
}
const {actionsToTake, content, postDate, title, author, subscription, postLink} = props
return(
<View style={styles.postContainer}>
<ScrollView
style={styles.scrollContainer}
showsVerticalScrollIndicator={false}
stickyHeaderIndices={[0]}
>
<View style={styles.headerContainer}>
<View style={styles.headerTopRow}>
<View style={{flexDirection: 'row'}}>
{postIcon}
<Text style={styles.postType}>{postTypeName}</Text>
</View>
<Text style={styles.postDate}>{monthDayYearConversion(postDate)}</Text>
</View>
<Text style={styles.postTitle}>{title}</Text>
<View style={styles.headerBottomRow}>
<View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.authorName}>By {author.name}</Text>
</View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.subscriptionTitle}>{subscription}</Text>
</View>
</View>
</View>
</View>
<View style={{...htmlContentScrollContainer}}>
{actionsToTake ?
<ActionsToTake actions={actionsToTake}/>
:null}
<HTMLView
value={content}
stylesheet={htmlContentStylesheet}
style={styles.contentContainer}
renderNode={htmlNodeRendering}
/>
<TouchableOpacity
onPress={() => visitWebsiteVersion(postLink)}
style={{...inContentButton}}
>
<Text style={{fontSize: 15, color: gray100}}>Read Website Version</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
)
}
PostView.propTypes = {
postID: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
excerpt: PropTypes.string,
content: PropTypes.string.isRequired,
postDate: PropTypes.string.isRequired,
author: PropTypes.object.isRequired,
postType: PropTypes.string.isRequired,
subscription: PropTypes.string,
postLink: PropTypes.string.isRequired,
actionsToTake: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.array
]).isRequired
}
PostView.defaultProps = {
actionsToTake: false
}
const styles = StyleSheet.create({
postContainer: {
},
headerTopRow: {
flexDirection: 'row',
justifyContent: 'space-between'
},
headerBottomRow: {
flexDirection: 'row',
marginTop: 15,
backgroundColor: postHeaderGray,
marginBottom: -16,
marginRight: -15,
marginLeft: -15,
padding: 15,
borderColor: gray200,
borderTopWidth: 2
},
headerContainer: {
borderBottomWidth: 1,
borderColor: gray100,
shadowColor: '#000',
backgroundColor: gray100,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 1,
padding: 15,
marginBottom: 15
},
scrollContainer: {
},
iconStyles: {
alignSelf: 'flex-start'
},
postTitle: {
...PostTitle,
fontSize: 25
},
postType: {
...MetaTitle,
marginLeft: 5
},
postDate: {
alignSelf: 'flex-end',
...MetaTitle
},
authorName: {
...MetaTitle,
flex: 1,
flexWrap: 'wrap'
},
authorImage: {
width: 75,
height: 75,
borderRadius: 35
},
subscriptionTitle: {
...MetaTitle,
flexWrap: 'wrap',
fontWeight: '700'
},
// This isn't the best solution but I think it will work for now
contentContainer: {
// marginBottom: 600
}
})
export default PostView