There is some difference in perfomance between using tap event on label and on button component.
Lets take for example this nativescript hello world app
https://github.com/NativeScript/template-hello-world
And especially this code
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">
<StackLayout>
<Label text="Tap the button" class="title"/>
<Button text="TAP" tap="{{ onTap }}" />
<Label text="{{ message }}" class="message" textWrap="true"/>
</StackLayout>
</Page>
When i am tapping fast on the button the UI is updated smoothly, but when i change the Button component with Label and try to tap fast there is some delay with updating the UI or some of the taps are not handled and the message property is not updated correctly.
I am using android (5.0) genymotion and real device (Android 6)
Nativescript: 2.2
The "problem" occurs in nativescript angular2 too.
You can give the tap event to the layout containers containing labels to increase the maximum touchable area.
<StackLayout (tap)="yourFunction()">
<Label text = "click event"></Label>
</StackLayout>
Related
Usually in Xamarin forms, only active elements like Button, ImageButton receives the focus but not the passive elements like layouts and label elements. However in case of ListView or CollectionView, the templated items gets focused during key navigation. Any idea how this is feasible? Could someone navigate to the source code usage regarding this implementation?
How does a ListView item gets focused in Xamarin forms UWP?
The UWP native ListView is allowed XYFocusKeyboardNavigation by default, so you could navigation with the keyboard arrow keys. And here is document that you could refer.
And if you want enable for the control that in the specific panel container, you could enable XYFocusKeyboardNavigation like the following in uwp
<StackPanel Name="ContainerSecondary"
XYFocusKeyboardNavigation="Enabled"
TabFocusNavigation ="Cycle"
Orientation="Horizontal"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
Unfortunately, Xamarin StackLayout does not contain such property, I have to say you may not implement in forms.
I'm loading a list of items, each with an URL reference for a thumbnail foreach item. When rendering the list using RadListView, I notice that each image is being loaded several times from the server. This only happens in iOS, in Android each thumbnail only loads once. The view however, is correct (no duplicates).
NativeScript version is 5.1.1
<StackLayout>
<SearchBar id="searchBar" hint="{{sbHint}}" text="{{sbText}}" clear="onClear" submit="onSubmit" />
<GridLayout rows="auto, *" class="list-group">
<lv:RadListView class="listview" items="{{itemList}}" pullToRefresh="true" pullToRefreshInitiated="onPullToRefreshInitiated" loaded="onListLoaded" itemTemplateSelector="selectItemTemplate" row="1">
<lv:RadListView.itemTemplates>
<template key="hasimg">
<GridLayout rows="auto" columns="70,*,auto" class="list-group-item" tap="select">
<Image row="0" col="0" src="{{imgurl}}" width="60" height="50" stretch="aspectFill"/>
<Label row="0" col="1" class="p-l-15 text" text="{{ name }}"/>
<Label class="p-l-15 fa" text="" row="0" col="2"/>
</GridLayout>
</template>
<template key="noimg">
<GridLayout rows="auto" columns="70,*,auto" class="list-group-item" tap="select">
<Label class="fa imgicon" text="" row="0" col="0"/>
<Label row="0" col="1" class="p-l-15 text" text="{{ name }}"/>
<Label class="p-l-15 fa" text="" row="0" col="2"/>
</GridLayout>
</template>
</lv:RadListView.itemTemplates>
</lv:RadListView>
<ActivityIndicator busy="{{ isLoading }}" row="1" horizontalAlignment="center" verticalAlignment="center"/>
</GridLayout>
</StackLayout>
Output from the API server on the same list load, using iOS and Android.
Using iOS (wrong):
GET /v4/item/file/display/1/ 404 Not Found
GET /v4/item/file/display/1/ 404 Not Found
GET /v4/item/file/display/2/ 404 Not Found
GET /v4/item/file/display/2/ 404 Not Found
GET /v4/item/file/display/1/ 404 Not Found
GET /v4/item/file/display/2/ 404 Not Found
GET /v4/item/file/display/1/ 404 Not Found
GET /v4/item/file/display/2/ 404 Not Found
POST /v4/item/list/ 200 OK
Using Android (correct):
GET /v4/item/file/display/1/ 404 Not Found
GET /v4/item/file/display/2/ 404 Not Found
POST /v4/item/list/ 200 OK
(in reversed order, please ignore the 404, I changed the path better to diff each call)
When using ListView, it reuses the item template as you scroll down / up. Let's say if you have 100 data items loaded on ListView, it would not create 100 View / Image components. It will probably create a few depending on the visible area of your screen, when you scroll up / down the same views will be reused for other data items to keep the performance up. This is the advantage of using ListView or RadListView.
Coming to why the Image was loaded multiple times, by default Android caches the image and uses it on subsequent requests. With iOS, it doesn't. So it hits the URL every time whenever it has to render the image while you scroll up / down.
The solution is to cache your images in temp storage. You could simply do it with http module and a bit of logical statements Or there are even several plugins you could find in the market place for this purpose, nativescript-web-image-cache or nativescript-image-cache-it are couple to name.
I see that Frame works now much better.
We can have Tabview,that is a root of current view.
<TabView androidTabsPosition="bottom">
<TabViewItem title="First">
<Frame defaultPage="home/home-page" />
</TabViewItem>
<TabViewItem title="Second">
<Frame defaultPage="second/second-page" />
</TabViewItem>
</TabView>
This looks like home-page or second-page is “included”.
Now, i’m wondering if it’s possible to have app-root.xml that holds common elements, and needed page is included. I’ve tried this, but this is not working (why? This approach is possible only for tabview and sidedrawer ?)
app-root.xml
<Page>
<Frame defaultPage="create/create"></Frame>
</Page>
create/create.xml
<StackLayout class="footer white">
<Label text="test"></Label>
</StackLayout>
Instead of Page use layout like GridLayout Look at this test application as a reference and more specifically this page
However, the above approach would work for Android but for iOS, you should either remove the action bar for each Page (inside each Frame) or create multiple action bars (not recommended!).
is there anyway to customize the search-bar element that NativeScript provides ?
and add some buttons in it.
am trying to get something like this (the search-bar in this app)
I've been searching a bit but found nothing about it.
Basic demo here: https://play.nativescript.org/?template=play-vue&id=y6iFw9
You can always hide default action bar with actionBarHidden="true on your <page> element and then create your own action bar. In this case you can use GridLayout and put each element in its own column. Something like:
<Page actionBarHidden="true>
<StackLayout>
<GridLayout rows="auto columns="auto, *, auto, auto, auto>
<Label col="0 text="Menu"/>
<TextField col="1></TextField>
<Label col="2 text="icon1"/>
<Label col="3 text="icon2"/>
<Label col="4 text="icon3"/>
</GridLayout>
</StackLayout>
</Page>
Just replace labels with your icons, and add #tap="yourFunction to fire when icon is pressed. To turn labels into icons you can use package like Fonticon.
The search-bar from tns-core-modules doesn't provide what you're looking for (see the API at https://docs.nativescript.org/api-reference/modules/_ui_search_bar_). I'd recommend to implement the component yourself.
I have this code in main-page.xml:
<GridLayout rows="auto, *">
<Label text="Title" class="title" row="0" />
<ListView id="listView" items="{{ listItems }}" row="1">
<ListView.itemTemplate>
<StackLayout>
<Button text="{{ name }}" tap="dd" />
</StackLayout>
</ListView.itemTemplate>
</ListView>
</GridLayout>
When I scroll the title stick to the top (stay and don't move), is there is a way to make it behave normally ?
I found a cleaner solution using : https://docs.nativescript.org/cookbook/ui/repeater
<ScrollView>
<StackLayout>
<Label text="Title" class="title" />
<Repeater id="listItems" items="{{ listItems }}">
<Repeater.itemTemplate>
<StackLayout>
<Button text="{{ name }}" tap="loadGuide" />
</StackLayout>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
This is definitely the expected behavior when placing a Label at a row of a GridLayout which is set to auto. What you want to achieve can be done but will require additional implementations for example like this (No boring ActionBar) third party Android library. What you can do is either implement the same using pure JavaScript/TypeScript directly in your app (by managing the size of the ActionBar) or create a custom NativeScript plugin that uses the mentioned android library.
One of the many beauties of NativeScript is that 100% of the native iOS and Android APIs are accessible meaning anything that is achievable in an native iOS or Android app is achievable in {N}.