4

I have a expo app written with react-navigation ^3.12.0 I have a theme selection on my app, meaning you can click on color circle, and every screen on the app will have the background color whatever you chose, however the react-navigation doesn't change the header color, react-navigation only changes color accordingly if you navigate to different screen and go back to the screen where you can choose theme colors.

This is my code.

class AccountScreen extends Component {
    static navigationOptions = ({navigation}) => {
        const {params} = navigation.state;
        return {
            title: navigation.getParam("otherParam", "Account"),
            headerTintColor: "white",
            headerStyle: {
                elevation: 0,
                shadowOpacity: 0,
                borderBottomWidth: 0,
                backgroundColor: navigation.getParam("themeBackgroundColor"),
            },
            headerLeft: (
                < TouchableOpacity
            style = {
        {
            paddingLeft: 15
        }
    }
        onPress = {()
    =>
        navigation.dispatch(DrawerActions.toggleDrawer())
    }
    >
    <
        Feather
        name = "arrow-left"
        size = {24}
        color = "#ffffff" / >
            < /TouchableOpacity>
    ),
        headerRight: <
        View
        style = {
        {
            flexDirection: "row"
        }
    }><
        /View>,
    }
        ;
    };

    constructor(props) {
        super(props);
        this.state = {
            loading: false,
        };
    }

    componentDidMount() {
        // https://github.com/facebook/react-native/issues/12981
        YellowBox.ignoreWarnings(["Setting a timer"]);
        const {theme, navigation} = this.props;
        navigation.setParams({
            themeBackgroundColor: theme.backgroundColor,
        });
    }

    render() {
        renderItem = ({item}) => (
            < TouchableOpacity
        onPress = {()
    =>
        this.props.setTheme(item.key)
    }>
    <
        View
        style = {
            [
                style.itemContainer,
        {
            backgroundColor: item.backgroundColor,
        }
    ,
    ]
    }
        />
        < /TouchableOpacity>
    )
        ;
        return (
            < FlatList
        style = {
            [
                style.container,
        {
            backgroundColor: this.props.theme.backgroundColor
        }
    ,
    ]
    }
        data = {this.props.themes}
        numColumns = {3}
        contentContainerStyle = {
        {
            flexGrow: 1,
                justifyContent
        :
            "center",
                left
        :
            "14%",
        }
    }
        renderItem = {renderItem}
        />
    )
        ;
    }
}

Do I need to use redux? Please advise.

Edit: This is where i handle color selection

 <TouchableOpacity onPress={() => this.props.setTheme(item.key)}>
        <View
          style={[
            style.itemContainer,
            {
              backgroundColor: item.backgroundColor,
            },
          ]}
        />
      </TouchableOpacity>
5
  • Try to navigate to the same component after setting params navigation.setParams({ themeBackgroundColor: theme.backgroundColor, }); navigation.navigate('AccountScreen') ... I haven't tested it Commented Jul 24, 2020 at 13:37
  • Sadly does not work, thanks for your prompt reply. Commented Jul 24, 2020 at 13:50
  • Ciao, if I understood correctly you have a page in which you can change color (an this page is not AccountScreen). So why you are re-setting background color in AccountScreen? I mean why you wrote this line backgroundColor: navigation.getParam("themeBackgroundColor") ? Commented Jul 24, 2020 at 13:55
  • Sorry if you misunderstood wrong, English is not my first language, AccountScreen is the component, that handles the color selection and I'd like to change the color of header when you choose a new color, do you have any suggestions how else I should reference the active theme color? Commented Jul 24, 2020 at 13:58
  • Yeah, English is not my first language too. I made an answer, check if could work. Commented Jul 24, 2020 at 14:13

1 Answer 1

1

Ciao, try to modify your code like:

static navigationOptions = ({ navigation }) => {
const {params} = navigation.state;
return {
  ...
  headerStyle: {
    ...
    backgroundColor: navigation.getParam('BackgroundColor', '#ED2525'),  // replace themeBackgroundColor with BackgroundColor
    // #ED2525 is a default value, you can remove it if you don't need
  },
  ...
};
};

Then on componentDidMount:

componentDidMount() {
    // https://github.com/facebook/react-native/issues/12981
    YellowBox.ignoreWarnings(["Setting a timer"]);
    const {theme, navigation} = this.props;
    navigation.setParams({
        BackgroundColor: theme.backgroundColor,
    });
}

Should solve your problem.

Sign up to request clarification or add additional context in comments.

7 Comments

This doesn't work as well, I'm trying to change the header color at the same time when I click on specific color circle, and then change the header color, without having to navigate to different component. Image how it looks when I choose red color: i.imgur.com/ozZiKT3.png
Sorry can you show me code when you change color? I imagine there should be something like navigation.setParams({ BackgroundColor: theme.backgroundColor, });
Do you mean this? navigation.setParams({ BackgroundColor: theme.backgroundColor, });
Yes but on your code example navigation.setParams({...}) is visible only in componentDidMount function that is triggered one time when you enter on AccountScreen. When user select a color, there should be the same line with the color that user selected. Correct?
The color selection is handled in TouchableOpacity element, could it be that we need to add the color logic for header in the touchableopacity onPress function too? Check main post I've updated it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.