如何在React Native FlatList中使用TouchableOpacities导航到不同的屏幕?

huangapple go评论50阅读模式
英文:

How can I navigate to different screens using TouchableOpacities in a React Native FlatList?

问题

你想问关于在React Native中使用Flatlist的问题。如何在使用TouchableOpacity时制作Flatlist以及如何使其成为列。我希望每个TouchableOpacity都可以进入不同的屏幕。我们可以这样做吗?也许需要创建一个函数?或者其他方法?请帮我,我一点头绪都没有 :")

这是Flatlist的结果:

如何在React Native FlatList中使用TouchableOpacities导航到不同的屏幕?

这是我的HomeScreen代码,用于创建屏幕截图上的Flatlist。如你所见,我只能创建一个TouchableOpacity并转到“BossScreen”。

<FlatList 
    data={categoryList}
    key={3}
    numColumns={3}
    keyExtractor={(item) => item.id}
    contentContainerStyle={styles.flatListContainer}
    showsVerticalScrollIndicator={false}
    renderItem={({ item }) =>{
        return(
            <TouchableOpacity
                style={styles.button}
                onPress={
                    () => navigation.navigate('BossScreen',{ categoryId: item.id })
                }
            >
                <Image
                    source={{uri:item.icon}}
                    style={styles.icon}
                />
                <Text style={styles.itemName}>{item.name}</Text>
            </TouchableOpacity>
        )
    }}
/>

这是我的MainNavigator.js:

<NavigationContainer>
    <Stack.Navigator initialRouteName="MainScreen">

        <Stack.Screen
            name="MainScreen"
            component={MainScreen}
            options={{
                title: 'ArcanePedia',
                headerStyle: {
                    backgroundColor: '#0074C4',
                },
                headerTitleStyle: {
                    color: 'white',
                    fontSize: 24
                },
                headerLeft: null,
                headerTitleAlign: 'center',
            }}
        />

        <Stack.Screen
            name="MagicScreen"
            component={MagicScreen}
            options={{
                title: 'Magic',
                headerStyle: {
                    backgroundColor: '#0074C4',
                },
                headerTitleStyle: {
                    color: 'white',
                    fontSize: 24
                },
                headerLeft: null,
                headerTitleAlign: 'center',
            }}
        />

        // 其他屏幕...

        <Stack.Screen
            name="BossScreen"
            component={BossScreen}
            options={{
                title: 'Boss',
                headerStyle: {
                    backgroundColor: '#0074C4',
                },
                headerTitleStyle: {
                    color: 'white',
                    fontSize: 24
                },
                headerLeft: null,
                headerTitleAlign: 'center',
            }}
        />

    </Stack.Navigator>
</NavigationContainer>

我期望我仍然可以使用Flatlist,并且每个“item”都可以进入他们自己的屏幕。

P.S. 我希望你们能理解我的意思。对于我的英文不太好,我很抱歉 :")

英文:

I want to ask about Flatlist on React Native. How to make Flatlist if there are using TouchaleableOpacity and make a column. I want each of the TouchaleableOpacity can go to different Screen. Can we make it like that? Maybe make a function? Or something? Please i don't have a clue :")

This is the result of Flatlist

如何在React Native FlatList中使用TouchableOpacities导航到不同的屏幕?

This is my HomeScreen Code to make that flatlist on the Screenshot. As you can see, i just can make 1 TouchaleableOpacity and go to "BossScreen"

