2

i'm creating a screen using react-native-paper. When i use a Appbar as header with three dots menu, the options appear at the wrong side of the screen. It should appear at the right side, not the left one.
My code:

import React, { useEffect,useState } from 'react'
import {
    SafeAreaView,
    StyleSheet,
    Platform
} from 'react-native'
import {connect} from 'react-redux'
...
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import {Appbar,Menu} from 'react-native-paper'
import MComponent from './subpages/component'
const Tab = createMaterialTopTabNavigator();
const TAG = 'TAG'
const MPage = ({ navigation,handleLoadData,isLoading }) => {
    useEffect(() => {
        handleLoadData()
    }, [])
    const [openMenu,setOpenMenu] = useState(false)
    return (
        <SafeAreaView style={styles.container}>
      <Menu
            style={styles.menu}
            visible={openMenu}
            onDismiss={()=>{
              setOpenMenu(false)
            }}
            
            anchor={
              <Appbar.Header
              statusBarHeight={0}
          >
          <Appbar.BackAction
            onPress={()=>{
              navigation.goBack()
            }}
          />
          <Appbar.Content
            title="App Screen"
          />
          <Appbar.Action icon="dots-vertical" onPress={()=>{
              setOpenMenu(true)}}
            />
        </Appbar.Header>
            }
          >
            <Menu.Item onPress={() => {
              setOpenMenu(false)
              handleLoadServiceOrders()
            }} title="Option 1" />
            <Menu.Item onPress={() => {}} title="Option 2" />
          </Menu>
            <Loading
                loading={isLoading}
            />
            <Tab.Navigator>
                <Tab.Screen name={OPTIONS.PAGE_A} component={MComponent} />
                <Tab.Screen name={OPTIONS.PAGE_B} component={MComponent } />
            </Tab.Navigator>
        </SafeAreaView>
    )
}

const styles = StyleSheet.create({
    container: {
        marginTop: Platform.OS === 'android' ? 30 : 0,
        justifyContent: 'center',
        flex:1
    }
})
...

Images showing what happened:
https://i.stack.imgur.com/5ST0T.jpg menu closed before clicking at three dots menu
menu opened at the wrong side


I'm using react-native with react-native-paper lib to create the Appbar. The Menu component also belongs to react-native-paper.

2 Answers2

1

You have to pass the correct anchor prop. It accepts a React.ReactNode or an Object like this type { x: number; y: number }. I posted an example for you with the anchor anchor={{ x: windowWidth, y: 100 }}. This will work. Also you don't have to combine Appbar with Menu. It will work if you seperate them.

 <Appbar.Header>
    <Appbar.BackAction onPress={_goBack} />
    <Appbar.Content title="Title" subtitle="Subtitle" />
    <Appbar.Action icon="magnify" onPress={openMenu} />
    <Appbar.Action icon="dots-vertical" onPress={openMenu} />
  </Appbar.Header>
  <Provider>
    <View>
      <Menu
        visible={visible}
        onDismiss={closeMenu}
        anchor={{ x: windowWidth, y: 100 }}>
        <Menu.Item onPress={() => { }} title="Item 1" />
        <Menu.Item onPress={() => { }} title="Item 2" />
        <Divider />
        <Menu.Item onPress={() => { }} title="Item 3" />
      </Menu>
    </View>
  </Provider>
Arbnor
  • 2,190
  • 18
  • 26
1

The menu position is set relative to its anchor. In your original example, the entire Appbar is the anchor, so the menu appears to the left side of that. Instead, you can make the anchor just be the Appbar.Action, which will make the menu appear next to the vertical dots. Here is similar example using a Menu:

  <Card.Title
        title={item.name}
        subtitle={item.description}
        style={{overflow: 'visible'}}
        left={(props) => <Avatar.Icon {...props} icon={require('../assets/icon.png')} />}
        right={(props) => 
            <Menu
                visible={menuvisible}
                onDismiss={handleMenuDismiss}
                anchor={ <IconButton {...props} icon="dots-vertical" onPress={handleMenuShow}></IconButton>}
            >
                <Menu.Item onPress={() => {alert('item1')}} title="Item 1" />
                <Menu.Item onPress={() => {}} title="Item 2" />
                <Menu.Item onPress={() => {}} title="Item 3" />
            </Menu>
        }
    />
jimbrocato
  • 11
  • 1