Smooth screen transition between splashscreen and slides-tour?


#1

Hi everyone!

My app shows a splashscreen for 3000ms, with a fade out. Then the app tour starts. The tour is a bunch of Slides. On Android device, the transition between the splashscreen and the Slides-tour gives a short white screen flicker at the bottom of the screen. A user can choose to not skip the tour on startup. Then the transition between the splashscreen and my apps HomePage has the same flicker. How to get a smooth transition?

Thank you!
Fred

my config.xml

  <preference name="AutoHideSplashScreen" value="false" />
  <preference name="SplashMaintainAspectRatio" value="true"/>
  <preference name="FadeSplashScreen" value="true"/>
  <preference name="FadeSplashScreenDuration" value="700"/>

I check if the tour is wanted first in my app.component file:

    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.hide(); 
      Splashscreen.hide();

    //redirect to the rootPage
    storage.get('showTour').then((val) => {
      console.log('We found showTour to be: ' + val);
      if (val == null){ 
        this.rootPage = OnboardingPage;
      } else {
        this.rootPage = HomePage;
      }      
    }).catch((err) => {
      console.log('error retrieving showTour value '+err)
    })

#2

Hi - I’ve seen the flicker too, but not sure what’s causing it… have you tried using the new debugging feature of Ionic? Maybe you could have a stepped debug and be able to see this way what element, or load effect is causing this?


#3

Hi Snag! Good idea. Using the debugger; script step? Never done this before…

Also, since the same glitch happens every time the splash goes over to another view, it seems like something goes wrong at the end of the splash-process.


#4

I just tested on iOS and everything transitions smoothly. It is Android that gives glitches. Where can I start to solve this issue?


#5

I just found out, there may be a flickering issue with splashscreen on Android only.
See here: https://issues.apache.org/jira/browse/CB-12099


#6

Hey Fred – did you make any progress in terms of fixing it?
I’ve seen the flickering before myself some time ago, I think, need to reproduce the effect though and then see what’s causing it


#7

Hi @Snag!

:confounded: To be honest: the flickering is frustrating me. I have tried so many things, but no matter what page launches that with the App, it starts with a short flicker. So even without splashscreen. It is really the very first page that loads. So, it seems an app-level issue rather than the splashscreen plugin. Android only.

How can I reproduce? I would like to get some handlers to debug this nasty one.

Thanks
Fred


#8

Hi Fred – I’ll try to reproduce this today and see if I can find out what’s causing it… I distinctly remember this issue myself, so lets see if we can fix it between us :slight_smile: (even if not, lets try, it’s annoying)

Is the post at apache.org from you, or just something you found that reflects your issue?


#9

@Snag Hi Snag

Great you try to help isolate this issue! We WILL find this one :slight_smile:
Here’s a short screen movie that shows what’s going on. Screenrecording Flicker

Apache poster is not me…

Cheerz


#10

At second 8-9, right? It’s really brief, I think the one I had a while back was worse…
Which version of ionic are you using? I believe in RC0 or later this is gone… I have one app here that is RC3 and it runs on Android with none of the flickering


#11

I think it is because you hide the splash screen before your rootpage has loaded.

I’m doing this:

				let rootPage: any = IntroPage;
				if (skipIntro) {
					rootPage = TabsPage;
				}
				this.navController
					.setRoot(rootPage)
					.then(() => Splashscreen.hide());

#12

Hi @infoproducts That’s an interesting suggestion. I am implementing your solution (check my code below), but get this error:

