NuGetXamarinXamarin.Forms

Xamarin.Forms CarouselView

Contents

With CarouselView, item collections are displayed in a floating order. By default, items are listed in a horizontal position.

Our motivation in this post, get first five news from newsapi and show it in a CarouselView. Also, I used PancakeView plugin to make beautiful design. You can learn how to use PancakeView from my recent post.

Download Plugins

You need the following plugins for the project:

  • Newtonsoft.Json -> to deserialize JSON files.
  • Xamarin.Forms.PancakeView -> for design

You can use download plugins using Nuget Package Manager. I also recommend you to check out Top 5 Useful Plugins in Xamarin.

Get API Key

In this project I use News API because it is free. You need API key to query. Register this site and get an API key easily.

This is an example query to understand this documentation. Open the following link in a browser. You can see the result.

http://newsapi.org/v2/everything?q=bitcoin&from=2020-06-25&sortBy=publishedAt&apiKey=0aa6acdc93314fa380708f86053e21fc

Model Class

After open the above link you will see a JSON file. To convert this file to C# class use jsonutils.com. You can paste JSON file and convert it easily.

After doing the translation, create a folder named Model in the project and add a class named News.cs to this folder. Paste the class you just translated from the site into this class.

    public class Source
    {
        public string id { get; set; }
        public string name { get; set; }
    }

    public class Article
    {
        public Source source { get; set; }
        public string author { get; set; }
        public string title { get; set; }
        public string description { get; set; }
        public string url { get; set; }
        public string urlToImage { get; set; }
        public DateTime publishedAt { get; set; }
        public string content { get; set; }
    }

    public class News
    {
        public string status { get; set; }
        public int totalResults { get; set; }
        public IList<Article> articles { get; set; }
    }

Service Class

Add a Services folder to the project and create a class named NewsAPI.cs in this folder. There will be methods in this class that make the API query.

    class NewsAPI
    {
        public const string NEWS_API_KEY = "WRITE YOUR API KEY HERE";
        public const string BASE_URL = "https://newsapi.org/v2/everything?q={0}&from={1}&sortBy=publishedAt&apiKey={2}";

        public static async Task<News> GetNewsAsync(string query)
        {
            string date = DateTime.Now.ToString("yyyy-MM-dd h:mm tt");
            News news = new News();
            string url = String.Format(BASE_URL, query, date, NEWS_API_KEY);
            HttpClient httpClient = new HttpClient();
            var response = await httpClient.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                var posts = JsonConvert.DeserializeObject<News>(content);
                news = posts;
            }
            return news;
        }
    }

After write the class codes add namespaces that necessary. You will see the required namespaces already.

CarouselView ViewModel Class

To fully implement the MVVM architecture, add the ViewModels folder to the project and create a class named NewsViewModel.cs in this folder.

Put the answers from the API in a List<> named ArticleList. This list will be the ItemSource of CarouselView.

   public class NewsViewModel : INotifyPropertyChanged
    {
        private List<Article> articleList { get; set; }
        public List<Article> ArticleList
        {
            get
            {
                return articleList;
            }

            set
            {
                if (value != articleList)
                {
                    articleList = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public NewsViewModel()
        {
            Task.Run(APIAsync);
        }
        private async Task APIAsync()
        {
            var news = await NewsAPI.GetNewsAsync("Android");
            List<Article> articleList = new List<Article>();
            for (int i = 0; i < 5; i++)
            {
                articleList.Add(new Article
                {
                    title= news.articles[i].title,
                    description=news.articles[i].description,
                    urlToImage=news.articles[i].urlToImage,
                    url=news.articles[i].url
                }
                );
            }
            ArticleList = articleList;
        }
    }

APIAsync method gets news about “Android”. Assigns the title, description, urlToImage and url variables to the list with a for loop.

CarouselView Page

Now add a Views folder to the project and add a ContentPage named NewsPage.xaml. Create a CarouselView and IndicatorView in ContentPage. Set the ArticleList as ItemSource property of CarouselView.

    <ContentPage.Content>
        <StackLayout>
                <CarouselView ItemsSource="{Binding ArticleList}" IndicatorView="IndicatorView">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout >
                            <Frame HorizontalOptions="Center" VerticalOptions="CenterAndExpand">
                                    <StackLayout>
                                        <pancakeview:PancakeView BackgroundColor="#d4d6c8" HeightRequest="600" WidthRequest="300" CornerRadius="20" HorizontalOptions="Center" VerticalOptions="Center">
                                        <ScrollView>
                                            <Grid>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                </Grid.RowDefinitions>
                                                <pancakeview:PancakeView  Grid.Row="0" BackgroundColor="Transparent" CornerRadius="20,20,0,0" HorizontalOptions="Center" VerticalOptions="Center">
                                                    <Image Source="{Binding urlToImage}"  HeightRequest="200" WidthRequest="300" Aspect="AspectFill" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"  />
                                                </pancakeview:PancakeView>
                                                <Label Grid.Row="1" Text="{Binding title}" TextColor="Black" FontSize="20" FontAttributes="Bold" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Margin="10"  />
                                                <Label Grid.Row="2" Text="{Binding description}"  TextColor="Black" FontSize="15" HorizontalOptions="Center" VerticalOptions="Center" Margin="10"   />
                                                <Label Grid.Row="3" Text="{Binding url}"  TextColor="#1235F5"  FontSize="15" HorizontalOptions="Center" VerticalOptions="Center" Margin="10" TextDecorations="Underline" FontAttributes="Italic" />
                                            </Grid>
                                        </ScrollView>
                                        </pancakeview:PancakeView>
                                    </StackLayout>
                            </Frame>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <IndicatorView x:Name="IndicatorView"
                       IndicatorSize="7"
                       IndicatorsShape="Circle"
                       IndicatorColor="Black"
                       SelectedIndicatorColor="DarkGray"
                       HorizontalOptions="Center"
                       VerticalOptions="Center" Margin="0,0,0,20">
            </IndicatorView>
        </StackLayout>
    </ContentPage.Content>

Add necessary namespaces for PancakeView and others if exists.

To link the ViewModel class to the page, add the following line in the constructor method of the NewsPage.xaml.cs class.

        public NewsPage()
        {
            InitializeComponent();
            this.BindingContext = new NewsViewModel();
        }

Finally, set MainPage in the App.xaml.cs class before launching the application. And of course add the required namespaces.

        public App()
        {
            InitializeComponent();
            MainPage = new NewsPage();
        }

CarouselView Output

Everything is ok. You can run the application and see how it looks.

Xamarin.Forms-CarouselView

Your screen will look different from this because the AppShell structure is used here. You can check our Using Shell in Xamarin.Forms article to learn how to use AppShell.

Serkan

Software Engineer. Problem solver. Music practitioner. Thinker. Industrious.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button