FuYaoDe / react-native-app-intro

react-native-app-intro is a react native component implementing a parallax effect welcome page using base on react-native-swiper , similar to the one found in Google's app like Sheet, Drive, Docs...
MIT License
3.24k stars 508 forks source link

Updating the statusbar color resets the pagination indicator #38

Open SandroMachado opened 7 years ago

SandroMachado commented 7 years ago

Hi @FuYaoDe,

I am trying to update the status bar color (in Android) to match background of each page of the onboard.

My render function looks like this:

  render() {
    return (
      <View>
      <StatusBar
        backgroundColor={shadeStatusBarColor(this.state.statusBarColor, -0.3)}
      />
      <AppIntro
        onDoneBtnClick={this.doneBtnHandle}
        onSkipBtnClick={this.onSkipBtnHandle}
        onSlideChange={this.onSlideChangeHandle}
        pageArray={this.state.pageArray}
      />
      </View>
    );
  }

On the slide change callback I have this:

onSlideChangeHandle = (index, total) => {
    this.setState({ statusBarColor: this.state.pageArray[index].backgroundColor, currentPage: index });
  }

Doing this, the color of the statusbar changes, but the pagination is reset to the first position.

baconmhc19qsandromachado09262016140353

I also tried to do this change directly in the library (I want to make a PR to add this feature to the library also), but the behaviour is the same, the page position is not persisted.

Do you have any tips to fix this?

Thanks for the great work.

nelsonkam commented 7 years ago

Hello @SandroMachado this behaviour is due to the use of setState in your callback. Using setState triggers the render method thereby reinitializing the AppIntro component (and resetting pagination to first position).

SandroMachado commented 7 years ago

@nelsonkam I know, but the component should know that it is not required to redraw the component, since I am not changing any variable that affects the component.

FuYaoDe commented 7 years ago

Hi @SandroMachado You can use defaultIndex temporarily fix the bug

  render() {
    return (
      <View>
      <StatusBar
        backgroundColor={shadeStatusBarColor(this.state.statusBarColor, -0.3)}
      />
      <AppIntro
        onDoneBtnClick={this.doneBtnHandle}
        onSkipBtnClick={this.onSkipBtnHandle}
        onSlideChange={this.onSlideChangeHandle}
        pageArray={this.state.pageArray}
        defaultIndex={this.state.currentPage}
      />
      </View>
    );
  }
onSlideChangeHandle = (index, total) => {
    this.setState({ 
      statusBarColor: this.state.pageArray[index].backgroundColor,
      currentPage: index 
    });
  }

And I will look for the unusual render

SandroMachado commented 7 years ago

Another fix for this is using the imperative method available in the StatusBar.

StatusBar.setBackgroundColor(shadeStatusBarColor(this.pageArray[index].backgroundColor, -0.3), false);

This will not cause the re-render of the AppIntro component.

SandroMachado commented 7 years ago

This is kind of fixed by #42.

jonathanpalma commented 7 years ago

Do you know a way to make this works for Advanced Usage?

shareefhiasat commented 6 years ago

Didnt the newest versions of the library have this sorted ?! yet .