Nativescript 在 ListView 中向上滚动时显示元素 - 视差效果
Posted
技术标签:
【中文标题】Nativescript 在 ListView 中向上滚动时显示元素 - 视差效果【英文标题】:Nativescript Show element while scrolling up in ListView - parallax effect 【发布时间】:2019-01-12 12:03:22 【问题描述】:我想获得有关如何实现在许多应用程序(如 Whatsapp 或 Facebook)中看到的功能的建议,在这些应用程序中,您有一个列表和一个不总是可见的标题,但当用户开始时会逐渐显示从列表中的任何位置向上滚动。
在 whatsapp 和 facebook 中,向上滚动手势会导致搜索栏慢慢出现在屏幕顶部,而列表本身不会滚动,直到搜索栏完全出现(至少这是 android 实现)。
我需要关于如何使用带有 Telerik RadListView (android + ios) 的 Nativescript angular 来实现这一点的建议。据我所知,telerik 通常不建议将 ListView 放在 ScrollView 中。
谢谢!
编辑:我了解到它被称为视差效果,并在原生 android 中找到了它的示例,但是,在带有 ListView 的 nativescript 中没有找到它(确实找到了一个带有 ScrollView 和常规 StackLayout 的示例,而不是ListView 里面)。
【问题讨论】:
【参考方案1】:您可以在 NativeScript 市场官方网站的“示例”部分查看可用的“实现视差滚动效果”示例,该示例展示了如何实现该效果。只需转到Market.nativescript.org 并搜索“视差”。还有一个 plugin 提供了这样的功能,但我不确定它的质量。
【讨论】:
您好,感谢您的回复。我知道您所指的示例,这是我想到的那个:“确实找到了一个带有 ScrollView 和常规 StackLayout 的示例,而不是里面的 ListView”。它以非常简单的方式实现视差,然而,滚动部分是一个简单的 StackLayout,而不是 ListView。并且由于所有内容都包含在 ScrollView 中,因此无法以相同的方式实现,因为没有将 Listview 放入 ScrollView 的约束。 嗯,知道了。好吧,我还没有看到任何关于列表组件内视差效果的示例或讨论。您描述“始终不可见”的方式可能是在谈论“动态操作栏”而不是视差效果? 您好,我不确定确切的术语是什么,当您说“动态操作栏”时,您的意思是什么?我用谷歌搜索了它,但没有找到一个可以证明我要做什么的例子。我能给出的最好的例子是 SearchBar 在 android 上的 Whatsapp 和 Facebook 应用程序中隐藏和显示的方式,同时上下滚动列表。有些应用程序在发生这种情况时也有很好的动画效果,非常类似于视差示例,即在滚动底部布局时导致标题出现\缩小。 如果你在谈论这样的事情:androcode.es/wp-content/uploads/2015/10/simple_coordinator.gif,在来自“CoordinatorLayout”的 Android 上,我不确定 iOS 是否有类似的内置功能。在 NativeScript 中,CoordinatorLayout 不会被框架公开,但有人可以通过插件实现和公开它。 是的,非常相似,感谢您为我提供了正确的术语。我发现这个功能请求github.com/NativeScript/NativeScript/issues/4908 也谈到了它。【参考方案2】:这是一个使用 Angular 实现的可滚动视差效果 RadListView 的示例(不需要 ScrollView)。它还提供了将列表标题粘贴在顶部的示例。
请告诉我它是否适合你。
组件模板:
<GridLayout class="page">
<RadListView (scrolled)="onScroll($event)" [items]="dataItems" itemReorder="true"
(itemReordered)="onItemReordered($event)">
<ListViewGridLayout tkListViewLayout scrollDirection="Vertical" spanCount="1" ios:itemHeight="150"
dynamicItemSize="false"></ListViewGridLayout>
<ng-template tkListItemTemplate let-item="item">
<StackLayout orientation="vertical">
<!-- list item content goes here -->
</StackLayout>
</ng-template>
<ng-template tkListViewHeader>
<StackLayout>
<GridLayout #fixedHeaderContainer class="fixed-header-container">
<label text="Fixed Content" verticalAlignment="center"></label>
</GridLayout>
<StackLayout class="list-header-container">
<StackLayout #listHeaderContainer>
<label text="List Title"></label>
</StackLayout>
</StackLayout>
</StackLayout>
</ng-template>
</RadListView>
<GridLayout verticalAlignment="top" [height]="dockContainerHeight" [opacity]="dockContainerOpacity">
<FlexboxLayout justifyContent="flex-start" alignItems="center" class="docked-label-wrapper">
<button class="fas" text=""></button>
<StackLayout flexGrow="1" [opacity]="dockContentOpacity" orientation="horizontal">
<label text="List Title"></label>
</StackLayout>
</FlexboxLayout>
</GridLayout>
组件scss:
.fixed-header-container
height: 200;
padding: 0 16;
background-color: green;
label
font-size: 30;
font-weight: 700;
color: $white;
.list-header-container
margin-top: -12;
border-radius: 12 12 0 0;
background-color: #ffffff;
label
margin: 16 0;
font-size: 22;
color: black;
vertical-align: center;
.smaller-label
font-size: 12;
color: #909090;
RadListView
height: 100%;
background-color: #ffffff;
.docked-label-wrapper
margin: 0 0 10;
background-color: #ffffff;
.fas
margin: 0;
font-size: 18;
label
font-size: 18;
color: black;
vertical-align: center;
组件 ts:
import Component, ElementRef, OnInit, ViewChild from '@angular/core';
import ListViewEventData, ListViewScrollEventData from 'nativescript-ui-listview';
import DataItem, DataItemService from './data-items.service';
export const DOCK_HEADER_HEIGHT = 58;
@Component(
moduleId: module.id,
selector: 'app-comp-name',
templateUrl: './comp-name.component.html',
styleUrls: ['./comp-name.component.scss']
)
export class CompNameComponent implements OnInit
dataItems: DataItem[];
dockContainerHeight = DOCK_HEADER_HEIGHT;
dockContainerOpacity = 0;
dockContentOpacity = 0;
@ViewChild('fixedHeaderContainer', static: false )
fixedHeaderContainerRef: ElementRef;
@ViewChild('listHeaderContainer')
listHeaderContainerRef: ElementRef;
constructor(private _dataItemService: DataItemService)
ngOnInit(): void
this.dataItems = this._dataItemService.getDataItems();
onItemReordered(args: ListViewEventData)
console.log('Item reordered. Old index: ' + args.index + ' ' + 'new index: ' + args.data.targetIndex);
onScroll(args: ListViewScrollEventData)
if (!this.fixedHeaderContainerRef)
return;
const offset = args.scrollOffset < 0 ? 0 : args.scrollOffset;
const fixedHeaderHeight = this.fixedHeaderContainerRef.nativeElement.getActualSize().height;
this.applyFixedHeaderTransition(offset);
this.applyTitleTransition(offset, fixedHeaderHeight);
this.applyDockHeaderTransition(offset, fixedHeaderHeight);
private applyFixedHeaderTransition(scrollOffset: number)
this.fixedHeaderContainerRef.nativeElement.translateY = scrollOffset;
private applyTitleTransition(scrollOffset: number, fixedHeaderHeight: number)
const maxHeightChange = fixedHeaderHeight - DOCK_HEADER_HEIGHT;
const titleElement = this.listHeaderContainerRef.nativeElement;
if (maxHeightChange < scrollOffset)
titleElement.translateX = -(scrollOffset - maxHeightChange) / 1.2;
titleElement.translateY = -(scrollOffset - maxHeightChange) * 2;
titleElement.scaleX = 1 - (scrollOffset - maxHeightChange) / fixedHeaderHeight;
titleElement.scaleY = 1 - (scrollOffset - maxHeightChange) / fixedHeaderHeight;
else
titleElement.translateX = 0;
titleElement.translateY = 0;
titleElement.scaleX = 1;
titleElement.scaleY = 1;
private applyDockHeaderTransition(scrollOffset: number, fixedHeaderHeight: number)
const maxHeightChange = fixedHeaderHeight - DOCK_HEADER_HEIGHT;
const containerOpacity = 1 - scrollOffset / maxHeightChange;
this.dockContainerOpacity = containerOpacity <= 0 ? 1 : 0;
this.dockContentOpacity = (scrollOffset - (fixedHeaderHeight - DOCK_HEADER_HEIGHT)) / DOCK_HEADER_HEIGHT - 0.2;
【讨论】:
以上是关于Nativescript 在 ListView 中向上滚动时显示元素 - 视差效果的主要内容,如果未能解决你的问题,请参考以下文章
Nativescript 在 ListView 中向上滚动时显示元素 - 视差效果
水平 StackLayout 中的 ListView - Nativescript Vue
Nativescript-Vue:如何在 ListView 中正确使用 v-for
ListView 不在 ScrollView 和 StackLayout 内呈现,在 ios 中具有水平方向 - nativescript-vue