EXCEPTION: No provider for t! main.js:27556
ORIGINAL STACKTRACE: main.js:27561
Error: DI Error
    at e.Error (<anonymous>)
    at e (file:///android_asset/www/build/main.js:3:30277)
    at e (file:///android_asset/www/build/main.js:15:27169)
    at new e (file:///android_asset/www/build/main.js:15:27496)
    at t._throwOrNull (file:///android_asset/www/build/main.js:34:18600)
    at t._getByKeyDefault (file:///android_asset/www/build/main.js:34:18956)
    at t._getByKey (file:///android_asset/www/build/main.js:34:18510)
    at t.get (file:///android_asset/www/build/main.js:34:14872)
    at e.get (file:///android_asset/www/build/main.js:12:28858)
    at e.get (file:///android_asset/www/build/main.js:34:20634) main.js:27562
EXCEPTION: No provider for t! main.js:27556
ORIGINAL STACKTRACE: main.js:27561
Error: DI Error
    at e.Error (<anonymous>)
    at e (file:///android_asset/www/build/main.js:3:30277)
    at e (file:///android_asset/www/build/main.js:15:27169)
    at new e (file:///android_asset/www/build/main.js:15:27496)
    at t._throwOrNull (file:///android_asset/www/build/main.js:34:18600)
    at t._getByKeyDefault (file:///android_asset/www/build/main.js:34:18956)
    at t._getByKey (file:///android_asset/www/build/main.js:34:18510)
    at t.get (file:///android_asset/www/build/main.js:34:14872)
    at e.get (file:///android_asset/www/build/main.js:12:28858)
    at e.get (file:///android_asset/www/build/main.js:34:20634) main.js:27562
e

my app.component.ts file so far:

import { Component, ViewChild}  from '@angular/core';
import { 
  Platform, 
  Nav, 
  NavController }               from 'ionic-angular';
import './rxjs-operators';
import { 
  StatusBar,
  Splashscreen,
  Device
      }                         from 'ionic-native';
import { Storage }              from '@ionic/storage';

import { HomePage }             from '../pages/home/home';
import { OnboardingPage }       from '../pages/onboarding/onboarding';
import { HelperService }        from '../providers/helper-service';


@Component({
  template: `<ion-nav [root]="rootPage"></ion-nav>`
})

export class MyApp {
  // First page to push onto the stack
  rootPage: any = OnboardingPage;
  @ViewChild(Nav) nav: Nav;
  deviceUuid: string;
  appVersion: string;
 
  constructor(
    platform: Platform,
    helperService: HelperService,
    storage: Storage,
    navCtrl: NavController
     ) {

    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.

      //redirect to rootPage
      storage.get('skipTour').then((skipTour) => {
        console.log('success: value skipTour: ' + skipTour);
        if (skipTour){ 
          this.rootPage = HomePage;
        }  
        navCtrl.setRoot(this.rootPage)
					      .then(() => {
                  Splashscreen.hide();
                  StatusBar.hide(); });    
      }).catch((err) => {
        console.log('error retrieving skipTour value '+err)
      })

#13

You can’t inject NavController in the root component. See this: http://ionicframework.com/docs/v2/components/#navigating_from_root


#14

Thanks, @infoproducts! The error is gone :slight_smile: Still I have the flickering. See recording.

Has this something todo with storage? It may take some time before the SQLite has opened databases. Ideally, the view would render only after all this is done…

Also, I am confused with storage, does it need to be inside a platform.ready() handler or not? Not a word about it in the docs. I would say yes, because it uses a Cordova SQLite.


#15

Can you paste your complete AppComponent?

Don’t assign a initial value to rootPage. Your code should ideally go in ngOnInit and look something like this (not tested):

... 
@ViewChild('nav') public nav: NavController;

public rootPage: any;

public ngOnInit(): void {
	this.platform.ready()
		.then() = this.storage.get('skipTour'))
		.then(skipTour => {
			let rootPage = OnboardingPage;
			if (skipTour) {
				let rootPage = HomePage;
			}
			return this.nav.setRoot(rootPage);
		})
		.then(() => {
			Splashscreen.hide();
			StatusBar.hide();
		});
}

EDITED.


#16

As to platform.ready and storage, then yes, you should always call Cordova plugins when platform is ready, or you will run into hard to track down errors / your code simply won’t do anything.


#17

my full code:

import { Component, ViewChild}  from '@angular/core';
import { 
  Platform, 
  Nav }                         from 'ionic-angular';
import './rxjs-operators';
import { 
  StatusBar,
  Splashscreen,
  Device
      }                         from 'ionic-native';
import { Storage }              from '@ionic/storage';

import { HomePage }             from '../pages/home/home';
import { OnboardingPage }       from '../pages/onboarding/onboarding';
import { HelperService }        from '../providers/helper-service';


@Component({
  template: `<ion-nav [root]="rootPage"></ion-nav>`
})

export class MyApp {
  // First page to push onto the stack
  rootPage: any = OnboardingPage;
  @ViewChild(Nav) nav: Nav;
  deviceUuid: string;
  appVersion: string;
 
  constructor(
    platform: Platform,
    helperService: HelperService,
    storage: Storage,
     ) {

    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.

      //redirect to rootPage
      storage.get('skipTour').then((skipTour) => {
        console.log('success: value skipTour: ' + skipTour);
        if (skipTour){ 
          this.rootPage = HomePage;
        }  
        this.nav.setRoot(this.rootPage)
					      .then(() => {
                  Splashscreen.hide();
                  StatusBar.hide(); });    
      }).catch((err) => {
        console.log('error retrieving skipTour value '+err)
      })
      
      //android devices can go back with hard back button
      platform.registerBackButtonAction(() => { 
            console.log('back button pressed');
            if(this.nav.canGoBack()) {
              console.log('nav can go back');
              this.nav.pop();
            } 
        }, 100);
    
      let HTTPBody = {
        origin:       'app',
        event:        'app_launch',
        devUuid :     helperService.deviceUuid, //multiple reference to var, so set up as app wide in HelperService -> devUuid serves as unique user identifier 
        model:        Device.device.model, //one time use of these vars
        platform:     Device.device.platform,
        os:           Device.device.version,
        manufacturer: Device.device.manufacturer,
      }
      helperService.track(HTTPBody);

    });
  }

}

#18

I don’t see any flicker? There’s a delay between your logo fading out and the new page is displayed - is that what you mean by ‘flicker’? It should be solved by hiding the splashscreen only after the new page has already loaded.

Here’s how my transition looks:


#19

No I mean by ‘flicker’, the short white bar that appears near the bottom of the screen. It is just before my onboarding page shows. It is very short, but I would like a professional look. Like your transition! Beautifully done :slight_smile: Now I wil see if it disappears with the ngOnInit method. Again, on iOS it runs smooth. Android only.


#20

Ah, I see it now.

Actually, that looks like it’s because you’re hiding the statusbar (the white bar is same height as the statusbar when it starts to disappear).