&lt;FlatList 
    data={categoryList}
    key={3}
    numColumns={3}
    keyExtractor={(item) =&gt; item.id}
    contentContainerStyle={styles.flatListContainer}
    showsVerticalScrollIndicator={false}
    renderItem={({ item }) =&gt;{
        return(
            &lt;TouchableOpacity
                style={styles.button}
                onPress={
                    () =&gt; navigation.navigate(&#39;BossScreen&#39;,{ categoryId: item.id })
                }
            &gt;
                &lt;Image
                    source={{uri:item.icon}}
                    style={styles.icon}
                /&gt;
                &lt;Text style={styles.itemName}&gt;{item.name}&lt;/Text&gt;
            &lt;/TouchableOpacity&gt;
        )
    }}
/&gt;

This is my MainNavigator.js

        &lt;NavigationContainer&gt;
            &lt;Stack.Navigator initialRouteName=&quot;MainScreen&quot;&gt;

                &lt;Stack.Screen
                    name=&quot;MainScreen&quot;
                    component={MainScreen}
                    options={{
                        title: &#39;ArcanePedia&#39;,
                        headerStyle: {
                            backgroundColor: &#39;#0074C4&#39;,
                        },
                        headerTitleStyle: {
                            color: &#39;white&#39;,
                            fontSize: 24
                        },
                        headerLeft: null,
                        headerTitleAlign: &#39;center&#39;,
                    }}
                /&gt;

                    &lt;Stack.Screen
                        name=&quot;MagicScreen&quot;
                        component={MagicScreen}
                        options={{
                            title: &#39;Magic&#39;,
                            headerStyle: {
                                backgroundColor: &#39;#0074C4&#39;,
                            },
                            headerTitleStyle: {
                                color: &#39;white&#39;,
                                fontSize: 24
                            },
                            headerLeft: null,
                            headerTitleAlign: &#39;center&#39;,
                        }}
                    /&gt;

                    &lt;Stack.Screen
                        name=&quot;FightingStyleScreen&quot;
                        component={FightingStyleScreen}
                        options={{
                            title: &#39;Fighting Style&#39;,
                            headerStyle: {
                                backgroundColor: &#39;#0074C4&#39;,
                            },
                            headerTitleStyle: {
                                color: &#39;white&#39;,
                                fontSize: 24
                            },
                            headerLeft: null,
                            headerTitleAlign: &#39;center&#39;,
                        }}
                    /&gt;

                    &lt;Stack.Screen
                        name=&quot;WeaponScreen&quot;
                        component={WeaponScreen}
                        options={{
                            title: &#39;Weapons&#39;,
                            headerStyle: {
                                backgroundColor: &#39;#0074C4&#39;,
                            },
                            headerTitleStyle: {
                                color: &#39;white&#39;,
                                fontSize: 24
                            },
                            headerLeft: null,
                            headerTitleAlign: &#39;center&#39;,
                        }}
                    /&gt;

                        &lt;Stack.Screen
                            name=&quot;StorylineScreen&quot;
                            component={StorylineScreen}
                            options={{
                                title: &#39;StoryLine&#39;,
                                headerStyle: {
                                    backgroundColor: &#39;#0074C4&#39;,
                                },
                                headerTitleStyle: {
                                    color: &#39;white&#39;,
                                    fontSize: 24
                                },
                                headerLeft: null,
                                headerTitleAlign: &#39;center&#39;,
                            }}
                        /&gt;

                        
                        &lt;Stack.Screen
                            name=&quot;StatsScreen&quot;
                            component={StatsScreen}
                            options={{
                                title: &#39;Boss&#39;,
                                headerStyle: {
                                    backgroundColor: &#39;#0074C4&#39;,
                                },
                                headerTitleStyle: {
                                    color: &#39;white&#39;,
                                    fontSize: 24
                                },
                                headerLeft: null,
                                headerTitleAlign: &#39;center&#39;,
                            }}
                        /&gt;

                        &lt;Stack.Screen
                            name=&quot;BossScreen&quot;
                            component={BossScreen}
                            options={{
                                title: &#39;Boss&#39;,
                                headerStyle: {
                                    backgroundColor: &#39;#0074C4&#39;,
                                },
                                headerTitleStyle: {
                                    color: &#39;white&#39;,
                                    fontSize: 24
                                },
                                headerLeft: null,
                                headerTitleAlign: &#39;center&#39;,
                            }}
                        /&gt;


            &lt;/Stack.Navigator&gt;
        &lt;/NavigationContainer&gt;

I expecting i can still using Flatlist and make every "item" can go through on their screen.

Ps: I hope you guys can understand want i mean. Sorry for my english is not good :")

答案1

得分: 1

是的,你可以这样做,在你的catagoryList中添加一个键值对,例如:"screen: 'MagicScreen'",然后在你的renderItem中,只需引用这个键,例如:

onPress={() => navigation.navigate(item.screen, { categoryId: item.id })}
英文:

yes you can do that, in your catagoryList have a key value pair, eg. "screen: 'MagicScreen'", ... and then in your renderItem, just reference the key, eg.

onPress={
    () =&gt; navigation.navigate(item.screen,{ categoryId: item.id })
}

答案2

得分: 0

如果我理解正确,您想根据所按下的组件导航到一个屏幕。然而,我们需要查看categoryList以便给出精确的答案,因为它基于该列表呈现FlatList

但是,如果categoryList包含屏幕名称,解决方案可能会如下所示:

const screenNames = ['MagicScreen', 'FightingStyleScreen', 'WeaponScreen', 'StorylineScreen', 'StatsScreen', 'BossScreen'];
            
<FlatList
  data={screenNames}
  renderItem={({ item, index }) => {
    const screenName = screenNames[index];
    const params = screenName === 'BossScreen' ? { categoryId: item.id } : {};                                     

    const navigateToScreen = () => navigation.navigate(screenName, params);
        
    return (
      <TouchableOpacity style={styles.button} onPress={navigateToScreen}>
        <Image source={{ uri: item.icon }} style={styles.icon} />
        <Text style={styles.itemName}>{item.name}</Text>
      </TouchableOpacity>
    );
  }}
  keyExtractor={(item, index) => index.toString()}
/>

您可以根据需要为哪个组件传递item.id,修改以下行:

const params = screenName === 'BossScreen' || 'MagicScreen' ...etc
英文:

If I understood correctly, you want to navigate to a screen based on the pressed component. However, we need to see categoryList to give precise answer, since its rendering flatlist based on that.

but if categoryList contains screenNames, solution would look somewhat like this:

const screenNames = [&#39;MagicScreen&#39;, &#39;FightingStyleScreen&#39;, &#39;WeaponScreen&#39;, &#39;StorylineScreen&#39;, &#39;StatsScreen&#39;, BossScreen];
        
    &lt;FlatList
      data={screenNames}
      renderItem={({ item, index }) =&gt; {
        const screenName = screenNames[index];
        const params = screenName === &#39;BossScreen&#39; ? { categoryId: item.id } : {};                                     

        const navigateToScreen = () =&gt; navigation.navigate(screenName, params);
    
        return (
          &lt;TouchableOpacity style={styles.button} onPress={navigateToScreen}&gt;
            &lt;Image source={{ uri: item.icon }} style={styles.icon} /&gt;
            &lt;Text style={styles.itemName}&gt;{item.name}&lt;/Text&gt;
          &lt;/TouchableOpacity&gt;
        );
      }}
      keyExtractor={(item, index) =&gt; index.toString()}
    /&gt;

u can change

> const params = screenName ==='BossScreen' || 'MagicScreen' ...etc

based on which component requires item id

答案3

得分: 0

你可以添加一个名为renderItem的单独函数,并在FlatList的renderItem中调用它,

在你的FlatList组件中进行如下更改,

每个FlatList中的TouchableOpacity将根据item.id导航到不同的屏幕。只需根据实际的屏幕组件和要求更新屏幕名称和参数。

英文:

You can add a separate function called renderItem and call that into your renderItem in the FlatList ,

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

renderItem={({ item }) =&gt; {
  let screenName;
  let screenParams = {};

  // Determine the screen name and parameters based on the item
  switch (item.id) {
    case &#39;magic&#39;:
      screenName = &#39;MagicScreen&#39;;
      break;
    case &#39;fightingStyle&#39;:
      screenName = &#39;FightingStyleScreen&#39;;
      break;
    case &#39;weapons&#39;:
      screenName = &#39;WeaponScreen&#39;;
      break;
    // Add more cases for other items if needed

    default:
      screenName = &#39;BossScreen&#39;;
      screenParams = { categoryId: item.id };
      break;
  }

  return (
    &lt;TouchableOpacity
      style={styles.button}
      onPress={() =&gt; navigation.navigate(screenName, screenParams)}
    &gt;
      &lt;Image source={{ uri: item.icon }} style={styles.icon} /&gt;
      &lt;Text style={styles.itemName}&gt;{item.name}&lt;/Text&gt;
    &lt;/TouchableOpacity&gt;
  );
}}

<!-- end snippet -->

And change your FlatList component like this ,

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

&lt;FlatList 
    data={categoryList}
    key={3}
    numColumns={3}
    keyExtractor={(item) =&gt; item.id}
    contentContainerStyle={styles.flatListContainer}
    showsVerticalScrollIndicator={false}
    renderItem={renderItem}
/&gt;

<!-- end snippet -->

Each TouchableOpacity in your FlatList will navigate to a different screen based on the item.id. Just make sure to update the screen names and parameters according to your actual screen components and requirements.

huangapple
  • 本文由 发表于 2023年5月25日 20:00:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76332030.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定