I want to include a scrollToId() method in my ts.
fiche.html :
<ScrollView id="myScroller">
<FlexboxLayout (tap)="scrollToId('google-map')">
.....
</FlexboxLayout>
<FlexboxLayout (tap)="scrollToId('horaire')">
....
</FlexboxLayout>
<StackLayout id="horaire">
....
</StackLayout>
<GridLayout id="google-map">
...
</GridLayout>
</ScrollView>
fiche.ts :
public scrollToId(id: string) {
if (this.scrollLayout == null) {
this.scrollLayout = this.page.getViewById("myScroller");
}
let focus = this.page.getViewById(id);
this.scrollLayout.scrollToVerticalOffset(focus.verticalOffset, false);
}
All is ok on IOS but on Android, no scroll to StackLayout or GridLayout.
Any help on this?
@Neferteus neither StackLayout nor GridKLayout have verticalOffset property.
However you can use methods like getLocationRelativeTo or getLocationOnScreen / getLocationOnWindow or even getMeasuredHeight to calculate and scroll to the desired position.
e.g.
page.component.html
<ScrollView #myScroller>
<StackLayout>
<Button #btn text="scrollTo" (tap)="scrollTo()"></Button>
<StackLayout>
<Image src="res://logo"></Image>
<Image src="res://icon"></Image>
<Image src="res://logo"></Image>
<Image src="res://icon"></Image>
</StackLayout>
<GridLayout #grid width="200" height="200" backgroundColor="green">
</GridLayout>
</StackLayout>
</ScrollView>
_page.component.ts_
export class AppComponent implements OnInit {
@ViewChild("myScroller") sv: ElementRef;
@ViewChild("btn") btn: ElementRef;
@ViewChild("grid") gr: ElementRef;
scrollLayout: ScrollView;
button: Button;
grid: GridLayout;
ngOnInit() {
this.scrollLayout = this.sv.nativeElement;
this.button = this.btn.nativeElement;
this.grid = this.gr.nativeElement;
}
public scrollTo() {
this.scrollLayout.scrollToVerticalOffset(this.grid.getLocationRelativeTo(this.button).y, false);
}
}
Thanks it's worked.
It's been a while, just wanted to say that with NativeScript / Angular 4, Nick's method is still valid. I'm currently using it on an iOS application, and I can't complain!
Note:
To scroll a full screen's length (or width for that matter), it is possible to use the screen.mainScreen.heightPixels var from @tns-core-modules/platform.
Made my life a bit easier. Cheers
I am developing an app where when user click on cardview layout, detail of that view is opened on that card view layout. I have used nativescript ScrollView for scrolling the views. But, when user click on last cardview layout it should scroll to show detail of cardview layout. It does not automatically scrolls to the last card view detail, due to this the detail of the card view is hidden and user have to scroll manually.
I found this https://stackoverflow.com/questions/51181694/nativescript-scroll-to-bottom-of-scrollview-programmatically but i am not able to solve my problem. Below is my code for layout.
`
<StackLayout row="0" col="0">
<StackLayout *ngFor="let item of items" class="card-view" id="cardViewLayout">
<GridLayout columns="auto, *, auto" rows="auto,auto,auto" (tap)="toggleDetail(@event)">
</GridLayout>
<GridLayout row="3" col="0" colSpan="3" columns=" *, *" rows="auto,auto" id="detailedData" visibility="hidden" class="cardDetail">
<StackLayout row="0" col="0" class="detailDataStack">
</StackLayout>
</GridLayout>
</StackLayout>
</StackLayout>
</ScrollView>
`
toggleDetail(args){
var scrollView = this.page.getViewById("scrollView")
var offset = this.scrollView.nativeElement.scrollableHeight;
this.scrollView.nativeElement.scrollToVerticalOffset( this.scrollView.nativeElement.offset+ 120, false);
}
As shown in above when user click on card-view class layout, it is toggling cardDetail class. When there is last item in card-view it should scroll automatically to show the details but it don't automatically scrolls.
In toggleDetail() method i tried to get scrollableHeight, add 120 to that height and make it scroll when user in last item but nothing happened.
Thank you in advance :)
I am developing an app where when user click on cardview layout, detail of that view is opened on that card view layout. I have used nativescript ScrollView for scrolling the views. But, when user click on last cardview layout it should scroll to show detail of cardview layout. It does not automatically scrolls to the last card view detail, due to this the detail of the card view is hidden and user have to scroll manually.
I found this https://stackoverflow.com/questions/51181694/nativescript-scroll-to-bottom-of-scrollview-programmatically but i am not able to solve my problem. Below is my code for layout.
`
<StackLayout row="0" col="0"> <StackLayout *ngFor="let item of items" class="card-view" id="cardViewLayout"> <GridLayout columns="auto, *, auto" rows="auto,auto,auto" (tap)="toggleDetail(@event)"> </GridLayout> <GridLayout row="3" col="0" colSpan="3" columns=" *, *" rows="auto,auto" id="detailedData" visibility="hidden" class="cardDetail"> <StackLayout row="0" col="0" class="detailDataStack"> </StackLayout> </GridLayout> </StackLayout> </StackLayout> </ScrollView>`
toggleDetail(args){ var scrollView = this.page.getViewById("scrollView") var offset = this.scrollView.nativeElement.scrollableHeight; this.scrollView.nativeElement.scrollToVerticalOffset( this.scrollView.nativeElement.offset+ 120, false); }As shown in above when user click on card-view class layout, it is toggling cardDetail class. When there is last item in card-view it should scroll automatically to show the details but it don't automatically scrolls.
In toggleDetail() method i tried to get scrollableHeight, add 120 to that height and make it scroll when user in last item but nothing happened.
Thank you in advance :)
You will need to keep track of "where you are" regarding pixels.
I know that it is possible through ScrollView to manually set the location of the scroll. So, you can wire up a button to scroll to the next "segment" (whatever you make it) and add the width/height of that scroll to the current location. Then scroll to that new location. Same would work with going backwards, just decrement the adjustment.
If you're still having problems, let me know and I'll get an example written out for you. I ended up making a custom component to handle the custom scroller.
Thank you @mster :) . I will try as you said and let you know about it. Thank you.
@mster I tried as you said but unable to achieve scroll. I have made playground demo app for this . Can you please check it and provide some solution on this. Thank you
Playground Demo app
https://play.nativescript.org/?template=play-ng&id=Y2ZJLs&v=17
As shown in demo if user is on record and tap on card-view to view detail , the detail data is hidden , it need to be scrolled.
@vishwa1937 No problemo! This was a problem I worked with for a bit.
This gist should give you some clarification:
https://gist.github.com/mster/c1c715d2af64ac4b5ff5c0e18b50de29
I'm using NativeScript with Angular 2+, however the same idea can be done with Angular.js
As far as I am concerned, the secret sauce is:
this.scrollerView.scrollToVerticalOffset(pixels, true)
// or
this.scrollerView.scrollToHorizontalOffset(pixels, true)
// second param (bool) represents scroll-to animation
Edit:
The functionality needs to built, then you will be able to invoke the scroll from anywhere (as long as you import properly).
I am currently trying scroll to the bottom of a ListView of items in a ScrollView. The goal is to create something that mimics a messenger app and to do that I want the user to start from the bottom of the ScrollView. None of the options listed here have done anything to the scroll view and it remains stuck at the top as always.
<StackLayout>
<Label
height="6%"
[text]="recipientName"
class="blockTitle p-b-8"
textWrap="true">
</Label>
<ScrollView
#messageScroll
height="84%">
<ListView
minHeight="100%"
height="100%"
style="padding: 5px"
[items]="messages"
class="list"
>
<ng-template
let-item="item"
>
<GridLayout
columns="*"
rows="auto"
class="message"
>
<StackLayout
[class]="fromClass(item.creator_person_id)"
orientation="horizontal"
[horizontalAlignment]="align(item.creator_person_id)"
>
<Label
class="authorimg fas fa fa-user"
stretch="aspectFill"
height="30"
width="30"
verticalAlignment="top"
>
</Label>
<Label
[text]="item.message_text"
class="msg_text"
textWrap="true"
verticalAlignment="top">
</Label>
</StackLayout>
</GridLayout>
</ng-template>
</RadListView>
</ScrollView>
<StackLayout height="10%">
<GridLayout
columns="*,auto"
style="padding: 10px"
>
<TextField
hint="Type message here"
row="0"
col="0"
ngDefaultControl
(submit)="chat()"
[(ngModel)]="message"
>
</TextField>
<Button
row="0"
col="1"
text="send"
(tap)="chat()"
>
</Button>
</GridLayout>
</StackLayout>
</StackLayout>
Relevant Scroll to Code.
@ViewChild('messageScroll', { static: true, read: ElementRef }) messageScroll: ElementRef<ScrollView>
scrollLayout: ScrollView
ngOnInit () {
this.scrollLayout = this.messageScroll.nativeElement
setTimeout(() => {
this.scrollTo(platform.screen.mainScreen.heightPixels)
}, 1000)
}
scrollTo (offset: number) {
this.scrollLayout.scrollToVerticalOffset(offset, false)
}
I have tried numerous solutions in this thread an so far none have changed anything on the page itself..
@mmerbes have you tried initializing the component with the starting position set to the bottom?
@mster I'm open to learning how to do that. I can't find anything in the nativescript documentation about setting a components starting position.
Most helpful comment
@Neferteus neither StackLayout nor GridKLayout have verticalOffset property.
However you can use methods like getLocationRelativeTo or getLocationOnScreen / getLocationOnWindow or even getMeasuredHeight to calculate and scroll to the desired position.
e.g.
page.component.html
_page.component.ts_