How to fix android ui performance - nativescript

I'm getting:
Avoid using ListView or ScrollView with no explicit height set inside StackLayout. Doing so might results in poor user interface performance and a poor user experience.
My UI performance is very crappy on Android. It seems pretty smooth on iOS. I'm trying to figure out what could be the issue. This one error crops up for me. I'm running "nativescript-angular": "^8.0.0",
<ScrollView [visibility]="isBusy ? 'collapsed' : 'visible'" #sv>
<GridLayout rows="auto,auto,auto,auto" id="t2" columns="*" class="template_body">
<GridLayout row="0" col="0" #wv1wrapper>
<!-- <web-view id="instruction-wv" #wv1></web-view> -->
<template-text [data]="lessonDetail.instruction" *ngIf="lessonDetail.instruction" [screenwidth]="screenWidth"></template-text>
</GridLayout>
<StackLayout row="1" col="0" class="main-img">
<Image [src]="(lesson$ | async)?.thumbUrl" #imgref [data-image]="(lesson$ | async)?.imageUrl" (tap)="modalImage($event);"></Image>
</StackLayout>
<GridLayout row="2" col="0" #wvwrapper>
<!-- <web-view id="wv" #wv></web-view> -->
<template-text [data]="lessonDetail.body_text" [version]="version" *ngIf="lessonDetail.body_text" [screenwidth]="screenWidth"></template-text>
</GridLayout>
</GridLayout>
This is a template that is pulled into a router-outlet that looks like this in the master template:
<FlexboxLayout class="contentbody" [visibility]="isBusy ? 'hidden' : 'visible'" [data-template]="template_id">
<Label [text]="error" *ngIf="error"></Label>
<router-outlet></router-outlet>
</FlexboxLayout>
Also on that page, I do have a listview inside of a stacklayout.
<StackLayout row="0" >
<StackLayout class="vocab-notes">
<Label *ngIf="vocabArray" class="h3 section-title" text="Vocabulary"></Label>
<ListView [items]="vocabArray" id="vocablistview" (itemTap)="onItemTap($event)" class="list-items">
<ng-template let-item="item" let-i="index" let-odd="odd" let-even="even">
<GridLayout columns="*" rows="auto,auto" [class.odd]="odd" [class.even]="even" class="vocab-list">
<FlexboxLayout col="0" row="0" class="vocab-list-item-layout">
<Label [text]='item.label' textWrap="true" [id]="item.id" class="h3 vocab-list-item" (tap)="showVocab($event)"></Label>
</FlexboxLayout>
</GridLayout>
</ng-template>
</ListView>
</StackLayout>

I know its late for you but if someone is looking for this in future, so if you are getting below in console on any page you load.
JS: Avoid using ListView or ScrollView with no explicit height set inside StackLayout. Doing so might results in poor user interface performance and a poor user experience.
You just need to give your scrollView a height, try different heights like in my case I need 650
<Page class="main" actionBarHidden="true">
<StackLayout class="gradient-bg">
<ScrollView orientation="vertical" height="650"> <!-- Here height is 650 -->
<StackLayout>
<GridLayout rows="50" class="page-header">
<Label
row="0"
class="fa label-back"
:text="'fa-arrow-left' | fonticon"
v-on:tap="navigateTo('app')"
/>
<Label text="Plot Suggestion" row="0" class="lbl-heading" horizontalAlignment="center" />
...
...

Related

nativescript bottom nav that stays in place after loading new view

