NativeScript virtualScroll in huge list - nativescript

Beforehand I was using Ionic for my cross platform apps. When using Angular repeat, there was performance and memory issues in huge lists.
But ionic has a feature called virtualRepeat (or collection-repeat in v1.x). But it has lots of bugs and is not usable.
Is there such a feature in NativeScript? (It must not keep all elements alive in the list, and as user scroll change the list.) The same feature is available in React Native.
Also I took a screenshot video for performance demonstration. At first I have 20 items. Then for load more in scroll, I load a very huge list . Then, see the result:
https://www.youtube.com/watch?v=220FS2SqLqI

In Nativescript you will want to use ListView and not ngFor or other repeating techniques, Listview reuses view and reducing memory usage for big lists
Example
<ListView [items]="myItems">
<template let-item="item">
<StackLayout>
<Label [text]='item.name'></Label>
</StackLayout>
</template>
</ListView>
Link with docs/more examples:
https://docs.nativescript.org/angular/ui/list-view.html

Finally I found out, it uses virtulization. I ran this command:
tns debug android
Then I could be able to see the elements from chrome dev tools:
It uses only a few elements and while scrolling changes them.

Related

Since RelativeLayeout is not recommended to use in .Net Maui, what techniques would replace it?

I used Factor of RelativeLayout in Xamarin.Forms a lot, this way my app UI scaled properly on any device. RelativeLayout is not recommended for use anymore and no replacement offered, so I wonder what would be techniques to indicate for example I want the xaml element to occupy 80% of it's parent element (container)? Should I calculate real width/height of the container in the runtime, depending on the device resolution? Or there is a better solution? I just can find nothing close in .Net Maui to what RelativeLayout+Factor allowed me to do in Xamarin.Forms.
I fear right now there is no way except Creating your own derivate of a Relative Layout. I've got the same problem of converting a Xamarin App to MAUI. There we did use a relative Layout to display various machines at their respective positions inside a building.
I found a few examples on how to create a custom layout here.
I would not recommend using the compatibility namespace. For me it makes problems and upon activating it, some of my page content is no longer displayed.
Hope this helps at least a little.
One option is to use the Grid layout with ColumnDefinitions="*,8*,*".
Place the content in Column 1.
AbsoluteLayout and RelativeLayout now exist only in the compatibility namespace, you can update your code to use them by adding the new namespace, and prefixing your XAML references:
<ContentPage
xmlns:cmp="clr-namespace:Microsoft.Maui.Controls.Compatibility;assembly=Microsoft.Maui.Controls"
...
>
<cmp:AbsoluteLayout>
<BoxView
Color="Red"
cmp:RelativeLayout.XConstraint="{cmp:ConstraintExpression Type=Constant, Constant=0}"
cmp:RelativeLayout.YConstraint="{cmp:ConstraintExpression Type=Constant, Constant=0}" />
</cmp:AbsoluteLayout>
</ContentPage>

Xamarin Forms: Footer image is not displaying fully

