Ionic App overlaps in a wear way on Android ZTE

I don`t know what exactly is going wrong, but I am desperate. App works completely fine on Samsung, LG, Moto and Android Emulator, but it goes really wear on ZTE.

After a page change (with root) or menu swipe, app overlaps pages in a really wear way, I upload what it displays:

But when I inspect on Console with Chrome Developer Tools it looks perfectly fine.

The device is a ZTE BLACE A530 (8.1.0) with Chrome updated to last version.

My package looks like this:

"@angular/animations": "^11.2.12",
    "@angular/common": "~11.2.0",
    "@angular/core": "~11.2.0",
    "@angular/fire": "^6.1.4",
    "@angular/forms": "~11.2.0",
    "@angular/localize": "~11.2.0",
    "@angular/platform-browser": "~11.2.0",
    "@angular/platform-browser-dynamic": "~11.2.0",
    "@angular/router": "~11.2.0",
    "@ionic-native/android-permissions": "^5.34.0",
    "@ionic-native/background-geolocation": "^5.33.1",
    "@ionic-native/background-mode": "^5.33.1",
    "@ionic-native/camera": "^5.33.1",
    "@ionic-native/core": "^5.32.1",
    "@ionic-native/device": "^5.33.1",
    "@ionic-native/device-orientation": "^5.32.1",
    "@ionic-native/diagnostic": "^5.33.1",
    "@ionic-native/geolocation": "^5.32.1",
    "@ionic-native/in-app-browser": "^5.32.1",
    "@ionic-native/location-accuracy": "^5.32.1",
    "@ionic-native/onesignal": "^5.31.1",
    "@ionic-native/splash-screen": "^5.32.1",
    "@ionic-native/status-bar": "^5.32.1",
    "@ionic/angular": "^5.5.2",
    "@ng-bootstrap/ng-bootstrap": "^9.1.0",
    "@sentry/angular": "^6.3.5",
    "@sentry/tracing": "^6.3.5",
    "@types/googlemaps": "^3.43.3",
    "@types/intro.js": "^3.0.1",
    "add": "^2.0.6",
    "angular-code-input": "^1.4.0",
    "bootstrap": "^4.5.0",
    "bs-stepper": "^1.7.0",
    "cordova": "^10.0.0",
    "cordova-browser": "6.0.0",
    "cordova-plugin-background-fetch": "^6.0.3",
    "cordova-plugin-geolocation": "^4.1.0",
    "cordova-plugin-ionic-webview": "^5.0.0",
    "cordova-plugin-statusbar": "^2.4.3",
    "firebase": "^7.0 || ^8.0",
    "geofire-common": "^5.2.0",
    "globalthis": "^1.0.2",
    "intro.js": "^3.4.0",
    "ionic": "^5.4.16",
    "ionic4-mask-directive": "^1.0.2",
    "ngx-image-compress": "^11.0.3",
    "ngx-image-cropper": "^3.3.5",
    "ngx-mask": "^11.1.5",
    "ngx-moment": "^5.0.0",
    "ngx-order-pipe": "^2.1.1",
    "plugin": "^0.3.3",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"

A fragment of my code is:
View after changing page:

<ion-header class="ion-no-border ">
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button mode="md" text="" defaultHref="/login" icon="chevron-back-outline">
      </ion-back-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col size="12" class="ion-text-center">
        <ion-grid>
          <ion-row>
            <ion-col size="8">
              <h1 class="ion-text-left">
                Nueva cuenta
              </h1>
            </ion-col>
            <ion-col size="4">
              <input id="fotoPerfil" class="doNotShow" (change)="changeListener($event)" type="file" accept="image/*">
              <input id="fotoPerfilCamera" class="doNotShow" (change)="changeListener($event)" type="file"
                accept="image/*;capture=camera" capture="environment">
              <div class="img-picker-wrapper">
                <div *ngIf="!userData.imagen" (click)="presentPopover($event)" class="img-picker">
                  <ion-icon name="camera-outline"></ion-icon>
                </div>
                <div *ngIf="userData.imagen" (click)="presentPopover($event)" class="img-profile">
                  <img [src]="userData.imagen" alt="">
                </div>
                <small (click)="presentPopover($event)">
                  Subir foto
                </small>
              </div>
            </ion-col>
          </ion-row>
        </ion-grid>
      </ion-col>
      <ion-col size="12" class="ion-text-center">
        <form [formGroup]="registerForm" (ngSubmit)="login()">
          <ion-list>
            <ion-item>
              <ion-label position="floating">Correo electrónico</ion-label>
              <ion-input formControlName="email" autocorrect="on" autofocus="on" autocomplete="email" color="primary"
                type="email" inputmode="email" placeholder="Correo electrónico de usuario" required="true"></ion-input>
              <ion-icon size="small" name="mail-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Contraseña</ion-label>
              <ion-input formControlName="password" clearInput="true" clearOnEdit="true" color="primary" type="text"
                inputmode="password" placeholder="Contraseña" required="true"></ion-input>
              <ion-icon size="small" name="key-outline" slot="start"></ion-icon>
              <div *ngIf="!registerForm.controls.password.valid &&
                registerForm.controls.password.dirty" class="validator-error text-danger">
                <small>La contraseña debe tener al menos 6 caracteres.</small>
              </div>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Nombres</ion-label>
              <ion-input formControlName="nombres" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                autocomplete="name" type="text" inputmode="text" placeholder="Ingresa tus nombres" required="true">
              </ion-input>
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Apellidos</ion-label>
              <ion-input formControlName="apellidos" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                autocomplete="given-name" type="text" inputmode="text" placeholder="Ingresa tus apellidos"
                required="true"></ion-input>
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Número de teléfono</ion-label>
              <ion-input formControlName="telefono" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                type="tel" inputmode="tel" placeholder="Ingresa tu número de teléfono" required="true"></ion-input>
              <ion-icon size="small" name="call-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item (click)="verAlertaViajeSeguro()" class="mt-4" button lines="none" [detail]="false">
              <ion-label class="ion-text-wrap">
                Información para Viaje Seguro
              </ion-label>
              <ion-icon name="help-circle-outline" slot="end"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">Número de DPI (sólo números)</ion-label>
              <input formControlName="dpi" autocorrect="on" autofocus="on" clearInput="true" class="with-mask"
                mask="0000 00000 0000" color="primary" type="text" inputmode="text"
                placeholder="Ingresa tu número de DPI" required="true">
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item *ngIf="dpi.invalid && (dpi.dirty || dpi.touched)" class="ion-text-center" lines="none">
              <small class="ion-text-center w100">
                Por favor, revisa el DPI ingresado, sólo pueden ser números.
              </small>
            </ion-item>
            <ion-item (click)="seleccionarImagen($event,'foto_dpi', 2, false)">
              <ion-label position="stacked">Fotografía de DPI</ion-label>
              <ion-input disabled class="donotfade" color="primary" type="text" placeholder="Foto DPI" required="true">
              </ion-input>
              <ion-icon size="small" name="image-outline" slot="start">
              </ion-icon>
            </ion-item>
            <div *ngIf="userData.foto_dpi" class="img-selected">
              <img [src]="userData.foto_dpi" alt="">
              <ion-icon (click)="borrarFoto('foto_dpi')" name="close-outline"></ion-icon>
            </div>
            <ion-item>
              <ion-label position="stacked">Fecha de nacimiento</ion-label>
              <ion-datetime displayFormat="DD/MM/YYYY" formControlName="fecha_nacimiento"
                placeholder="Selecciona una fecha de nacimiento" type="date" cancelText="cancelar" doneText="Aceptar"
                clearInput>
              </ion-datetime>
              <ion-icon size="small" name="calendar-outline" slot="start">
              </ion-icon>
            </ion-item>
            <div class="spacer"></div>
            <div class="ion-checkbox-wrapper">
              <ion-checkbox mode="md" slot="start" formControlName="publicidad"></ion-checkbox>
              <ion-label (click)="cambiarDisponibilidad('publicidad')">
                Recibir publicidad y noticias.
              </ion-label>
            </div>
            <div class="spacer"></div>
            <div class="ion-checkbox-wrapper">
              <ion-checkbox mode="md" slot="start" formControlName="acepto"></ion-checkbox>
              <ion-label (click)="cambiarDisponibilidad('acepto')">
                Acepto los
                <span routerLink="/terms" class="color-primary">Términos y Condiciones.</span>
              </ion-label>
            </div>
            <div class="spacer"></div>
            <ion-button class="special" [disabled]="registerForm.invalid" type="submit" shape="round" color="primary">
              Completar registro
            </ion-button>
            <ion-item class="ion-text-center" lines="none">
              <a class="register w100" routerLink="/login">
                ¿Ya tienes una cuenta?
                <small class="ion-text-center w100">
                  Inicia sesión
                </small>
              </a>
            </ion-item>
          </ion-list>
        </form>
      </ion-col>
    </ion-row>
  </ion-grid>

</ion-content>

<ng-template #content let-modal>
  <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Ajusta la imagen</h4>
    <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <image-cropper [imageChangedEvent]="imageChangedEvent" [maintainAspectRatio]="maintainAspectRatio"
      [aspectRatio]="ratio" backgroundColor="#ffffff" [imageBase64]="imageURL" [resizeToWidth]="width_resize"
      format="jpeg" [canvasRotation]="rotacion" (imageCropped)="imageCropped($event)">
    </image-cropper>

    <ion-button (click)="rotar()" class=" uk-button uk-button-default" type="button" shape="round">
      Rotar
    </ion-button>
    <ion-button (click)="completarCambio()" class="uk-modal-close uk-button uk-button-default" shape="round"
      type="button">
      Completar
    </ion-button>
  </div>
</ng-template>

<input class="noFileInput" id="noFileInput" (change)="seleccionarImagenChange($event)" type="file"
  accept="image/*;capture=camera">
<input class="noFileInput" id="noFileInputCamera" (change)="seleccionarImagenChange($event)" type="file"
  accept="image/*;capture=camera" capture="environment">

View before page change:

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col size="12" class="ion-text-center">
        <h1>
          Selecciona una opción
        </h1>
      </ion-col>
      <ion-col size="12" class="ion-text-center">
        <ion-button class="special" (click)="cerrar('user')" [routerLink]="linkUser" shape="round" color="primary"
          routerDirection="root">
          Ser un Usuario
        </ion-button>
        <ion-button class="special" (click)="cerrar('memo')" [routerLink]="linkMemo" shape="round" color="secondary"
          routerDirection="root">
          Ser un Memo
        </ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

Please help, I`ve been having this extremely wear bug without any reazon.