I'm developing some app made on nativescript. Recently, i see that my app is more like website not an app, beacuse of how navigation works.
I'm having bottom nav (atached - this grey with 5 icons) that is used to load proper views.
But when i click on home or any other icon, new view is loaded, but also nav is 'reloaded'. So it will not stay in place but load with new view. My question is - is possible oto have static botom bar ? I've tried 2 plugins found on marketplace, but without success. Thanks for and help.
<Page class="page" loaded="loaded" xmlns:header="components/header" xmlns:footer="components/footer">
<GridLayout rows="120,*,60">
<StackLayout row="0">
<!-- Common header -->
<header:header/>
</StackLayout>
<ScrollView row="1" verticalAlignment="top" class="scrollview" tap="{{ loadPage }}">
<StackLayout class="redeem">
<Label text="Enter your code below to redeem your reward" class="info" textWrap="true"></Label>
<Label text="Code" class="info code" textWrap="true"></Label>
<TextField />
<Button text="Redeem" class="button blue"></Button>
</StackLayout>
</ScrollView>
<StackLayout row="2">
<!-- Common footer -->
<footer:footer/>
</StackLayout>
</GridLayout>
</Page>
:
<AbsoluteLayout class="footer" loaded="menu" horizontalAlignment="center" xmlns:sd="nativescript-ui-sidedrawer">
<GridLayout rows="auto" columns="*,*,*,*,*" horizontalAlignment="center">
<Label row="0" col="0" class="fa" text="" tap="{{ mainPage }}"></Label>
<Label row="0" col="1" class="fa" text="" tap="{{ creditPage }}"></Label>
<Label row="0" col="2" class="fa" text="" tap="{{ seatPage }}"></Label>
<Label row="0" col="3" class="fa" text="" tap="{{ refs }}"></Label>
<Label id="openMenu" row="0" col="4" class="fa" text="" tap="toggleDrawer"></Label>
<!--<Label id="openMenu" row="0" col="4" class="fa" text="" tap="{{ loadPage }}"></Label>-->
</GridLayout>
</AbsoluteLayout>
You could use DockLayout and dock the content to the bottom (Angular example here)
Also in the upcoming release 4.0.0 of NativeScript (expected April-2018) will provide support for different root views (apart from Page) meaning you could create bottom static layout like GridLayout or even better a bottom TabView (also coming for Android in 4.0.0) and create Frame in the upper layout for your dynamic content. (Look here)

Nativescript inner StackLayout

Hello everyone I'm trying to make inner StackLayouts but the second one comes to top of first one so that I can't see the second StackLayout should I handle with css if it is how or is there an other way
Here is my code
<StackLayout orientation="horizontal">
<StackLayout width="500">
<GridLayout columns="50, *" rows="*" width="500" height="50"
verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
</StackLayout>
<StackLayout orientation="horizontal" width="500" height="180">
<Image src="http://lorempixel.com/400/200" width="500" left="10"
top="30">
</Image>
</StackLayout>
</StackLayout>
Thank you
At first I would delete the widths to see how the page is displayed. 500 is a very big value. Only large tablets can support that.
As an example at first I would try this :
<GridLayout columns="auto, auto">
<GridLayout col="0" columns="50, *" rows="*" verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
<Image col="1" src="http://lorempixel.com/400/200" left="10" op="30">
</Image>
</GridLayout>
After you see the two parts align horizontally you can start tweaking the widths

center image in nativescript

After I try NativeScript tutorial "Grocery", I found out that its button quite hard to tap it's because tap area is too small, so I want to increase Image hight by update layout file to the following below. However, image not seem to be in the center (Image Below).
How can I achieve this in NativeScript ?
list.html
<ActionBar title="Groceries">
<ActionItem text="Share" (tap)="share()"
android.systemIcon="ic_menu_share_holo_dark"
ios.systemIcon="9" ios.position="right"></ActionItem>
</ActionBar>
<GridLayout rows="auto, *">
<GridLayout row="0" columns="*, auto" class="add-bar">
<TextField #groceryTextField [(ngModel)]="grocery" hint="Enter a grocery item" col="0"></TextField>
<StackLayout class="delete-container" height="100%" (tap)="add()" col="1" >
<Image src="res://add" stretch="none" horizontalAlignment="center"></Image>
</StackLayout>
</GridLayout>
<ListView [items]="groceryList" row="1" class="small-spacing" [class.visible]="listLoaded">
<ng-template let-item="item">
<GridLayout columns="*, auto">
<Label col="0" [text]="item.name" class="medium-spacing"></Label>
<StackLayout col="1" class="delete-container" height="100%" (tap)="delete(item)">
<Image src="res://delete"></Image>
</StackLayout>
</GridLayout>
</ng-template>
</ListView>
<ActivityIndicator
[busy]="isLoading" [visibility]="isLoading ? 'visible' : 'collapse'"
row="1" horizontalAlignment="center" verticalAlignment="center"></ActivityIndicator>
</GridLayout>
You should check out NS's FlexBox layout.
It is quite useful:
http://docs.nativescript.org/cookbook/ui/layouts/flexbox-layout

