question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Appbar title won't show equally centered when using more than one Appbar.Actions

See original GitHub issue

Current behaviour

The title in the Appbar won’t show equally centered when using more than one Appbar.Actions beside of it.

Expected behaviour

The title in the Appbar should be exactly centered within the viewport and not only within the space between the left and right elements of the Appbar

Code sample

<Appbar.Header>
  <Appbar.BackAction />
  <Appbar.Content
    titleStyle={{ alignSelf: 'center' }} // won't work and neither alignSelf will work
    title='Centered Title' />
  <Appbar.Action icon='magnify' />
  <Appbar.Action icon='dots-vertical' />
</Appbar.Header>

Screenshot

image

What have you tried

  • textStyle= {{ textAlign: ‘center’ }}
  • textStyle= {{ alignSelf: ‘center’ }}
  • wrapping the right 2 Actions into a flexbox

Your Environment

software version
ios or android iPhone 11 simulator
react-native 0.63.2
react-native-paper 4.1.0
node 12.18.1
npm 6.14.8
react-native-vector-icons 7.1.0

This is my original code for my generic header component. It will be fed with params with help of an context component which will be updated when loading a screen.

import {Appbar, useTheme, Menu} from 'react-native-paper';

import {TouchableOpacity, Route, StyleSheet} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import {
  Scene,
  StackNavigationProp,
} from '@react-navigation/stack/lib/typescript/src/types';
import {ParamListBase} from '@react-navigation/native';
import {DrawerNavigationProp} from '@react-navigation/drawer';
import {useAppContext} from '../store/contexts/AppContext';
import {HeaderAction} from '../store/reducers/AppReducer';

export type HeaderProps = {
  scene: Scene<Route>;
  previous?:
    | Scene<
        Readonly<{
          key: string;
          name: string;
          params?: object | undefined;
        }>
      >
    | undefined;
  stackNavigation?: StackNavigationProp<ParamListBase>;
  drawerNavigation?: DrawerNavigationProp<{}>;
};

interface menuState {
  key: string;
  isOpened: boolean;
}

export const Header = ({
  scene,
  previous,
  stackNavigation,
  drawerNavigation,
}: HeaderProps) => {
  const theme = useTheme();
  const {options} = scene.descriptor;
  const title =
    options.headerTitle !== undefined
      ? options.headerTitle
      : options.title !== undefined
      ? options.title
      : scene.route.name;

  const {appState} = useAppContext();
  const [menuState, setMenuState] = useState<{[key: string]: boolean}>({});

  const renderHeaderActionMenu = (action: HeaderAction) => {
    return (
      <Menu
        onDismiss={() => setMenuState({...menuState, [action.key]: false})}
        visible={menuState[action.key]}
        anchor={
          <Appbar.Action
            key={action.key}
            disabled={action.disabled}
            color={action.color}
            icon={action.icon}
            onPress={() => setMenuState({...menuState, [action.key]: true})}
          />
        }>
        {action.menuItems?.map((menuItem) => (
          <Menu.Item
            icon={menuItem.icon}
            title={menuItem.text}
            onPress={menuItem.onPress}
          />
        ))}
      </Menu>
    );
  };

  const renderHeaderActions = () => {
    return appState.headerActions.map((action) => {
      if (Array.isArray(action.menuItems) && action.menuItems.length > 0) {
        return renderHeaderActionMenu(action);
      } else {
        return (
          <Appbar.Action
            key={action.key}
            icon={action.icon}
            onPress={action.onPress}
          />
        );
      }
    });
  };

  return (
    <Appbar.Header
      theme={{colors: {primary: theme.colors.surface}}}
      style={{display: 'flex'}}>
      {previous ? (
        <Appbar.BackAction
          onPress={() => {
            stackNavigation?.pop();
          }}
          color={theme.colors.primary}
        />
      ) : (
        <TouchableOpacity
          onPress={() => {
            drawerNavigation?.openDrawer();
          }}
          style={styles.menuIcon}>
          <Icon name="menu" size={30} />
        </TouchableOpacity>
      )}
      <Appbar.Content
        title={title}
        titleStyle={{
          textAlign: 'center', // TODO: Check how the title will stay centered with more than 1 action icon
        }}
      />
      {renderHeaderActions()}
    </Appbar.Header>
  );
};

const styles = StyleSheet.create({
  menuIcon: {
    marginLeft: 10,
  },
});

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
RichardLindhoutcommented, Nov 20, 2020

Maybe it’s better to align text on the left side here (based on images of other apps with multiple action buttons)

If you really want this (https://snack.expo.io/MiKSwH!2A) here is the code to do it: Schermafbeelding 2020-11-20 om 22 27 03

      <Appbar.Header>
        <Appbar.BackAction onPress={() => null} />
        <View
          style={[
            StyleSheet.absoluteFill,
            { alignItems: "center", justifyContent: "center" },
          ]}
          pointerEvents="box-none"
        >
          <Appbar.Content
            title="Title"
            subtitle="Subtitle"
            style={{
              alignItems: "center",
              justifyContent: "center",
            }}
          />
        </View>
        <View style={{ flex: 1 }} />
        <Appbar.Action icon="magnify" onPress={() => null} />
        <Appbar.Action icon="dots-vertical" onPress={() => null} />
      </Appbar.Header>
1reaction
ajenkuhnabatcommented, Sep 15, 2020

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

  • npm (found: 6.14.5, latest: 6.14.8)
  • react-native-vector-icons (found: 7.0.0, latest: 7.1.0)

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

verified … error still exists

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to center the title of an appbar - Stack Overflow
You can center the title of an appBar by using centerTitle parameter. centerTitle is Boolean Datatype, and default value ...
Read more >
Layouts in Flutter - Flutter documentation
1. Select a layout widget; 2. Create a visible widget; 3. ... Scaffold( appBar: AppBar( title: const Text('Flutter layout demo'), ), body: const...
Read more >
Build a Responsive UI with ConstraintLayout
To define a view's position in ConstraintLayout , you must add at least one horizontal and one vertical constraint for the view. Each...
Read more >
Playing with AppBar in Flutter - Medium
In Appbar we create different toolbar widgets like menu button, actions, icon buttons and many more. So, In this article we'll covered some...
Read more >
AppBar - FlutterFlow Docs
To make the page title appear in the center: Select the AppBar from the widget tree or from the canvas area. Move to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found