In my login UI, I have a footer image, which is showing perfectly in small devices. But on big screen devices (mainly on iPad) it is not showing fully.
I tried all Aspect property of Image, but not worked.
Screenshot:
I try a lot to fix this but didn't get a solution.
Attaching the LoginPage.xaml file with this question. Please suggest a solution for this issue. :)
Make sure (in the iOS project -> Assets) your image set has 3 different sizes xxx.png,xxx.png#2x and xxx.png#3x .
Which image will be used for your app? That depends on the device your app is viewed on. Higher resolution devices (larger and newer devices) have more pixels on their screens. Thus they need higher resolution images to display properly without any blurring.
If you don’t supply the higher resolution (#2x or #3x) images, your app will automatically try to scale the #1x image up. This is not good and can result in a distorted or blurry image!
Based on the file you linked in the comments, I think it would suffice to remove the bottom StackLayout wrapping the Image, and instead put Grid.Row="1" & VerticalOptions="End" to the bottom Image.
Please update your question with the relevant code to make the question and answers more helpful to others.
Remove latest StackLayout with image and add it after StackLayout with Grid.Row="1" like this
<Grid Grid.Row="1"
BackgroundColor="#c0eefb">
<Image
Source="ic_footer_image_xx.png"
Aspect="AspectFill"
HorizontalOptions="FillAndExpand"/>
</Grid>

NativeScript-Vue rendering RadListView very slow under android and freeze the UI

I have a nativescript-vue app with the RadListView component to display data to the user. Each row of the list include multiple informations for the current item. When i tap on a button to load and show the list the UI freeze (fast hardware -> short; slow hardware -> long). I figured out that the code part to load/combine the data run very short but the nativescript-internal rendering or creation of the UI elements are the problem. The android console show the information
I/Choreographer: Skipped 430 frames! The application may be doing too much work on its main thread.
Platform info:
tns-ios 5.2.0
tns-android 5.2.1
nativescript-ui-listview 6.2.0
tns-core-modules 5.3.1
Similar problem reports
I look at stackoverflow and github but the problems there (e.g. NativeScript Angular RadListView rendering extremely slowly) looks similar but the solutions not suitable for me.
I use the LinearListView (not Grid nor Stagged) and maybe in my real app i will be able to simplify the row elements from the list but in my sample app (look down) i use a simple row ui design.
Sample app
For a simpler and better report i created a sample app on the {N}-Playground. The app creates 10000 array elements and set them as source of the RadListView which has a Label, a Switch and an ActivityIndicator for every element.
<RadListView ref="listView"
for="alarm in alarms"
layout="linear">
<v-template>
<StackLayout class="list-element" orientation="vertical" >
<GridLayout columns="*, auto, auto" rows="*">
<Label col="0" row="0">{{alarm.name}}</Label>
<Switch col="1" row="0" :checked="alarm.active" />
<ActivityIndicator col="2" row="0" :busy="alarm.active"/>
</GridLayout>
<Label class="list-element-divider"></Label>
</StackLayout>
</v-template>
</RadListView>
In the first step the 10000 elements will be generated in a temporary array:
loadData() {
this.tmpAlarms = [];
for (let i = 0; i <= 10000; i++) {
this.tmpAlarms.push({
name: "Hase " + i,
active: i % 2 === 0,
});
}
}
With a second button set the temporary array as source:
setData() {
this.alarms = this.tmpAlarms;
}
Note: I use 10000 elements to make the problem visible even the sample app runs on a S9 or another high end smartphone.
The full source is runnable under https://play.nativescript.org/?template=play-vue&id=Td1GWR
A slightly different version with an ObservableArray instead of a plain array is under https://play.nativescript.org/?template=play-vue&id=5BXOFG
In both versions the data handling is fast but as soon the UI elements generated from the internal functions the UI will be frozen.
Sample: On my Nexus 7 2013 with Android 6.x the UI freeze nearly 6 seconds and no other apps running in background.
iOS
If i try the same apps on an iOS device (e.g. iPhone 7s) the rendering is very fast and the UI running smooth even so with the 10000 elements and more.
Ideas?
Have anyone an idea how i can speed up the rendering? If not is there a suggestion how i can build an animation (e.g. ActivityIndicator) to show the user that the device is working? At the moment when i put an ActivityIndicator on the UI the user can not see it because of the frozen UI.
Android and IOS have a very different way of rendering the ui. This difference added to particularity of the Rad list can affect performance. Note that the rad list reuse the instance of the list element to improve performance. This reuse is not done the same way in IOS and in Android.
There are two simple optimizations that can improve a lot the rendering in ios and android.
The first one is to reduce the layouts in layouts. It is easier for the rendering if there are less elements. This reduce the depth/passes rendering
<RadListView ref="listView" for="alarm in alarms" layout="linear">
<v-template>
<GridLayout class="list-element" columns="*, auto, auto" rows="*, auto">
<Label col="0" row="0">{{alarm.name}}</Label>
<Switch col="1" row="0" :checked="alarm.active" />
<ActivityIndicator col="2" row="0" :busy="alarm.active"/>
<Label colSpan="3" row="1" class="list-element-divider"></Label>
</GridLayout>
</v-template>
</RadListView>
The second is the one that have the most impact. Set an height to component when possible. Here the use of *,auto,auto will means that it will have to recalculate for each elements of the list. And here is where IOS and Android differs.
IOS will re render only what is required in the element. This means that the stack layout and the grid layout will stay the same when the element is recycled but if the content of the grid layout would be bigger in lower elements, the rendering on IOS may be all wrong the more you scroll. This is really faster because no need to adjust the height each time. But can be bad if size need to change.
Android tends recycle but to rerender all the components and therefore recalculate for each. This is slower but safer for size change.
In general, setting and height will boost the performance of the app because there are less inference form the rendering engine that need to be done. This is true everywhere in your app but really important in rad list.

Creating Custom label background in Xamarin Forms

I am developing in Xamarin forms, and I have a Label that can contain a varying amount of text.
The platforms I use in forms are primarily: Android and UWP (no need for iOS ATM).
I want to give this label a background that is not rectangular and that is something more like this: (chat/message bubble style)
I have read about some possible solutions but I'm confused from all the options that are available.
From what I understand of my research around this and from my work with other platforms there are basically two options:
Set an image background.
Use Custom graphic controls to create the shape I want.
I'm not sure how to implement any of these options in Xamarin Forms, I'll be glad to get some help.
The easy solution would be to host the Label inside a View and set have an Image behind the label:
<Grid>
<Image Source="message_background.png">
<Label Text="{Binding Message}">
</Grid>
This is not very performant if you're going to have a lot of these on screen. The best solution would then be to use a custom renderer for each platform an implement it natively. This would give much better performance much more flexibility. It's more maintenance and initial work though.
You can read up on custom renderers here

Scaled Pixels for FontSizes in Xamarin.Forms

I have problems with my font sizes on big screens.
By default, my label looks perfect on my small android phone.
<Label HorizontalTextAlignment="Center"
Text="Lobby"
FontSize="16" />
When I switch to my Amazon Fire Tablet, the label is very, very tiny. Almost everything is too tiny.
I have read, there is a unit "sp" for Android projects. Is there a built in way to do it in Xamarin.Forms? Are there libraries that could help me with that?
I already took a look at:
Resolution-dependent font size in Xamarin. Unfortunately I am using Xamarin.Forms.
Thanks in advance!
You can use the NamedSize enum for font sizes.
The available ones are :
Micro
Small
Medium
Large
Eg:
<Label Text="Login" FontSize="Large"/>
<Label Text="Instructions" FontSize="Small"/>
Try use Device.Idiom if you are using PCL. Depend of type of device, you can add a different image size.
https://developer.xamarin.com/api/type/Xamarin.Forms.Device/
https://developer.xamarin.com/api/property/Xamarin.Forms.Device.Idiom/
And this extended guide - https://developer.xamarin.com/guides/android/application_fundamentals/resources_in_android/part_4_-_creating_resources_for_varying_screens/

Resources