nativescript 'this' inside tkListViewHeader (RadListView header directive)

I'm using the TKListViewHeaderDirective of teleriks RadListView in nativescript like so:
<GridLayout columns="*" rows="*" tkToggleNavButton>
<RadListView *ngIf="!loading" row="3" col="0" [items]="nodes" ...>
<ng-template tkListItemTemplate let-node="item">
<!-- list item -->
</ng-template>
<ng-template tkListViewHeader>
<GridLayout columns="*" rows="auto, auto, auto">
<GridLayout row="0" col="0" columns="40,*,40">
<Button class="fa action-item" row="0" col="0" [text]="'fa-sort-amount-asc' | fonticon" ios.position="right" android="actionBar" style="background-color:#c9c9ce;;"></Button>
<SearchBar row="0" col="1" #searchInput hint="Search" (submit)="search(searchInput.text)" (clear)="search('')" (textChange)="search(searchInput.text)"></SearchBar>
<Button class="fa action-item" row="0" col="2" [text]="'fa-th' | fonticon" ios.position="right" android="actionBar" style="background-color:#c9c9ce;"></Button>
</GridLayout>
<StackLayout row="1" col="0">
<Label text="Hello world"></Label>
<Label [text]="currentNode.name"></Label>
<Label [text]="nodes?.length ? nodes.length : 0"></Label>
</StackLayout>
<StackLayout row="2" col="0" *ngIf="!nodes?.length" class="list-group">
<!-- some contents -->
</StackLayout>
<StackLayout row="3" col="0" *ngIf="currentNode?.name !== '/'" class="list-group">
<!-- some contents -->
</StackLayout>
</GridLayout>
</ng-template>
</RadListView>
</GridLayout>
it seems like two things go wrong here:
this seems to be missing here (the *ngIf should show one of the StackLayouts in specific cases but does not
The GridLayout (does not have any effect if I change it to StackLayout) inside the list header shows only one child element
According to the docs: http://docs.telerik.com/devtools/nativescript-ui/Controls/Angular/ListView/header-footer
There is an issue on github concerning this: https://github.com/telerik/nativescript-ui-feedback/issues/207

Get a TextView to scroll

I've got a TextView inside a GridLayout and have it set to take maximum available height. That works.
But If the user presses new-line to the bottom of the TextView and more - the TextView cursor goes off the bottom of the screen instead of scrolling the TextView.
How can I get the TextView to scroll.
In iOS the TextView should be scrollable by default if you set large text in it.
However for Android you could use ScrollView and to use StackLayout for main container inside it. For further help you could review the below attached example:
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<GridLayout columns="*" rows="auto,*">
<GridLayout row="0" col="0" columns="auto,*" rows="auto">
<Label text="header" row="0" col="0" />
</GridLayout>
<GridLayout row="1" col="0" columns="auto,*" rows="auto">
<Label text="Note" row="0" col="0" />
<ScrollView orientation="vertical" row="1" col="0" height="300" width="300" backgroundColor="green">
<StackLayout orientation="vertical" class="scroll-menu" backgroundColor="red">
<TextView text="" hint="Enter text..." />
</StackLayout>
</ScrollView>
</GridLayout>
</GridLayout>
</Page>

Resources