【发布时间】:2021-08-02 13:32:13
【问题描述】:
我已经使用这个问题React native grid like instagram 实现了一个类似 Instagram 探索页面的列表 但是对于我的 布局,它根本没有性能。还有其他方法可以实现吗?
另一个问题是在滚动时为某些行重新渲染不同的项目,我设法通过更改应该渲染项目的条件来减少它,但仍然存在问题。
我在这里上传了我的应用的视频:https://youtu.be/gP7kbwKDeNA
我将我的内容 chunck 转换为 3 个项目数组,然后将其传递给这个组件这是我的代码:
const albumIcon = require("../../assets/icons/stream.png");
const videoIcon = require("../../assets/icons/play.png");
const { width } = Dimensions.get("window");
let isLeft = false;
let url = null;
let icon = null;
function CustomGridList(props){
const onRefresh = (loadMore = false) => {
if (loadMore === true) {
loadMore();
} else {
props.refresh(props.query);
}
};
const loadMore = () => {
props.refresh(props.query, true);
};
const getItemKey = (index,item) => {
return "item".concat(index);
};
const _renderPhoto = (item, isLarge) => {
url = null;
icon = null;
if (item && item.videos.length > 0) {
url = item.videos[0].thumbnail;
icon = videoIcon;
} else if (item && item.images.length > 1) {
url = item.images[0].url;
icon = albumIcon;
} else if(item && item.images.length > 0){
url = item.images[0].url;
}else{
url = 'https://castlebba.co.uk/wp-content/uploads/2017/04/default-image-620x600.jpg'
}
return (
<TouchableOpacity style={{marginRight: 1}}>
<CachedImage
source={{uri: url}}
style={{ flex: 1}}
afterClickFunc={() => console.log('clicked')}
useTouchableOpacity
width={isLarge ? (width*(2/3)+4) : width/3}
height={isLarge ? 200: 100}
/>
<View
style={{
position: 'absolute',
top: 4,
right: 4,
}}
>
<CustomIcon boldColor={'#fff'} icon={icon} />
</View>
</TouchableOpacity>
);
};
const _renderRow = (index, item) => {
console.log(index, item );
console.log('indexable -> ', ++index%3 );
let item1 = item[0] !== null? item[0]: null;
let item2 = item[1] !== null? item[1]: null;
let item3 = item[2] !== null? item[2]: null;
if((index+1) % 3 === 0){
if (isLeft){
isLeft = false;
}else{
isLeft = true;
}
return (
<View style={{flexDirection: isLeft? 'row' : 'row-reverse', height: 200}}>
{_renderPhoto(item1, true)}
<View style={{flexDirection: 'column'}}>
<View style={{flex:1, height: 100}}>
{_renderPhoto(item2,false)}
</View>
<View style={{ flex:1, height: 100}}>
{_renderPhoto(item3,false)}
</View>
</View>
</View>
);
}else{
return (
<View style={{flexDirection: 'row', height: 100}}>
{_renderPhoto(item1, false)}
{_renderPhoto(item2, false)}
{_renderPhoto(item3, false)}
</View>
);
}
}
const { loading, content } = props;
if(loading && !content) {
return (
<View style={{ marginTop: 30, height: 100, alignItems: 'center' }}>
<ActivityIndicator
color={getThemeStyle().color_main}
size={'large'}
/>
</View>
);
}
if (content === null) {
return <View />;
}
return (
<View style={styles.flatListUserListWrapper}>
<View style={styles.albumContainer}>
<CustomFlatList
{...props}
showsVerticalScrollIndicator={false}
style={[
styles.albumContainer,
content.length > 0 ? { margin: 1 } : {},
]}
content={content}
renderItem={({ index,item }) => _renderRow(index,item)}
itemSeparator={() => <View style={{ width: '100%', height: 1 }} />}
keyExtractor={(index,item) => getItemKey(item)}
enableLoadMore={true}
loading={loading}
onRefresh={() => onRefresh()}
loadMore={()=>loadMore()}
pagePostType={"search"}
canSendPost={false}
/>
</View>
</View>
);
}
CustomGridList.propTypes = {
error: PropTypes.string,
loading: PropTypes.bool,
refresh: PropTypes.func,
navigation: PropTypes.object,
content: PropTypes.array,
query: PropTypes.string,
navigateTo: PropTypes.func, //TODO implement this one on click
};
export default CustomGridList = React.memo(CustomGridList);
【问题讨论】:
标签: react-native react-native-android react-native-ios react-native-flatlist