Mr. Fullop
Mr. Fullop

Reputation: 21

My scrollview jumping when I add my contentview as a child to stackpanel

In Xamarin forms, when I add my ContentView as a child to stacklayout my scrollview jumping a little second. In Windows isn't jumping but in Android is jumping. video My ContentView has one image and one label. I add my ContentView as a child when my scrollview scrolld to bottom. I created for this a async method. My MainPage code:

    <ScrollView Orientation="Vertical" HorizontalScrollBarVisibility="Never" Grid.Row="1" Grid.Column="1" VerticalOptions="Fill" Padding="0" Margin="0,0,10,0" x:Name="scroll_R" Scrolled="scroll_R_Scrolled">
        <StackLayout Orientation="Vertical" x:Name="main_w" VerticalOptions="Fill">
        </StackLayout>
    </ScrollView>

And the c# code:

private async void scroll_R_Scrolled(object sender, ScrolledEventArgs e)
{
    if (loading) return;
    if(e.ScrollY >= ((scroll_R.ContentSize.Height - scroll_R.Height) - 200))
    {
        loading = true;
        fo_grid.RaiseChild(load_txt);
        load_txt.IsVisible = true;
                        

        await Task.Run(async () =>
        {
            if (Connectivity.NetworkAccess == NetworkAccess.Internet)
            {
                string json = new WebClient().DownloadString("https://szemle.hu/mobilapp.php?op=list&r=" + menu + "&min=" + load_int + "&l=10");
                List<fooldal_items> fin = JsonConvert.DeserializeObject<List<fooldal_items>>(json);
                Device.BeginInvokeOnMainThread(() =>
                {
                    load_int += 10;
                    fi = fin;
                });
            }
            else
            {
                DisplayAlert("Warning", "No internet connection!", "OK");
            }
        });
        addRow();
        loading = false;
    }
}

public void addRow()
{
    foreach (fooldal_items f in fi)
    {
        Button b = new Button();
        b.Text = "test";
        main_w.Children.Add(he);
    }
}

The fooldal_items class:

class fooldal_items
{
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string cim { get; set; }
    [DataMember]
    public string rovat { get; set; }
    [DataMember]
    public string kep { get; set; }
    [DataMember]
    public string tipus { get; set; }
}

MY contentview code.

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:App1"
                 x:Class="App1.hirlista_elem">
      <ContentView.Content>
            <Grid>
                <StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Margin="0,0,5,15" BackgroundColor="White" Padding="10" Orientation="Vertical" >
                    <Image Source="default" x:Name="img" HorizontalOptions="Fill" Aspect="AspectFit" HeightRequest="200"/>
                    <Label Text="TESZT6543" FontSize="Subtitle" TextColor="#208b55" x:Name="lbl" Grid.Row="1" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                </StackLayout>
            </Grid>
        </ContentView.Content>
    </ContentView>

My contentview c# code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace App1
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class hirlista_elem : ContentView
    {
        public MainPage mp;

        string id;

        public hirlista_elem(string img_url, string title, string _id, MainPage _mp)
        {
            InitializeComponent();

            if(img_url != "") img.Source = img_url;
            lbl.Text = title;    

            //img.HeightRequest = img.Height;
            mp = _mp;
            //enable tap
            var open_rovat = new TapGestureRecognizer();
            open_rovat.Tapped += Open_rovat_Tapped;
            this.GestureRecognizers.Add(open_rovat);
            id = _id;
        }

        private void Open_rovat_Tapped(object sender, EventArgs e)
        {
           //
        }
    }
}

Upvotes: 1

Views: 164

Answers (1)

Mr. Fullop
Mr. Fullop

Reputation: 21

I find the answer. Change ScrollView to Listview and delete the stacklayout. Then try this code:

<ListView CachingStrategy="RecycleElement" Grid.Row="1" Grid.Column="1" VerticalOptions="Fill" Margin="0,0,10,0" x:Name="list_V" Scrolled="list_V_Scrolled" HasUnevenRows="True" ItemAppearing="list_V_ItemAppearing">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                                            <StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Margin="0,0,5,15" BackgroundColor="White" Padding="10" Orientation="Vertical" >
                                                <Image Source="{Binding kep_url}" HorizontalOptions="Fill" Aspect="AspectFit" HeightRequest="200"/>
                                                <Label Text="{Binding cim}" FontSize="Subtitle" TextColor="#208b55" x:Name="lbl" Grid.Row="1" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                                            </StackLayout>
                                            <Image Source="https://szemle.hu/design/img/sarok.png" VerticalOptions="Start" HorizontalOptions="End" Margin="0,0,5,0" HeightRequest="100" WidthRequest="100" Aspect="AspectFit"/>
                                            <Image Source="{Binding kep_r_f}" x:Name="rovat_img" VerticalOptions="Start" HorizontalOptions="End" Margin="{Binding margin}" HeightRequest="50" WidthRequest="50" Aspect="AspectFit"/>
                                        </Grid>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>

Create a elements class like this:

public class elements
{
    public MainPage mp { get; set; }

    public string id { get; set; }

    public string kep_url { get; set; }

    public string cim { get; set; }

    public string tipus { get; set; }

    public string kep_r_f { get; set; }

    public Thickness margin { get; set; }
}

And then use this code in MainPage.cs:

public ObservableCollection<elements> elemek { get; private set; }

private async void list_V_ItemAppearing(object sender, ItemVisibilityEventArgs e)
{
    if (loading) return;
    if (e.Item == elemek[elemek.Count - 3] && !loading && menu != rovatok.fooldal)
    {
        //LOAD YOUR ELEMENTS HERE
    }
}

Upvotes: 1

Related Questions