nativescript-ui-feedback icon indicating copy to clipboard operation
nativescript-ui-feedback copied to clipboard

RadListView image display bug in IOS

Open tsonevn opened this issue 6 years ago • 16 comments

From @peppeg85 on September 21, 2018 14:44

hello, i read yet other topics about this "bug", like this: https://www.telerik.com/forums/radlistview-image-display-bug-in-ios or this: https://www.telerik.com/forums/image-from-url-not-showing-initially-in-radlistview i understand the problem, but i still am not able to fix it. i load images of a listview dynamically and after the http request i set the pagedata with the images, the listview is the following:

            <GridLayout columns="*" rows="*,41">
                <GridLayout row="0">
                    <lv:RadListView items="{{ homeArray }}" itemTap="homeTapped">
                        <lv:RadListView.listViewLayout>
                            <lv:ListViewGridLayout scrollDirection="Vertical" itemHeight="210" spanCount="2"/>
                        </lv:RadListView.listViewLayout>
                        <lv:RadListView.itemTemplate itemHeight="210">
                            <StackLayout class="home-container" orientation="horizontal"
                                         horizontalAlignment="center"
                                         webUrl="{{ webUrl }}">
                                <StackLayout class="innerHomeImg" verticalAlignment="middle" orientation="horizontal">
                                    <GridLayout rows="210" class="grid-fonts">
                                        <Image class="brand-img" src="{{ pictureUrl }}"
                                               horizontalAlignment="center"/>
                                    </GridLayout>
                                </StackLayout>
                            </StackLayout>
                        </lv:RadListView.itemTemplate>
                    </lv:RadListView>
                </GridLayout>
                <StackLayout row="1" class="phoneStackLayout" orientation="vertical" tap="phone">
                    <Image class="phoneBtn" src="res://icphonewhite24dp"
                           horizontalAlignment="center"/>
                </StackLayout>
            </GridLayout>

and another listview "loses" elements after scroll (element previously loaded disappear) what i could try?thanks in advance

Copied from original issue: NativeScript/NativeScript#6291

tsonevn avatar Sep 21 '18 14:09 tsonevn

Hi @peppeg85 We reviewed the provided info, however, it is not enough to investigate further the case. Can you send us the project or at least the code, which shows how you are creating the HTTP request and how you are loading the data in the RadListView?

tsonevn avatar Sep 24 '18 07:09 tsonevn

hello, thank you for your support, here is the home page code:

var frameModule = require("ui/frame");
const utilityModule = require('utils/utils');
var Observable = require("tns-core-modules/data/observable").Observable;
var http = require("http");
const global = require('../../shared/globals');
var pageData = new Observable();
const platformModule = require("tns-core-modules/platform");
var LoadingIndicator = require("nativescript-loading-indicator").LoadingIndicator;
var loader = new LoadingIndicator();

exports.loaded = function (args) {
    loader.show();
    var page = args.object;
    http.getJSON(global.apiURL + "/home").then(function (response) {
        var firstElem = {
            "id": "1",
            "name": "firstElem",
            "pictureUrl": "res://Elem",
            "webUrl": "views/products/products"
        };
        response.data.unshift(firstElem);
        pageData.set("homeArray", response.data)
    }).catch(function (e) {
        console.log("Error: " + e.message);
    });
    page.bindingContext = pageData;
    loader.hide()
};

exports.homeTapped = function (args) {
    var tappedView = args.view;
    var tappedItem = tappedView.bindingContext;
    if (tappedItem.name == "firstElem") {
        var navigationPoint = {
            moduleName: 'views/products/products',
            clearHistory: false,
            animated: true,
            transition: {
                name: "slideLeft"
            },
            context: {
                subcategoryId: tappedItem.id,
            }
        };
        frameModule.topmost().navigate(navigationPoint);
    } else {
        utilityModule.openUrl(tappedItem.webUrl)
    }
}

the bu of this page is at the startup this page only shows the static image(firstElem) and randomly one of the other dynamic images, if i change view and go back to the home it shows all the images. the images from the server are little, some kB. thank you

peppeg85 avatar Sep 24 '18 09:09 peppeg85

Hi @peppeg85 I was able to reproduce an issue with the Image component in RadListView while loading the source from URL. I will mark this as a bug. As a temporary solution, you can set up width and height to the Image element. For example:

    <GridLayout columns="*" rows="*,41">
                <GridLayout row="0">
                    <lv:RadListView items="{{ homeArray }}" itemTap="homeTapped">
                        <lv:RadListView.listViewLayout>
                            <lv:ListViewGridLayout scrollDirection="Vertical" itemHeight="210" spanCount="2"/>
                        </lv:RadListView.listViewLayout>
                        <lv:RadListView.itemTemplate itemHeight="210">
                            <StackLayout class="home-container" orientation="horizontal"
                                         
                                         webUrl="{{ webUrl }}">
                                <StackLayout class="innerHomeImg" verticalAlignment="middle" orientation="horizontal">
                                    <GridLayout rows="210" class="grid-fonts">
                                        <Image height="210" width="210" class="brand-img" src="{{ pictureUrl }}"
                                               horizontalAlignment="center"/>
                                    </GridLayout>
                                </StackLayout>
                            </StackLayout>
                        </lv:RadListView.itemTemplate>
                    </lv:RadListView>
                </GridLayout>
                <StackLayout row="1" class="phoneStackLayout" orientation="vertical" tap="phone">
                    <Image class="phoneBtn" src="res://icon"
                           horizontalAlignment="center"/>
                </StackLayout>
            </GridLayout>

tsonevn avatar Sep 25 '18 13:09 tsonevn

