From 009a9c5e034dc0cc66f22246a4017c88ed63c2f0 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 30 May 2021 14:49:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BF=9B=E5=85=A5=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E8=AF=A6=E6=83=85=E9=A1=B5=E3=80=81=E6=AD=8C=E5=8D=95?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E7=9A=84=E5=8A=A8=E7=94=BB=E6=95=88?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/navigation/navigation.js | 129 ++++++++++++++---- src/screens/Home/SongList/List.js | 2 +- src/screens/Home/SongList/ListItem.js | 4 +- .../PlayerPortrait/components/Pic.js | 18 +-- src/screens/PlayDetail/Portrait/Player/Pic.js | 12 +- .../Portrait/Player/Player/index.js | 2 +- .../PlayDetail/Portrait/Player/index.js | 2 +- .../PlayDetail/Portrait/components/Header.js | 2 +- src/screens/SonglistDetail/Header.js | 16 +-- .../PlayerPortrait/components/Pic.js | 19 +-- 11 files changed, 133 insertions(+), 74 deletions(-) diff --git a/publish/changeLog.md b/publish/changeLog.md index 46fb301..718b94a 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -7,6 +7,7 @@ - 优化应用布局对手机系统字体大小的适配 - 调整歌单详情页,现在在歌单详情页按手机上的返回键将会返回歌单列表,而不是直接退出APP +- 优化进入播放详情页、歌单详情页的动画效果 ### 修复 diff --git a/src/navigation/navigation.js b/src/navigation/navigation.js index bff326d..84f51ee 100644 --- a/src/navigation/navigation.js +++ b/src/navigation/navigation.js @@ -68,7 +68,7 @@ export function pushHomeScreen() { }, }) } -export function pushPlayDetailScreen(componentId) { +export function pushPlayDetailScreen(componentId, id) { /* Navigation.setDefaultOptions({ topBar: { @@ -119,13 +119,44 @@ export function pushPlayDetailScreen(componentId) { }, animations: { push: { - content: { - translationX: { - from: Dimensions.get('window').width, - to: 0, - duration: 300, + sharedElementTransitions: [ + { + fromId: `pic${id}`, + toId: `pic${id}Dest`, + interpolation: { type: 'spring' }, }, - }, + ], + elementTransitions: [ + { + id: 'header', + alpha: { + from: 0, // We don't declare 'to' value as that is the element's current alpha value, here we're essentially animating from 0 to 1 + duration: 300, + }, + translationY: { + from: -16, // Animate translationY from 16dp to 0dp + duration: 300, + }, + }, + { + id: 'player', + alpha: { + from: 0, // We don't declare 'to' value as that is the element's current alpha value, here we're essentially animating from 0 to 1 + duration: 300, + }, + translationY: { + from: 16, // Animate translationY from 16dp to 0dp + duration: 300, + }, + }, + ], + // content: { + // translationX: { + // from: Dimensions.get('window').width, + // to: 0, + // duration: 300, + // }, + // }, }, pop: { content: { @@ -142,7 +173,7 @@ export function pushPlayDetailScreen(componentId) { }) }) } -export function pushSonglistDetailScreen(componentId) { +export function pushSonglistDetailScreen(componentId, id) { InteractionManager.runAfterInteractions(() => { Navigation.push(componentId, { component: { @@ -161,32 +192,72 @@ export function pushSonglistDetailScreen(componentId) { }, animations: { push: { - content: { - scaleX: { - from: 1.2, - to: 1, - duration: 200, + sharedElementTransitions: [ + { + fromId: `pic${id}`, + toId: `pic${id}Dest`, + interpolation: { type: 'spring' }, }, - scaleY: { - from: 1.2, - to: 1, - duration: 200, + ], + elementTransitions: [ + { + id: 'title', + alpha: { + from: 0, // We don't declare 'to' value as that is the element's current alpha value, here we're essentially animating from 0 to 1 + duration: 300, + }, + translationX: { + from: 16, // Animate translationX from 16dp to 0dp + duration: 300, + }, }, - alpha: { - from: 0, - to: 1, - duration: 200, - }, - }, + ], + // content: { + // scaleX: { + // from: 1.2, + // to: 1, + // duration: 200, + // }, + // scaleY: { + // from: 1.2, + // to: 1, + // duration: 200, + // }, + // alpha: { + // from: 0, + // to: 1, + // duration: 200, + // }, + // }, }, pop: { - content: { - alpha: { - from: 1, - to: 0, - duration: 200, + sharedElementTransitions: [ + { + fromId: `pic${id}Dest`, + toId: `pic${id}`, + interpolation: { type: 'spring' }, }, - }, + ], + elementTransitions: [ + { + id: 'title', + alpha: { + to: 0, // We don't declare 'to' value as that is the element's current alpha value, here we're essentially animating from 0 to 1 + duration: 300, + }, + translationX: { + to: 16, // Animate translationX from 16dp to 0dp + duration: 300, + }, + }, + ], + // content: { + // alpha: { + // from: 1, + // to: 0, + // duration: 200, + // }, + // }, }, }, }, diff --git a/src/screens/Home/SongList/List.js b/src/screens/Home/SongList/List.js index c975b9a..f12ead9 100644 --- a/src/screens/Home/SongList/List.js +++ b/src/screens/Home/SongList/List.js @@ -63,7 +63,7 @@ export default ({ width }) => { const handleListPress = useCallback((item, index) => { // console.log(item) setSelectListInfo(item) - navigations.pushSonglistDetailScreen(componentIds.home) + navigations.pushSonglistDetailScreen(componentIds.home, item.id) }, [componentIds.home, setSelectListInfo]) const itemWidth = useMemo(() => Math.max(parseInt(width * 0.125), 110), [width]) diff --git a/src/screens/Home/SongList/ListItem.js b/src/screens/Home/SongList/ListItem.js index f1d8ea1..a46adb7 100644 --- a/src/screens/Home/SongList/ListItem.js +++ b/src/screens/Home/SongList/ListItem.js @@ -12,11 +12,11 @@ export default memo(({ data: { index, item }, width, onPress = () => {} }) => { - + - {item.name} + {item.name} {/* {JSON.stringify(item)} */} diff --git a/src/screens/Home/components/PlayerPortrait/components/Pic.js b/src/screens/Home/components/PlayerPortrait/components/Pic.js index f290f56..f2e70b6 100644 --- a/src/screens/Home/components/PlayerPortrait/components/Pic.js +++ b/src/screens/Home/components/PlayerPortrait/components/Pic.js @@ -9,19 +9,21 @@ import { navigations } from '@/navigation' export default () => { const playMusicInfo = useGetter('player', 'playMusicInfo') const theme = useGetter('common', 'theme') - const [imgUrl, setImgUrl] = useState(null) const setNavActiveIndex = useDispatch('common', 'setNavActiveIndex') const setPrevSelectListId = useDispatch('common', 'setPrevSelectListId') const setJumpPosition = useDispatch('list', 'setJumpPosition') // const { t } = useTranslation() const componentIds = useGetter('common', 'componentIds') + const musicInfo = useMemo(() => { + return (playMusicInfo && playMusicInfo.musicInfo) || {} + }, [playMusicInfo]) const handlePress = useCallback(() => { // console.log('') // console.log(playMusicInfo) if (!playMusicInfo) return - navigations.pushPlayDetailScreen(componentIds.home) + navigations.pushPlayDetailScreen(componentIds.home, musicInfo.songmid) // toast(t('play_detail_todo_tip'), 'long') - }, [componentIds.home, playMusicInfo]) + }, [componentIds.home, musicInfo, playMusicInfo]) const handleLongPress = useCallback(() => { if (!playMusicInfo || playMusicInfo.listId == LIST_ID_PLAY_TEMP || playMusicInfo.listId == LIST_ID_PLAY_LATER) return @@ -32,23 +34,17 @@ export default () => { }) }, [playMusicInfo, setJumpPosition, setNavActiveIndex, setPrevSelectListId]) - useEffect(() => { - const url = playMusicInfo && playMusicInfo.musicInfo ? playMusicInfo.musicInfo.img : null - if (imgUrl == url) return - setImgUrl(url) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [playMusicInfo]) const component = useMemo(() => ( - - ), [handleLongPress, handlePress, imgUrl, theme]) + ), [handleLongPress, handlePress, musicInfo, theme]) return component } diff --git a/src/screens/PlayDetail/Portrait/Player/Pic.js b/src/screens/PlayDetail/Portrait/Player/Pic.js index e7222eb..48f5bf4 100644 --- a/src/screens/PlayDetail/Portrait/Player/Pic.js +++ b/src/screens/PlayDetail/Portrait/Player/Pic.js @@ -5,23 +5,19 @@ import { useLayout } from '@/utils/hooks' export default memo(() => { const playMusicInfo = useGetter('player', 'playMusicInfo') - const [imgUrl, setImgUrl] = useState(null) const theme = useGetter('common', 'theme') const { onLayout, ...layout } = useLayout() - useEffect(() => { - const url = playMusicInfo ? playMusicInfo.musicInfo.img : null - if (imgUrl == url) return - setImgUrl(url) - // eslint-disable-next-line react-hooks/exhaustive-deps + const musicInfo = useMemo(() => { + return (playMusicInfo && playMusicInfo.musicInfo) || {} }, [playMusicInfo]) - const imgWidth = useMemo(() => layout.width * 0.8, [layout.width]) + const imgWidth = Math.max(layout.width * 0.8, 100) return ( - { return ( - + <MoreBtn /> </View> diff --git a/src/screens/PlayDetail/Portrait/Player/index.js b/src/screens/PlayDetail/Portrait/Player/index.js index 783b785..c47962c 100644 --- a/src/screens/PlayDetail/Portrait/Player/index.js +++ b/src/screens/PlayDetail/Portrait/Player/index.js @@ -59,7 +59,7 @@ export default memo(() => { <View style={{ ...styles.pageIndicatorItem, backgroundColor: pageIndex == 0 ? theme.secondary20 : theme.normal60 }}></View> <View style={{ ...styles.pageIndicatorItem, backgroundColor: pageIndex == 1 ? theme.secondary20 : theme.normal60 }}></View> </View> - <View style={styles.player}> + <View style={styles.player} nativeID="player"> <Player /> </View> </View> diff --git a/src/screens/PlayDetail/Portrait/components/Header.js b/src/screens/PlayDetail/Portrait/components/Header.js index b5433f6..518464b 100644 --- a/src/screens/PlayDetail/Portrait/components/Header.js +++ b/src/screens/PlayDetail/Portrait/components/Header.js @@ -17,7 +17,7 @@ export default memo(() => { } return ( - <View style={{ ...styles.header, backgroundColor: theme.primary }}> + <View style={{ ...styles.header, backgroundColor: theme.primary }} nativeID="header"> <StatusBar backgroundColor="rgba(0,0,0,0)" barStyle="dark-content" translucent={true} /> <View style={{ ...styles.container }}> <TouchableOpacity onPress={back} style={{ ...styles.button }}> diff --git a/src/screens/SonglistDetail/Header.js b/src/screens/SonglistDetail/Header.js index 233cde4..b78cee3 100644 --- a/src/screens/SonglistDetail/Header.js +++ b/src/screens/SonglistDetail/Header.js @@ -1,5 +1,5 @@ -import React, { memo } from 'react' -import { View, Text, StyleSheet, ImageBackground } from 'react-native' +import React, { memo, useMemo } from 'react' +import { View, Text, StyleSheet, Image } from 'react-native' import { AppColors, BorderWidths } from '@/theme' import { useGetter } from '@/store' import ButtonBar from './ActionBar' @@ -13,16 +13,16 @@ const Header = memo(() => { <View style={{ ...styles.container, borderBottomColor: AppColors.borderColor }}> <View style={{ flexDirection: 'row', flexGrow: 0, flexShrink: 0, padding: 10 }}> <View style={{ ...styles.listItemImg, backgroundColor: AppColors.primary }}> - <ImageBackground source={{ uri: selectListInfo.img || listDetailDataInfo.img || null }} borderRadius={4} style={{ flex: 1, resizeMode: 'cover', justifyContent: 'flex-end' }}> - { + <Image nativeID={`pic${selectListInfo.id}Dest`} source={{ uri: selectListInfo.img || listDetailDataInfo.img || null }} borderRadius={4} style={{ flex: 1, resizeMode: 'cover', justifyContent: 'flex-end' }}> + {/* { playCount ? <Text style={{ fontSize: 12, paddingLeft: 3, paddingRight: 3, backgroundColor: 'rgba(0, 0, 0, 0.5)', color: AppColors.primary, borderBottomLeftRadius: 4, borderBottomRightRadius: 4 }} numberOfLines={ 1 }>{playCount}</Text> : null - } - </ImageBackground> + } */} + </Image> </View> - <View style={{ flexDirection: 'column', flexGrow: 1, flexShrink: 1, paddingLeft: 5 }}> - <Text style={{ fontSize: 13, color: AppColors.normal }} numberOfLines={ 1 }>{selectListInfo.name || listDetailDataInfo.name}</Text> + <View style={{ flexDirection: 'column', flexGrow: 1, flexShrink: 1, paddingLeft: 5 }} nativeID="title"> + <Text style={{ fontSize: 13, color: AppColors.normal }} numberOfLines={ 1 }>{selectListInfo.name}</Text> <View style={{ flexGrow: 0, flexShrink: 1 }}> <Text style={{ fontSize: 10, color: AppColors.normal40 }} numberOfLines={ 4 }>{selectListInfo.desc || listDetailDataInfo.desc}</Text> </View> diff --git a/src/screens/SonglistDetail/PlayerPortrait/components/Pic.js b/src/screens/SonglistDetail/PlayerPortrait/components/Pic.js index f290f56..a33b8ca 100644 --- a/src/screens/SonglistDetail/PlayerPortrait/components/Pic.js +++ b/src/screens/SonglistDetail/PlayerPortrait/components/Pic.js @@ -9,19 +9,21 @@ import { navigations } from '@/navigation' export default () => { const playMusicInfo = useGetter('player', 'playMusicInfo') const theme = useGetter('common', 'theme') - const [imgUrl, setImgUrl] = useState(null) const setNavActiveIndex = useDispatch('common', 'setNavActiveIndex') const setPrevSelectListId = useDispatch('common', 'setPrevSelectListId') const setJumpPosition = useDispatch('list', 'setJumpPosition') // const { t } = useTranslation() const componentIds = useGetter('common', 'componentIds') + const musicInfo = useMemo(() => { + return (playMusicInfo && playMusicInfo.musicInfo) || {} + }, [playMusicInfo]) const handlePress = useCallback(() => { // console.log('') // console.log(playMusicInfo) if (!playMusicInfo) return - navigations.pushPlayDetailScreen(componentIds.home) + navigations.pushPlayDetailScreen(componentIds.home, musicInfo.songmid) // toast(t('play_detail_todo_tip'), 'long') - }, [componentIds.home, playMusicInfo]) + }, [componentIds.home, musicInfo, playMusicInfo]) const handleLongPress = useCallback(() => { if (!playMusicInfo || playMusicInfo.listId == LIST_ID_PLAY_TEMP || playMusicInfo.listId == LIST_ID_PLAY_LATER) return @@ -32,23 +34,16 @@ export default () => { }) }, [playMusicInfo, setJumpPosition, setNavActiveIndex, setPrevSelectListId]) - useEffect(() => { - const url = playMusicInfo && playMusicInfo.musicInfo ? playMusicInfo.musicInfo.img : null - if (imgUrl == url) return - setImgUrl(url) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [playMusicInfo]) - const component = useMemo(() => ( <TouchableOpacity onLongPress={handleLongPress} onPress={handlePress} activeOpacity={0.7} > - <Image source={{ uri: imgUrl }} progressiveRenderingEnabled={true} borderRadius={2} style={{ + <Image source={{ uri: musicInfo.img }} nativeID={`pic${musicInfo.songmid}`} progressiveRenderingEnabled={true} borderRadius={2} style={{ // ...styles.playInfoImg, backgroundColor: theme.primary, width: 48, height: 48, }} /> </TouchableOpacity> - ), [handleLongPress, handlePress, imgUrl, theme]) + ), [handleLongPress, handlePress, musicInfo, theme]) return component }