Hi, as a test, I disabled Chrome as webview and everything went back to normal, sadly I can’t ask each user to do the same, is there a reason?

Hard to say what the issue is with the info provided here. What version of the webview are you running where things are broken? You can find this by logging window.navigator.userAgent when inspecting the app with dev tools.

Additionally, I noticed you are using Android 8.1.0. Are you using the <ion-icon> component at all? Another developer is running into a Chromium bug on certain devices where SVG icons cause the webview to render incorrectly (See: Android 8.1 Icons not displaying).

1 Like

Thank you, so much. I get from this “window.navigator.userAgent”: Mozilla/5.0 (Linux; Android 8.1.0; BLADE A530 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile Safari/537.36

Looks like you have a modern version of Chromium which is good. Are you using the <ion-icon> component anywhere in your app?

Yes, I am using it, at almost every page. If I go to the login page, which has a code like this:

<ion-header>
</ion-header>

<ion-content>
  <ion-grid>
    <ion-row  >
      <ion-col size="12" class="ion-text-center">
        <h1>
          Bienvenido a Memo
        </h1>
        <ion-button (click)="seleccionarRegistro()" class="special" type="submit" shape="round" color="primary">
          Regístrate
        </ion-button>
        <br>
        <p class="mt-4">
          <small>
            ¿Ya tienes una cuenta? Completa el siguiente formulario.
          </small>
        </p>
      </ion-col>
      <ion-col size="12" class="ion-text-center">
        <form [formGroup]="loginForm" (ngSubmit)="login()">
          <ion-list>

            <ion-item>
              <ion-label position="floating">Correo electrónico</ion-label>
              <ion-input formControlName="email" autocorrect="on" color="primary" type="email" inputmode="email"
                placeholder="Correo electrónico de usuario" required="true"></ion-input>
              <ion-icon size="small" name="mail-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Contraseña</ion-label>
              <ion-input formControlName="password" clearInput="true" clearOnEdit="true" color="primary" type="password"
                inputmode="password" placeholder="Contraseña" required="true"></ion-input>
              <ion-icon size="small" name="key-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item class="ion-text-center" lines="none">
              <a class="forget w100" routerLink="/forget">
                <small class="ion-text-center w100">
                  ¿Has olvidado tu contraseña?
                </small>
              </a>
            </ion-item>
            <ion-button class="special" [disabled]="loginForm.invalid" type="submit" shape="round" color="primary">
              Acceder
            </ion-button>
          </ion-list>
        </form>
      </ion-col>
      <ion-col size="12" size-sm="12" size-md="8" size-lg="6" class="ion-padding">
        <app-cintillo></app-cintillo>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

But, If I go to register, with a code like this:

<ion-header class="ion-no-border ">
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button mode="md" text="" defaultHref="/login" icon="chevron-back-outline">
      </ion-back-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col size="12" class="ion-text-center">
        <ion-grid>
          <ion-row>
            <ion-col size="8">
              <h1 class="ion-text-left">
                Nueva cuenta
              </h1>
            </ion-col>
            <ion-col size="4">
              <input id="fotoPerfil" class="doNotShow" (change)="changeListener($event)" type="file" accept="image/*">
              <input id="fotoPerfilCamera" class="doNotShow" (change)="changeListener($event)" type="file"
                accept="image/*;capture=camera" capture="environment">
              <div class="img-picker-wrapper">
                <div *ngIf="!userData.imagen" (click)="presentPopover($event)" class="img-picker">
                  <ion-icon name="camera-outline"></ion-icon>
                </div>
                <div *ngIf="userData.imagen" (click)="presentPopover($event)" class="img-profile">
                  <img [src]="userData.imagen" alt="">
                </div>
                <small (click)="presentPopover($event)">
                  Subir foto
                </small>
              </div>
            </ion-col>
          </ion-row>
        </ion-grid>
      </ion-col>
      <ion-col size="12" class="ion-text-center">
        <form [formGroup]="registerForm" (ngSubmit)="login()">
          <ion-list>
            <ion-item>
              <ion-label position="floating">Correo electrónico</ion-label>
              <ion-input formControlName="email" autocorrect="on" autofocus="on" autocomplete="email" color="primary"
                type="email" inputmode="email" placeholder="Correo electrónico de usuario" required="true"></ion-input>
              <ion-icon size="small" name="mail-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Contraseña</ion-label>
              <ion-input formControlName="password" clearInput="true" clearOnEdit="true" color="primary" type="text"
                inputmode="password" placeholder="Contraseña" required="true"></ion-input>
              <ion-icon size="small" name="key-outline" slot="start"></ion-icon>
              <div *ngIf="!registerForm.controls.password.valid &&
                registerForm.controls.password.dirty" class="validator-error text-danger">
                <small>La contraseña debe tener al menos 6 caracteres.</small>
              </div>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Nombres</ion-label>
              <ion-input formControlName="nombres" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                autocomplete="name" type="text" inputmode="text" placeholder="Ingresa tus nombres" required="true">
              </ion-input>
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Apellidos</ion-label>
              <ion-input formControlName="apellidos" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                autocomplete="given-name" type="text" inputmode="text" placeholder="Ingresa tus apellidos"
                required="true"></ion-input>
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Número de teléfono</ion-label>
              <ion-input formControlName="telefono" autocorrect="on" autofocus="on" clearInput="true" color="primary"
                type="tel" inputmode="tel" placeholder="Ingresa tu número de teléfono" required="true"></ion-input>
              <ion-icon size="small" name="call-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item (click)="verAlertaViajeSeguro()" class="mt-4" button lines="none" [detail]="false">
              <ion-label class="ion-text-wrap">
                Información para Viaje Seguro
              </ion-label>
              <ion-icon name="help-circle-outline" slot="end"></ion-icon>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">Número de DPI (sólo números)</ion-label>
              <input formControlName="dpi" autocorrect="on" autofocus="on" clearInput="true" class="with-mask"
                mask="0000 00000 0000" color="primary" type="text" inputmode="text"
                placeholder="Ingresa tu número de DPI" required="true">
              <ion-icon size="small" name="person-outline" slot="start"></ion-icon>
            </ion-item>
            <ion-item *ngIf="dpi.invalid && (dpi.dirty || dpi.touched)" class="ion-text-center" lines="none">
              <small class="ion-text-center w100">
                Por favor, revisa el DPI ingresado, sólo pueden ser números.
              </small>
            </ion-item>
            <ion-item (click)="seleccionarImagen($event,'foto_dpi', 2, false)">
              <ion-label position="stacked">Fotografía de DPI</ion-label>
              <ion-input disabled class="donotfade" color="primary" type="text" placeholder="Foto DPI" required="true">
              </ion-input>
              <ion-icon size="small" name="image-outline" slot="start">
              </ion-icon>
            </ion-item>
            <div *ngIf="userData.foto_dpi" class="img-selected">
              <img [src]="userData.foto_dpi" alt="">
              <ion-icon (click)="borrarFoto('foto_dpi')" name="close-outline"></ion-icon>
            </div>
            <ion-item>
              <ion-label position="stacked">Fecha de nacimiento</ion-label>
              <ion-datetime displayFormat="DD/MM/YYYY" formControlName="fecha_nacimiento"
                placeholder="Selecciona una fecha de nacimiento" type="date" cancelText="cancelar" doneText="Aceptar"
                clearInput>
              </ion-datetime>
              <ion-icon size="small" name="calendar-outline" slot="start">
              </ion-icon>
            </ion-item>
            <div class="spacer"></div>
            <div class="ion-checkbox-wrapper">
              <ion-checkbox mode="md" slot="start" formControlName="publicidad"></ion-checkbox>
              <ion-label (click)="cambiarDisponibilidad('publicidad')">
                Recibir publicidad y noticias.
              </ion-label>
            </div>
            <div class="spacer"></div>
            <div class="ion-checkbox-wrapper">
              <ion-checkbox mode="md" slot="start" formControlName="acepto"></ion-checkbox>
              <ion-label (click)="cambiarDisponibilidad('acepto')">
                Acepto los
                <span routerLink="/terms" class="color-primary">Términos y Condiciones.</span>
              </ion-label>
            </div>
            <div class="spacer"></div>
            <ion-button class="special" [disabled]="registerForm.invalid" type="submit" shape="round" color="primary">
              Completar registro
            </ion-button>
            <ion-item class="ion-text-center" lines="none">
              <a class="register w100" routerLink="/login">
                ¿Ya tienes una cuenta?
                <small class="ion-text-center w100">
                  Inicia sesión
                </small>
              </a>
            </ion-item>
          </ion-list>
        </form>
      </ion-col>
    </ion-row>
  </ion-grid>

</ion-content>

<ng-template #content let-modal>
  <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Ajusta la imagen</h4>
    <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <image-cropper [imageChangedEvent]="imageChangedEvent" [maintainAspectRatio]="maintainAspectRatio"
      [aspectRatio]="ratio" backgroundColor="#ffffff" [imageBase64]="imageURL" [resizeToWidth]="width_resize"
      format="jpeg" [canvasRotation]="rotacion" (imageCropped)="imageCropped($event)">
    </image-cropper>

    <ion-button (click)="rotar()" class=" uk-button uk-button-default" type="button" shape="round">
      Rotar
    </ion-button>
    <ion-button (click)="completarCambio()" class="uk-modal-close uk-button uk-button-default" shape="round"
      type="button">
      Completar
    </ion-button>
  </div>
</ng-template>

<input class="noFileInput" id="noFileInput" (change)="seleccionarImagenChange($event)" type="file"
  accept="image/*;capture=camera">
<input class="noFileInput" id="noFileInputCamera" (change)="seleccionarImagenChange($event)" type="file"
  accept="image/*;capture=camera" capture="environment">

Everything gets wear.

To make sure it’s not the issue I posted above, does the app still break even if you remove every instance of <ion-icon> in your app?

Yes, it is exactly that problem, I changed using npm install ionicons@4 --save-exact, but now they are not visible.

There is an open Chromium bug for this: 1222095 - chromium - An open-source project to help move the web forward. - Monorail. I recommend posting on that thread that you have the same issue and tell them what device you are using. Having more people chime in on that thread will help the Chromium team estimate impact and prioritize a fix.

You might want to look at Easiest way to prevent all ion-icons from displaying?, where another developer is trying to account for this bug. You two might be able to collaborate on a solution.

2 Likes