hi @tsonevn , thanks for yout answer, i will try it. the same issue causes an "element loose" behavior with a long list of elements, when i scroll the listview, it loses images. i think it's a kind of "element reuse" to create the listview, always on ios, not on android

peppeg85 avatar Sep 25 '18 13:09 peppeg85

@tsonevn I actually thing that isssue is related to Nativescript and not RadListView. I have the same issue with the core ListView item. To be even more precise i think it's an issue with the GridLayout.

I see the issue with a sample like that I am seeing the issue if using a GridLayout instead of the StackLayout in the item template.

farfromrefug avatar Nov 21 '18 15:11 farfromrefug

Hi @farfromrefug, In this current case, the issue was related to the itemHeight property and the fact that at this time we can not setup dynamically its value in iOS. There might be a different issue with the GridLayout. I would suggest opening a separate issue in the modules repository.

tsonevn avatar Nov 22 '18 08:11 tsonevn

@tsonevn sorry my bad will do

farfromrefug avatar Nov 22 '18 08:11 farfromrefug

any progress on it ?

tahir-jamil avatar Jan 26 '19 13:01 tahir-jamil

This is still a pretty terrible issue, I'm facing this in RadListView.

ibnYusrat avatar May 09 '19 06:05 ibnYusrat

Still facing this issue

Lehren avatar Jan 09 '20 09:01 Lehren

I have the same issue. Any workaround?

koraykupe avatar Jan 09 '20 09:01 koraykupe

at this moment the workaround that works for me is to set statically the item and image height and width inside the xml

                        <lv:RadListView.listViewLayout>
                            <lv:ListViewGridLayout scrollDirection="Vertical" itemHeight="190" spanCount="2"/>
                        </lv:RadListView.listViewLayout>
                        <lv:RadListView.itemTemplate itemHeight="190">
                            <StackLayout class="home-container" orientation="horizontal"
                                         horizontalAlignment="center"
                                         webUrl="{{ webUrl }}">
                                <StackLayout class="innerHomeImg" verticalAlignment="middle" orientation="horizontal">
                                    <GridLayout rows="*" class="grid-fonts">
                                        <Image height="135" width="135" class="brand-img" src="{{ pictureUrl }}"
                                               horizontalAlignment="center"/>
                                    </GridLayout>
                                </StackLayout>
                            </StackLayout>
                        </lv:RadListView.itemTemplate>
                    </lv:RadListView>

peppeg85 avatar Jan 09 '20 10:01 peppeg85

Same problem here. Since the images are loaded dynamically and have different heights in our case, I can't set a static height. So the workaround doesn't help very much.

markusmauch avatar Feb 28 '20 15:02 markusmauch

Had the same problem and found a workaround for images with dynamic height. Here is an example-snippet of my News-Page. Instead of:

<ListView for="singleNews in news">
     <v-template>
        <StackLayout>
            <Label :text="singleNews.title" textWrap="true" />
            <Image :src="'https://yourURL.com" stretch="aspectFill" />
        </StackLayout>
    </v-template>
</ListView>

Working example:

<StackLayout>
    <StackLayout v-for="singleNews in news" v-bind:key="singleNews.id">
        <!-- Margins like in ListView -->
        <StackLayout margin="8">
            <Label :text="singleNews.title" textWrap="true" margin="5" />
            <Image :src="'https://yourURL.com" stretch="aspectFill" />
            <!-- Divider like in ListView -->
            <StackLayout marginTop="10" height="1" backgroundColor="LightGray"/>
        </StackLayout>
    </StackLayout>
</StackLayout>

Traimex avatar Apr 27 '20 08:04 Traimex

The images I fill in a separate array. With this method I don't have flicker and also the images appear correctly.

oliverphaser avatar Jun 16 '20 13:06 oliverphaser

Hi all, I am having same problem with NS 8.x and iOS. The first images in the view would display properly and when I scroll down it takes 1-2 sec to render new images. Exactly same as:

the same issue causes an "element loose" behavior with a long list of elements, when i scroll the listview, it loses images. i think it's a kind of "element reuse" to create the listview, always on ios, not on android

I have replaced <Image... > with Img:img as below using xmlns:img="@nativescript-community/ui-image"

<iOS>
    <GridLayout row="2" col="0" rows="200" heigh="200" width="155" class="grid-fonts">
        <img:Img class="lista-artikala-slika" heigh="200" width="155" placeholderImageUri="res://nemaslike" failureImageUri="res://nemaslike" showProgressBar="false" fadeDuration="500" src="{{ putanja_slike + '/' + file_url }}"/> 
    </GridLayout>
</iOS>

When scrolled all images are rendered and loaded with fade animation etc. Problem is that now first images in view aren't displayed (rendered). I need to scroll down from them and scroll up to force re-rendering.

I do not see any image flickering as it was case before (NS 6).

@oliverphaser how did you solve it?

UPDATE: Fix! Really nasty solution is to combine two images as example below. This solves my problem completely. It does not make any sense having those like this but in a GridLayout they would stack on each other. Not sure how it actually forces rendering. It does not affect performance and my list with 600 items works just fine.

<iOS>
    <GridLayout row="2" col="0" rows="190" heigh="200" width="155" class="grid-fonts">
        <Image  loaded="slikaUcitana" height="210" width="210" class="lista-artikala-slika" src="{{ putanja_slike + '/' + file_url }}" />
        <img:Img class="lista-artikala-slika" heigh="200" width="155" placeholderImageUri="res://nemaslike" failureImageUri="res://nemaslike" showProgressBar="false" fadeDuration="500" src="{{ putanja_slike + '/' + file_url }}"/> 
    </GridLayout>    
</iOS>

markosole avatar Aug 21 '21 18:08 markosole