Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

ScrollView Pull to Refresh

ma12rkyma12rky Member ✭✭✭✭

Hi Xamarin Forum
is it possible to put Pull to refresh in a scrollView?Because there is a listView inside that ScrollView though I know that ListView has that functionality but due to the design I needed, I have to put scrollView to have a pull to Refresh

Best Answer

Answers

  • RichyRichy Member ✭✭
    edited November 2019
    Please refer the following link.

    I can't add a URL :# so Just google "Jamesmontemagno Xamarin.Forms-PullToRefreshLayout"
  • PrabakaranRamasamyPrabakaranRamasamy USMember ✭✭✭

    You can also try Syncfusion's pull to refresh layout for Xamarin.Forms.

    To get started, refer the following link.
    https://help.syncfusion.com/xamarin/pull-to-refresh/getting-started

    The whole suite of Syncfusion controls is available for free (commercial applications also) through the community license program if you qualify (less than 1 million US Dollars in revenue). The community license is the full product with no limitations or watermarks.

    Note: I work for Syncfusion.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    @ma12rky I suggest you to use RefreshView to achieve it.

    Before you used, please update the xamarin forms to 4.3

    Here is running GIF.

    Here is MainPage.xaml

    <RefreshView IsRefreshing="{Binding IsRefreshing}"   x:Name="rv"
             Command="{Binding RefreshCommand}">
        <ScrollView >
            <FlexLayout Direction="Row"
                    Wrap="Wrap"
                    AlignItems="Center"
                    AlignContent="Center"
                    BindableLayout.ItemsSource="{Binding Items}"
                   />
    
    
        </ScrollView>
    </RefreshView>
    

    Here is MainPage.xaml.cs

      public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
    
            BindingContext = new MyViewModel();
        }
     }
    

    Here is MyViewModel.cs, for the test, I put the INotifyPropertyChanged to the ViewModel, if you have Model, you should put it in Model.

      public class MyViewModel: INotifyPropertyChanged
    {
        public ICommand RefreshCommand { protected set; get; }
        public ObservableCollection<string> Items { get; set; }
    
    
        bool _isRefreshing = false;
        public bool IsRefreshing
        {
            get
            {
                return _isRefreshing;
            }
    
            set
            {
                if (_isRefreshing != value)
                {
                    _isRefreshing = value;
                    OnPropertyChanged("IsRefreshing");
    
                }
            }
    
        }
        public MyViewModel()
        {
            Items = new ObservableCollection<string>();
    
            Items.Add("ddddd" );
            Items.Add("ccccc");
            Items.Add("eeeeee");
    
            RefreshCommand = new Command<string>((key) =>
            {
                Items.Add("ffffff");
                IsRefreshing = false;
            });
        }
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  • ma12rkyma12rky Member ✭✭✭✭

    @LeonLu thanks gonna try your solution to be honest I have already saw that RefreshView in microsoft.com but when I click the sample link to fully understand the code it displayed to me a 404 page

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    @ma12rky
    Here is correct link about the sample of RefreshView
    https://github.com/xamarin/xamarin-forms-samples/tree/bb44fcf87e2d9e159638d7b83196f4c886bde57e/UserInterface/RefreshViewDemo

    All of the xamarin forms demos will be moved to this repository. If you meet 404 pages in the next time, you can search the simples in this repository.
    https://github.com/xamarin/xamarin-forms-samples/tree/bb44fcf87e2d9e159638d7b83196f4c886bde57e

    If the reply is helpful, please do not forget to mark it as answer, it will help others who have similar issue.

  • ma12rkyma12rky Member ✭✭✭✭

    @LeonLu thank you very much for the solution it work though I just encounter when I try to scroll up because it always triggers the refreshview instead of triggering the refreshview when Im on top of the listView, if it not much to you I will post the code

    XAML

    <RefreshView IsRefreshing="{Binding IsRefreshing}" x:Name="rfeshContent" Command="{Binding RefreshCommand}">
                <ScrollView>
                    <StackLayout>
                        <Grid>
                            <ci:PageControl ShowIndicator="{Binding ShowIcons}" IndicatorHeight="8" IndicatorWidth="8" UnselectedIndicator="unselected_circle.png" SelectedIndicator="selected_circle.png" Position="{Binding Position}" ItemsSource="{Binding Screenshots}" IsVisible="False"/>
                            <Image Source="{Binding Image}" HeightRequest="400" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Aspect="AspectFill"/>
                            <Label Text="Welcome to City Loads" FontAttributes="Bold" FontFamily="sans-serif"  FontSize="Large" TextColor="White"  Margin="10,320,0,0"/>
                            <StackLayout>
                                <StackLayout Spacing="0" VerticalOptions="Start" Orientation="Horizontal">
                                    <StackLayout.Margin>
                                        <OnPlatform x:TypeArguments="Thickness">
                                            <On Platform="iOS" Value="0,12,0,0" />
                                            <On Platform="Android" Value="0,24,0,0" />
                                        </OnPlatform>
                                    </StackLayout.Margin>
                                    <Image Source="search2.png" Margin="0,-15,10,15" HorizontalOptions="EndAndExpand" VerticalOptions="Center" HeightRequest="30" WidthRequest="30">
                                        <Image.GestureRecognizers>
                                            <TapGestureRecognizer Tapped="SearchPage"/>
                                        </Image.GestureRecognizers>
                                    </Image>
                                </StackLayout>
                            </StackLayout>
                        </Grid>
                        <StackLayout Orientation="Horizontal" Margin="0,10,0,15">
                            <Label Text="Welcome" FontAttributes="Bold" FontSize="Medium" FontFamily="sans-serif-light" Margin="10,0,0,0"/>
                            <Label x:Name="userName" FontSize="Medium" FontFamily="sans-serif-light"/>
                        </StackLayout>
                        <StackLayout Margin="10,15,0,15">
                            <Label Text="Recent Properties" FontAttributes="Bold" FontSize="Large" FontFamily="sans-serif-light"/>
                        </StackLayout>
                        <ScrollView Orientation="Horizontal" HorizontalScrollBarVisibility="Never" Margin="0,0,0,20">
                            <StackLayout Orientation="Horizontal">
                                <Grid>
                                    <Image HeightRequest="100" WidthRequest="120" Aspect="AspectFill" Source="tokyo.png" Margin="10,0,0,0">
                                        <Image.GestureRecognizers>
                                            <TapGestureRecognizer Tapped="SelectPopDestination"/>
                                        </Image.GestureRecognizers>
                                    </Image>
                                    <Label Text="TOKYO" FontAttributes="Bold" FontSize="Medium" VerticalTextAlignment="Center"  TextColor="White"  Margin="10,200,0,0"/>
                                </Grid>
                                <Grid>
                                    <Image HeightRequest="100" WidthRequest="120" Aspect="AspectFill" Source="hk.jpg" Margin="10,0,0,0" />
                                    <Label Text="HONG KONG" FontAttributes="Bold" FontSize="Large" TextColor="White"  Margin="10,200,0,0"/>
                                </Grid>
                                <Grid>
                                    <Image HeightRequest="100" WidthRequest="120" Aspect="AspectFill" Source="beijing.png" Margin="10,0,0,0" />
                                    <Label Text="BEIJING" FontAttributes="Bold" FontSize="Large" TextColor="White"  Margin="10,200,0,0"/>
                                </Grid>
                                <Grid>
                                    <Image HeightRequest="100" WidthRequest="120" Aspect="AspectFill" Source="macau.jpg" Margin="10,0,10,0" />
                                    <Label Text="MACAU" FontAttributes="Bold" FontSize="Large" TextColor="White"  Margin="10,200,0,0"/>
                                </Grid>
                            </StackLayout>
                        </ScrollView>
                        <ListView  x:Name="listViewPost" RowHeight="570" Margin="0" ItemTapped="ViewPost" SeparatorVisibility="None" IsPullToRefreshEnabled="True">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <Frame Padding="10,0,10,10" WidthRequest="400">
                                            <Frame CornerRadius="4" WidthRequest="400" Padding="0,0,0,10">
                                                <StackLayout Margin="5,0,5,0" Padding="0">
                                                    <StackLayout>
                                                        <StackLayout Orientation="Horizontal">
                                                            <controls:CircleImage Source="default_user.jpg" Aspect="AspectFit" BorderColor="Gray" BorderThickness="1" Grid.Column="0" Grid.Row="0">
                                                                <controls:CircleImage.WidthRequest>
                                                                    <OnPlatform x:TypeArguments="x:Double">
                                                                        <On Platform="Android, iOS">25</On>
                                                                    </OnPlatform>
                                                                </controls:CircleImage.WidthRequest>
                                                                <controls:CircleImage.HeightRequest>
                                                                    <OnPlatform x:TypeArguments="x:Double">
                                                                        <On Platform="Android, iOS">25</On>
                                                                    </OnPlatform>
                                                                </controls:CircleImage.HeightRequest>
                                                            </controls:CircleImage>
                                                            <StackLayout Margin="0,5,0,5">
                                                                <Label Text="{Binding Uploader}" HorizontalOptions="Start" FontSize="16" x:Name="uploader" FontAttributes="Bold" FontFamily="sans-serif-light"/>
                                                                <StackLayout Orientation="Horizontal">
                                                                    <Label Text="Posted on " FontFamily="sans-serif-light"/>
                                                                    <Label Text="{Binding Date_Uploaded, StringFormat='{}{0:MMM d,yyyy}'}" HorizontalOptions="Start" FontSize="12" FontFamily="sans-serif-light"/>
                                                                </StackLayout>
                                                            </StackLayout>
                                                        </StackLayout>
                                                    </StackLayout>
                                                    <Label Text="{Binding Post_Content}" FontSize="15"/>
                                                    <Image WidthRequest="400" HeightRequest="400" Aspect="AspectFill" Source="{Binding Photo}"/>
                                                </StackLayout>
                                            </Frame>
                                        </Frame>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </StackLayout>
                </ScrollView>
            </RefreshView>
    

    CodeBehind

    public partial class HomePage : ContentPage
        {
    
            t_Post SelectedPost;
            string json;
            string jsonImage1;
            string jsonImage2;
            string jsonImage3;
            string jsonImage4;
    
            public List<t_Post> postslist;
    
            public HomePage ()
            {
                InitializeComponent ();
                this.BindingContext = new MainViewModel();
    
                GetDataSource();
    
                string userfirstname = App.FirstName;
                userName.Text = userfirstname + ",";
                NavigationPage.SetHasNavigationBar(this, false);
            }
    
            private void Searchbar_searchpressed(object sender, EventArgs e)
            {
                var search = sender as SearchBar;
                this.Navigation.PushModalAsync(new SearchResultpage(search.Text), true);
            }
    
            async void SearchPage(object sender, EventArgs e)
            {
                var page = new LoadingPage();
                await PopupNavigation.Instance.PushAsync(page);
                await Navigation.PushModalAsync(new TopSearchPage());
                await PopupNavigation.Instance.PopAsync();
            }
    
            public async void ViewPost(object sender, ItemTappedEventArgs e)
            {
                var house = e.Item as t_Post;
                var page = new LoadingPage();
    
                await PopupNavigation.Instance.PushAsync(page);
                await this.Navigation.PushAsync(new PostDetailPage(house), false);
                ((ListView)sender).SelectedItem = null;
                await PopupNavigation.Instance.PopAsync();
            }
    
            void SelectPopDestination(object sender, EventArgs e)
            {
                Navigation.PushAsync(new PopularDestPage());
            }
    
            public async void GetDataSource()
            {
                var httpClient = new HttpClient();
                var response = await httpClient.GetStringAsync("http://xxx.xx.xxx.xxx:8087/path/pathanother");
                var dataSource = JsonConvert.DeserializeObject<List<t_Post>>(response);
                listViewPost.ItemsSource = dataSource;
            }
        }
    

    ViewModel

    public class MainViewModel : INotifyPropertyChanged
        {
                public event PropertyChangedEventHandler PropertyChanged;
    
                public ICommand RefreshCommand { protected set; get; }
    
                protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
                {
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    
                    if (PropertyChanged == null)
                        return;
    
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
    
                protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
                {
                    if (EqualityComparer<T>.Default.Equals(storage, value))
                    {
                        return false;
                    }
    
                    storage = value;
                    OnPropertyChanged(propertyName);
                    return true;
                }
    
                private int _position;
                public int Position
                {
                    get
                    {
                        this.Image = HouseImages[_position].Image;
                        return _position;
                    }
                    set { SetProperty(ref _position, value); }
                }
    
                private bool _showIcons = false;
                public bool ShowIcons
                {
                    get { return _showIcons; }
                    set
                    {
                        SetProperty(ref _showIcons, value);
                    }
                }
    
                private string _image;
                public string Image
                {
                    get { return _image; }
                    set { SetProperty(ref _image, value); }
                }
    
            public ObservableCollection<Screenshot> HouseImages { get; }
    
            public ObservableCollection<string> Items { get; set; }
    
            bool _isRefreshing = false;
    
            public bool IsRefreshing
            {
                get
                {
                    return _isRefreshing;
                }
    
                set
                {
                    if (_isRefreshing != value)
                    {
                        _isRefreshing = value;
                        OnPropertyChanged("IsRefreshing");
    
                    }
                }
    
            }
    
            public MainViewModel()
            {
    
                Items = new ObservableCollection<string>();
    
                HouseImages = new ObservableCollection<Screenshot>()
                {
                    new Screenshot (){Image = "home1.jpg"},
                    new Screenshot (){Image = "login.jpg"}
                };
    
                Position = 0;
                Device.StartTimer(TimeSpan.FromSeconds(5), () =>
                {
                    if (Position == 1)
                    {
                        Position = 0;
                    }
                    else
                    {
                        Position++;
    
                    }
    
                    return true;
                });
    
                RefreshCommand = new Command<string>((key) =>
                {
                    IsRefreshing = false;
                });
            }
    
        }
    
  • ma12rkyma12rky Member ✭✭✭✭

    @LeonLu anyway my objective is to refresh the listView and display any latest post like fb in a mobile phone

  • JoannaGJoannaG Member ✭✭

    Does RefreshVView support UWP platform?

Sign In or Register to comment.