Перейти к содержанию

Несколько drawers

Иногда мы хотим иметь несколько drawer на одном экране: один слева, другой справа. Этого можно добиться с помощью вложения 2 навигаторов drawer.

Вложение 2 навигаторов drawer

Здесь мы имеем два drawer, вложенных друг в друга, один из которых расположен слева, а другой - справа:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';

function HomeScreen({ navigation }) {
    return (
        <View
            style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <Button
                onPress={() => navigation.openDrawer()}
                title="Open drawer"
            />
        </View>
    );
}

const LeftDrawer = createDrawerNavigator();

const LeftDrawerScreen = () => {
    return (
        <LeftDrawer.Navigator
            screenOptions={{ drawerPosition: 'left' }}
        >
            <LeftDrawer.Screen
                name="Home"
                component={HomeScreen}
            />
        </LeftDrawer.Navigator>
    );
};

const RightDrawer = createDrawerNavigator();

const RightDrawerScreen = () => {
    return (
        <RightDrawer.Navigator
            screenOptions={{
                drawerPosition: 'right',
                headerShown: false,
            }}
        >
            <RightDrawer.Screen
                name="HomeDrawer"
                component={LeftDrawerScreen}
            />
        </RightDrawer.Navigator>
    );
};

export default function App() {
    return (
        <NavigationContainer>
            <RightDrawerScreen />
        </NavigationContainer>
    );
}

Но есть одна проблема. Когда мы вызываем navigation.openDrawer() в нашем HomeScreen, то всегда открывается левый ящик, поскольку он является непосредственным родителем экрана.

Чтобы решить эту проблему, нам необходимо использовать navigation.getParent для обращения к правому ящику, который является родителем левого ящика. Таким образом, наш код будет выглядеть следующим образом:

1
2
3
4
5
6
<Button
    onPress={() => navigation.openDrawer()}
    title="Open left drawer" />
<Button
    onPress={() => navigation.getParent().openDrawer()}
    title="Open right drawer" />

Однако это означает, что наша кнопка должна знать о родительских навигаторах, что не является идеальным вариантом. Если наша кнопка будет вложена в другие навигаторы, то потребуется несколько вызовов getParent(). Чтобы решить эту проблему, мы можем использовать пропс id для идентификации родительского навигатора.

Для настройки содержимого ящика мы можем использовать пропс drawerContent для передачи функции, которая отображает пользовательский компонент.

Итоговый код будет выглядеть следующим образом:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';

function HomeScreen({ navigation }) {
    return (
        <View
            style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <Button
                onPress={() =>
                    navigation
                        .getParent('LeftDrawer')
                        .openDrawer()
                }
                title="Open left drawer"
            />
            <Button
                onPress={() =>
                    navigation
                        .getParent('RightDrawer')
                        .openDrawer()
                }
                title="Open right drawer"
            />
        </View>
    );
}

function RightDrawerContent() {
    return (
        <View
            style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <Text>This is the right drawer</Text>
        </View>
    );
}

const LeftDrawer = createDrawerNavigator();

function LeftDrawerScreen() {
    return (
        <LeftDrawer.Navigator
            id="LeftDrawer"
            screenOptions={{ drawerPosition: 'left' }}
        >
            <LeftDrawer.Screen
                name="Home"
                component={HomeScreen}
            />
        </LeftDrawer.Navigator>
    );
}

const RightDrawer = createDrawerNavigator();

function RightDrawerScreen() {
    return (
        <RightDrawer.Navigator
            id="RightDrawer"
            drawerContent={(props) => (
                <RightDrawerContent {...props} />
            )}
            screenOptions={{
                drawerPosition: 'right',
                headerShown: false,
            }}
        >
            <RightDrawer.Screen
                name="HomeDrawer"
                component={LeftDrawerScreen}
            />
        </RightDrawer.Navigator>
    );
}

export default function App() {
    return (
        <NavigationContainer>
            <RightDrawerScreen />
        </NavigationContainer>
    );
}

Здесь мы передаем строки "LeftDrawer" и "RightDrawer" (здесь можно использовать любую строку) в свойстве id навигаторов ящиков. Затем мы используем navigation.getParent('LeftDrawer').openDrawer() для открытия левого ящика и navigation.getParent('RightDrawer').openDrawer() для открытия правого ящика.

Резюме

  • Чтобы иметь на экране 2 ящика, можно использовать опцию drawerPosition для их расположения слева и справа.
  • Чтобы открыть нужный ящик, можно использовать navigation.getParent в сочетании с параметром id.

Ссылки

Комментарии