1
votes

Nativescript Listview différents comportements sur IOS

J'utilise Nativscript-ui-listview, le composant RadListView. Dans la liste, j'affiche des widgets que j'ai créés moi-même. Sur Android, il n'y a pas de problème, ils sont tous chargés et affichés dès que j'ouvre la liste. Mais sur IOS, une certaine charge après que je les ai fait défiler, puis que je revienne vers eux, et certains ne s'afficheront pas du tout. L'image de gauche est Android et l'image de droite est IOS. La liste montre trois widgets, un widget Graphique, une carte et un widget avec des nombres. Comment puis-je les faire afficher sur IOS?

<GridLayout tkExampleTitle tkToggleNavButton>
  <app-action-bar [title]="title"></app-action-bar>
  <RadListView [items]="dataItems" id="rlv">
    <ng-template tkListItemTemplate let-item="item">
      <StackLayout orientation="vertical">
        <GridLayout columns="auto">
          <app-widgets-picker horizontalAlignment="left" [widget]="item"></app-widgets-picker>
        </GridLayout>
      </StackLayout>
    </ng-template>
    <ListViewLinearLayout *appIfIos tkListViewLayout itemHeight="250"></ListViewLinearLayout>
  </RadListView>
</GridLayout>
@Component({
  selector: 'app-newlist',
  templateUrl: './new-widgets-list.component.html',
  styleUrls: ['./new-widgets-list.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  moduleId: module.id,
})

export class NewListComponent implements OnInit {
  public title: String = 'Widgets';
  public widgetsListSubscription = new Subscription;
  public widgets$: ObservableArray < Widget > ;
  public _sourceDataItems: ObservableArray < Widget > ;
  public _sourceDataItems2: ObservableArray < Widget > ;
  public processing$ = new BehaviorSubject < boolean > (true);
  public listview: RadListView;
  public layout: ListViewLinearLayout;

  constructor(public page: Page,
    private readonly store: Store < AppState > ) {
    this.initData();
  }

  ngOnInit(): void {
    this.widgets$ = new ObservableArray < Widget > ();
  }

  public get dataItems(): ObservableArray < Widget > {
    return this._sourceDataItems2;
  }

  private initData(): void {
    this._sourceDataItems = new ObservableArray < Widget > ();
    const data = this.store.pipe(
      select(getDisplayedWidgets),
      map(idmap => Object.values(idmap))
    );
    data.subscribe(list => this._sourceDataItems.push(list));
    this._sourceDataItems2 = this._sourceDataItems;
  }
}


3 commentaires

Pouvez-vous s'il vous plaît partager un échantillon de Playground complet où le problème peut être reproduit?


J'ai contourné ce genre de problème en utilisant un répéteur plutôt qu'une liste. Si cette approche fonctionne pour vous, les répéteurs sont beaucoup plus prévisibles sur iOS.


Puis-je utiliser le répéteur dans un projet angulaire?


3 Réponses :


0
votes

Sous iOS, le ListView doit avoir une taille prédéfinie, sinon il n'occupera aucun espace ou entraînera des effets secondaires car la taille de ligne dynamique n'est pas prise en charge par la conception dans ios U | X. J'ai eu ce genre de problème plus tôt. Fournir la hauteur des éléments dans le modèle de ligne a résolu les problèmes pour me.eg

<ng-template tkListItemTemplate let-item="item">
      <StackLayout orientation="vertical" height="250">
        <GridLayout columns="auto" height="250">
          <app-widgets-picker horizontalAlignment="left" [widget]="item"></app-widgets-picker>
        </GridLayout>
      </StackLayout>
</ng-template>

Assurez-vous que la hauteur est également attribuée dans votre composant app-widgets-picker .

PS Oui, j'ai remarqué que vous utilisez ListViewLinearLayout mais cela ne résout pas l'objectif.


5 commentaires

Merci pour la réponse, j'ai obtenu un meilleur résultat avec votre exemple, mais j'ai changé le RadListView en ListView. Mais le ListView ne semble pas mettre à jour automatiquement mes widgets avec de nouvelles données au fur et à mesure. Et si je fais défiler le widget du graphique et y reviens, il se charge mais rien ne se passe. Les autres éléments de la liste se chargent et disparaissent lors du défilement. Pas un comportement très cohérent.


S'il est angulaire, utiliser ngOnChanges résout le but


Dois-je actualiser la vue de liste OnChanges?


Faire de l'élément de ligne un composant et actualiser l'apparence des données sur ngonchange


Je ne comprends pas comment faire ça? Y a-t-il un terrain de jeu ou un bon exemple de cela?



0
votes

J'ai donc essayé tellement de choses différentes pour résoudre ce problème et j'en ai finalement trouvé une qui fonctionne à la fois pour Android et iOS. Il n'a peut-être pas toutes les fonctionnalités sophistiquées intégrées à ListView, mais il fonctionne à merveille sur les deux plates-formes. Il met à jour l'interface utilisateur lorsque l'observable obtient de nouvelles données et qu'il n'y a pas de problèmes d'interface utilisateur.

La solution consiste simplement à utiliser un ScrollView et un ngFor pour afficher les éléments de la liste. Je n'ai essayé cela qu'avec de plus petites quantités d'éléments de listes (10-20) et cela se charge très rapidement.

<ScrollView orientation="vertical">
  <GridLayout rows="auto, auto">
    <StackLayout row="0">
      <StackLayout *ngFor="let item of obs$ | async" class="card">
        <app-widgets-picker horizontalAlignment="left" [widget]="item"></app-widgets-picker>
      </StackLayout>
    </StackLayout>
  </GridLayout>
</ScrollView>

Cela ne résout pas les problèmes que j'ai rencontrés avec le LitView sur iOS mais cela fonctionne pour le moment.


2 commentaires

Le ListView est virtualisé, ce qui signifie qu'il peut gérer des milliers de lignes. Il ne crée que des éléments d'interface graphique pour ce qui se trouve dans la zone d'affichage, puis modifie ces éléments lorsque vous faites défiler pour simuler le défilement dans une longue liste.


Oui, je sais, la vue par défilement n'est pas aussi bonne qu'une vue de liste appropriée pour afficher de plus grandes quantités de lignes. Mais je n'ai pas pu faire fonctionner la liste. Et j'ai besoin de diffuser cette application auprès des clients. Et dans ce cas d'applications, les listes ne seront jamais très grandes. J'adorerais utiliser la vue liste mais je ne peux pas la faire fonctionner sur iOS.



0
votes

mes données ne sont pas apparues sur Android car elles ont diminué. J'ai fait ce que @Narendra a dit et ai exécuté les codes correspondants dans la fonction ngOnChanges.

ngOnChanges(){
    if (this.item.profilePhoto === undefined) this.setAnonimProfilePhoto();
    if (!this.item.isOnline) this.userOfflineFromNow();
    this.getCityName();
}

@Narendra alors merci.


0 commentaires