我已经设置了一个系统,如果你点击一次按钮,你会得到一个成就(奖牌)。处理计数器是否被按下一次的逻辑在奖牌屏幕文件中。因此,我必须先打开并渲染奖牌屏幕,然后点击按钮,以获得任何效果。
我如何使它的效果发生,而不管奖牌屏幕被渲染?默认屏幕是计数器屏幕。下面是代码:
计数器
import React, { useEffect, useState, useContext } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useTheme } from '@react-navigation/native';
import { CountContext } from '../../contexts/CountContext';
import { styles } from "../../styles/Styles";
const CounterScreen = () => {
const { colors } = useTheme();
const { setCounter, counter } = useContext(CountContext);
return (
<View style={styles.container}>
<View>
<TouchableOpacity
onPress={() => setCounter(counter + 1)}
style={[styles.counterButton, {backgroundColor: colors.primary}]}>
<Text style={styles.counterText}>{counter}</Text>
</TouchableOpacity>
</View>
</View>
);
}
export default CounterScreen;
奖牌
import React, { useEffect, useState, useContext } from 'react';
import { View, Text, ScrollView } from 'react-native';
import { useTheme } from '@react-navigation/native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { CountContext } from '../../contexts/CountContext';
import { BadgeContext } from '../../contexts/BadgeContext';
import { styles } from "../../styles/Styles";
export default function MedalsScreen({ navigation }) {
const { colors } = useTheme();
const { counter } = useContext(CountContext);
const { badgeCount, setBadgeCount } = useContext(BadgeContext);
const [achieved, setAchieved] = useState(false);
const [customizeAchieved1, setCustomizeAchieved1] = useState(false);
const [countMedal1, setCountMedal1] = useState(0.25);
const [countMedal2, setCountMedal2] = useState(0.25);
const [countMedal3, setCountMedal3] = useState(0.25);
const [countMedal4, setCountMedal4] = useState(0.25);
const [countMedal5, setCountMedal5] = useState(0.25);
const [countMedal6, setCountMedal6] = useState(0.25);
const [customizeMedal1, setCustomizeMedal1] = useState(0.25);
const [customizeMedal2, setCustomizeMedal2] = useState(0.25);
const [secretMedal, setSecretMedal] = useState(0.25); //
useEffect(() => {
if (counter != 1 && counter != 100 && counter != 1000 && counter != 10000 && counter != 100000 && counter != 1000000) {
setAchieved(false);
}
if (counter == 1 && achieved == false) {
setCountMedal1(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (counter == 100 && achieved == false) {
setCountMedal2(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (counter == 1000 && achieved == false) {
setCountMedal3(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (counter == 10000 && achieved == false) {
setCountMedal4(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (counter == 100000 && achieved == false) {
setCountMedal5(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (counter == 1000000 && achieved == false) {
setCountMedal6(1);
setBadgeCount(badgeCount + 1)
setAchieved(true);
}
if (colors.primary != '#FFBF00' && customizeAchieved1 == false) {
setCustomizeMedal1(1);
setBadgeCount(badgeCount + 1)
setCustomizeAchieved1(true);
}
})
return (
<ScrollView style={{ backgroundColor: '#181818' }}>
<View style={styles.medalCardContainer}>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal1 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Getting Started</Text>
<Text style={styles.medalCardSubTitle}>Tap the button for the first time</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal2 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Tap 2</Text>
<Text style={styles.medalCardSubTitle}>Tap the button 100 times</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal3 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View style={styles.medalTextContainer}>
<Text style={styles.medalCardTitle}>Placeholder | Tap 3</Text>
<Text style={styles.medalCardSubTitle}>Tap the button 1000 times</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal4 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Tap 4</Text>
<Text style={styles.medalCardSubTitle}>Tap the button 10000 times</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal5 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Tap 5</Text>
<Text style={styles.medalCardSubTitle}>Tap the button 100000 times</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: countMedal6 }]}>
<Ionicons name='radio-button-on-outline' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Tap 6</Text>
<Text style={styles.medalCardSubTitle}>Tap the button 1000000 times</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: customizeMedal1 }]}>
<Ionicons name='color-palette' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Pablo Picasso</Text>
<Text style={styles.medalCardSubTitle}>Change the theme for the first time</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: customizeMedal2 }]}>
<Ionicons name='color-wand' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Customize 2</Text>
<Text style={styles.medalCardSubTitle}>Select an effect for the first time</Text>
</View>
</View>
<View style={[styles.medalCard, { borderColor: colors.border, opacity: secretMedal }]}>
<Ionicons name='help' size={50} color={colors.primary} />
<View>
<Text style={styles.medalCardTitle}>Placeholder | Secret 1</Text>
<Text style={styles.medalCardSubTitle}>Maybe it's in the source code?</Text>
</View>
</View>
</View>
</ScrollView>
);
}
主菜单
import React, { useState, useMemo } from 'react';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import * as NavigationBar from "expo-navigation-bar";
import { StatusBar } from 'expo-status-bar';
import CounterScreen from './screens/CounterScreen';
import CustomizeScreen from './screens/CustomizeScreen';
import SettingsScreen from './screens/SettingsScreen';
import MedalsScreen from './screens/MedalsScreen';
import { Amber, Tiger, Crimson, Blush, Amethyst, Azure, Lime } from "../styles/Themes"
import { ThemeContext } from '../contexts/ThemeContext';
import { CountContext } from '../contexts/CountContext';
import { BadgeContext } from '../contexts/BadgeContext';
// IMPORTS // IMPORTS // IMPORTS // IMPORTS // IMPORTS // IMPORTS // IMPORTS // IMPORTS // IMPORTS
const counterName = 'Counter';
const customizeName = 'Customize';
const settingsName = 'Settings';
const medalsName = "Medals";
const Tab = createBottomTabNavigator();
NavigationBar.setBackgroundColorAsync("#212121");
// DECLARATIONS // DECLARATIONS // DECLARATIONS // DECLARATIONS // DECLARATIONS // DECLARATIONS
export default function MainContainer() {
const [theme, setTheme] = useState('Amber');
const [counter, setCounter] = useState(0);
const [badgeCount, setBadgeCount] = useState(0);
const containerTheme = useMemo(() => {
switch (theme) {
case 'Amber':
return Amber;
case 'Tiger':
return Tiger;
case 'Crimson':
return Crimson;
case 'Blush':
return Blush;
case 'Amethyst':
return Amethyst;
case 'Azure':
return Azure;
case 'Lime':
return Lime;
default: console.log("Invalid theme (" + theme + ")");
}
}, [theme])
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<BadgeContext.Provider value={{ badgeCount, setBadgeCount }}>
<CountContext.Provider value={{ counter, setCounter }}>
<NavigationContainer theme={containerTheme}>
<StatusBar style="auto" />
<Tab.Navigator
initialRouteName={counterName}
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
let rn = route.name;
if (rn === counterName) {
iconName = focused ? 'radio-button-on-outline' : 'radio-button-off-outline';
} else if (rn === customizeName) {
iconName = focused ? 'color-palette' : 'color-palette-outline';
} else if (rn === medalsName) {
iconName = focused ? 'medal' : 'medal-outline';
} else if (rn === settingsName) {
iconName = focused ? 'settings' : 'settings-outline';
}
return <Ionicons name={iconName} size={size} color={color} />
},
tabBarInactiveTintColor: '#aaaaaa',
tabBarLabelStyle: { paddingBottom: 10, fontSize: 10 },
tabBarStyle: { padding: 10, height: 70, borderTopWidth: 1 },
headerStyle: { borderBottomWidth: 1 },
headerTitleAlign: 'center',
headerTitleStyle: { fontSize: 20 },
})}>
<Tab.Screen name={counterName} component={CounterScreen} />
<Tab.Screen name={customizeName} component={CustomizeScreen} />
<Tab.Screen name={medalsName} component={MedalsScreen}
options={{ tabBarBadge: badgeCount ? badgeCount : undefined }}
listeners={{
tabPress: e => {
setBadgeCount(0);
}
}}
/>
<Tab.Screen name={settingsName} component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
</CountContext.Provider>
</BadgeContext.Provider>
</ThemeContext.Provider>
);
}
1条答案
按热度按时间bmp9r5qi1#
效果绑定到呈现生命周期。在不呈现组件的情况下无法运行效果。如果要运行效果,请将函数上移一级。