Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-v5

adjusting Switch and Icon in stack header on react-navigation


I was trying to put an Switch and an Icon on header created with stack navigation from react navigation. the problem I am facing is that adjusting the switch and icon accordingly next to each other. I tried different alternatives but still I am unable to adjust them. I wanted to show on the header a text in the center; Home for instance, and show also a switch and icon on the right of the header next to each other (switch and icon). I will highly appreciate any help of how Can I do this? Here I am sharing my code trying to do it.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {useState} from 'react';
import {StatusBar, View, TouchableOpacity} from 'react-native';
import {
  NavigationContainer,
  DarkTheme as navigationDarkTheme,
  DefaultTheme as navigationDefaultTheme,
  useTheme
} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {
  DarkTheme as PaperDarkTheme,
  Provider as PaperProvider,
  DefaultTheme as PaperDefaultTheme,
  Text,
  Title,
  TouchableRipple,
  Switch,
} from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';



const customDarktheme = {
  ...PaperDarkTheme,
  ...navigationDarkTheme,
  colors: {
    ...PaperDarkTheme.colors,
    ...navigationDarkTheme.colors,
    headerColor: 'rgb(255, 255, 255)',
    bgcolor: "#404040",
    surface:"#404040",
    btnSearchColor:"#404040",
  }
}

const customDefaulttheme = {
  ...PaperDefaultTheme,
  ...navigationDefaultTheme,
  colors: {
    ...PaperDefaultTheme.colors,
    ...navigationDefaultTheme.colors,
    headerColor: "white",
    bgcolor: "#fafcff",
    btnSearchColor:"#006aff",
    surface:"white",
  }
}

const HomeS = () => {
  return <View></View>;
};

const Stack = createStackNavigator();

const App = () => {
  const {colors} = useTheme()
  const [isDarktheme, setDarkTheme] = useState(false);

  const togglemethod = () => {
    setDarkTheme(!isDarktheme);
   
  };

  return (
    <>
      <PaperProvider theme={isDarktheme?customDarktheme:customDefaulttheme}>
        <NavigationContainer theme={isDarktheme?customDarktheme:customDefaulttheme}>
          <StatusBar barStyle="dark-content" />
          <Stack.Navigator screenOptions={{headerTitleAlign: 'center',  headerStyle: { backgroundColor: colors.headerColor }}}>
            <Stack.Screen
              name="Home"
              component={HomeS}
              options={{
                headerTitle: (props) => (
                  <View style={{flexDirection: 'row', width:"300%"}}>
                  <>
                    <View>
                      <Title style={{paddingLeft: 180}}>
                        <Text>Home</Text>
                      </Title>
                    </View>

                    <View >
                      <TouchableRipple rippleColor="rgba(0, 0, 0, .32)">
                        <Switch
                          value={isDarktheme}
                          color="yellow"
                          onValueChange={() => togglemethod()}
                          style={{
                            paddingLeft:250,
                          }}
                        />
                      </TouchableRipple>
                      </View>
                      <View style={{}}>
                        <MaterialCommunityIcons
                          name={
                            isDarktheme
                              ? 'moon-waning-crescent'
                              : 'white-balance-sunny'
                          }
                          size={25}
                          color={isDarktheme ? "yellow" : "blue"}
                          style={{
                            paddingLeft: 110,
                           // paddingBottom: 5,
                            width: '200%',
                            flexDirection: 'row',
                            paddingRight:300
                          }}
                        />
                      </View>
                      </>
                    
                  </View>
                ),
              }}
            />
          </Stack.Navigator>
        </NavigationContainer>
      </PaperProvider>
    </>
  );
};

export default App;

currently the header looks like this:

enter image description here

look at the distance b/w the switch and Icon. trying to eliminate this was not possible for me. for example the text Home disappears while adjusting other elements like switch or Icon. I know this can be achieved. but I run out of options and glad that someone else can do it and learn from.


Solution

  • Since you want to add the switch and icon on the right, you should use headerRight instead of headerTitle

    options={{
      headerRight: () => (
        <View style={{ flexDirection: 'row', justifyContent: 'flex-end' }}>
          // Your switch and icon here
        </View>
      ),
    }}