在这一节中,我们将为播放按钮添加点击事件,跳转到频道详情页面。
1. 在底部标签栏按钮跳转到详情页面
对于底部标签栏中的播放按钮,跳转非常简单。我们可以在 options 属性中设置一个函数,从中获取到 navigation 对象,并在 onPress 中触发跳转。
<Tab.Screen
name="Pay"
component={Play}
options={({navigation}) => ({
tabBarButton: (props: BottomTabBarButtonProps) => {
delete props.onPress;
return (
<Play
onPress={() => navigation.navigate('ProgramDetail')}
/>
);
},
})}
/>
2. 在 Play 组件中处理点击事件
在 Play 组件中,我们声明一个 onPress 函数,并传递给按钮,处理点击事件。
interface IProps extends ModelState {
onPress: () => void;
}
onPress = () => {
const { onPress, thumbnailUrl } = this.props;
if (thumbnailUrl && onPress) {
onPress();
}
};
render() {
return (
<Touchable onPress={this.onPress}>
// 其他内容
</Touchable>
);
}
3. 处理页面之外的播放按钮跳转
对于独立于页面之外的播放按钮,问题在于该按钮无法直接访问 navigation 对象。为了解决这个问题,我们可以在 navigator/index.tsx 中,给 NavigationContainer 组件添加 ref,从而获取 navigation 实例。
const navigationRef = React.createRef<NavigationContainerRef>();
function navigate(name: keyof ModalStackParamList, params?: any) {
if (navigationRef.current) {
navigationRef.current.navigate(name, params);
}
}
function back() {
if (navigationRef.current) {
navigationRef.current.goBack();
}
}
return (
<NavigationContainer ref={navigationRef}>
<ModalStackScreen />
<PlayView activeScreenName={activeScreenName} />
</NavigationContainer>
);
然后,在 PlayView 中,我们可以使用 navigate 函数来进行跳转:
import { navigate } from '@/utils/index';
onPress = () => {
navigate('ProgramDetail');
};
4. 解决跳转时的错误
跳转到详情页面时,可能会出现 id 未传递的错误。我们需要在 Detail 页面中判断 route.params 是否存在,并根据情况执行 fetchShow 或 play。
if (route.params) {
dispatch({
type: 'player/fetchShow',
payload: {
id: route.params.id,
},
});
}
同时,我们需要避免在点击多个节目时同时播放多个音频。可以通过检查跳转时传入的 id 和仓库中保存的 id 是否一致,来决定是否执行 fetchShow 或 play。
if (route.params && route.params.id !== id) {
dispatch({
type: 'player/fetchShow',
payload: {
id: route.params.id,
},
});
} else {
dispatch({
type: 'player/play',
});
}
5. 解决 iOS 播放问题
在 iOS 上,如果应用不处于活动状态,音频会停止播放。我们需要在 AppState 中监听应用状态的变化,并相应地控制音频播放。
6. 总结
在这一节中,我们实现了播放按钮跳转到频道详情页面的功能,并解决了跳转时的一些常见错误和播放控制问题。下一节,我们将继续完成“我听”模块的功能。