【问题标题】:Nativescript Listview different behaviour on IOSNativescript Listview在IOS上的不同行为
【发布时间】:2019-03-04 08:30:20
【问题描述】:

我正在使用 RadListView 组件 Nativscript-ui-listview。在列表中,我显示了我自己构建的小部件。在 Android 上没有问题,只要我打开列表,它们就会全部加载并显示。但是在 IOS 上,我滚动过去然后滚动回它们后会加载一些负载,而有些则根本不会显示。左图是安卓,右图是IOS。该列表显示三个小部件,一个图表小部件、地图和一个带有数字的小部件。如何让它们在 IOS 上显示?

@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;
  }
}
<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>

【问题讨论】:

  • 您能否分享一个完整的 Playground 示例,以便重现该问题?
  • 我已经通过使用转发器而不是列表视图绕过了这种问题。如果这种方法对您有用,那么中继器在 iOS 上的可预测性会更高。
  • 我可以在 Angular 项目中使用中继器吗?

标签: angular nativescript angular2-nativescript nativescript-telerik-ui


【解决方案1】:

在 iOS 中,ListView 应该具有预定义的大小,否则它不会占用任何空间或导致一些副作用,因为 ios U|X 中的设计不支持动态行大小。我之前也遇到过这种问题。为行模板中的项目提供高度解决了我的问题。例如

<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>

确保在 app-widgets-picker 组件中也分配了高度。

附:是的,我注意到您使用的是ListViewLinearLayout,但这并不能解决问题。

【讨论】:

  • 感谢您的回复,我在您的示例中得到了更好的结果,但我将 RadListView 更改为 ListView。但是 ListView 似乎不会自动使用新数据更新我的小部件。如果我从图表小部件滚动并回滚到它,它只会加载但没有任何反应。列表中的其他项目在滚动时加载并消失。不是一个非常一致的行为。
  • 如果它是有角度的,那么使用 ngOnChanges 可以解决目的
  • 我应该刷新列表视图 OnChanges 吗?
  • 将行项目作为组件并在 ngonchange 上刷新数据外观
  • 我不明白该怎么做?有没有游乐场或很好的例子?
【解决方案2】:

所以我尝试了很多不同的方法来解决这个问题,我终于找到了一种适用于 android 和 ios 的方法。它可能没有像 ListView 那样内置所有花哨的东西,但它在两个平台上都能很好地工作。当 observable 获得新数据并且没有 ui 故障时,它会更新 ui。

解决方案是只使用 ScrollView 和 ngFor 来显示列表项。我只用较少的列表项(10-20)尝试过这个,它加载得非常快。

<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>

这并不能解决我在 ios 上使用 LitView 时遇到的问题,但暂时可以使用。

【讨论】:

  • ListView 是虚拟化的,这意味着它可以处理数千行。它只为显示区域内的内容创建 GUI 元素,然后在您滚动时更改这些元素以模拟滚动长列表。
  • 是的,我知道,滚动视图在显示更多行时不如适当的列表视图好。但我无法让列表工作。我需要把这个应用程序发布给客户。在这个应用程序的情况下,列表永远不会很大。我很想使用列表视图,但我无法让它在 iOS 上运行。
【解决方案3】:

我的数据在出现故障时没有显示在 Android 上。我按照@Narendra 所说的做了,并在 ngOnChanges 函数中执行了相应的代码。

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

@Narendra 非常感谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多