Beray Bentesen in Xamarin Android

Image Slider with ViewPager - Xamarin Android

 

This article will be covering :

  • Working with ViewPager
  • Loading images from url with Glide
  • Using Fragment and FragmentStatePagerAdapter

Many Android applications display images with sliding effect.

Slider implementation can be done easily for Android but there are some points that you must take care of for your application. This article not only covers implementation but also covers code efficiency, caching images and more.

  • In order to create you have to include the Xamarin.Android.Support.v4 , Xamarin.Android.Support.v7 and Glide.Xamarin for downloading and caching images without any exception.

Working with Layout

  • You need to add ViewPager into your layout first such as LinearLayout as following example
    • If you want to create full-screen slider, then change 400dp with match_parent
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="400dp" />
</LinearLayout>  
  • ViewPager will contains fragments so layout of each fragment must be created
    • Simple ImageView used for this post.
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:scaleType="centerCrop"
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:layout_height="400dp" />

Working with Code

  • The first step is creating a Fragment class.
  • Because ViewPager will always need a single view for each data, application will follow a certain pattern while returning fragments.
  • Func< T > is a predefined delegate type for a method that returns some value of the type and we can use this type to reference a method that returns some value of T which will be a View.
public class ImageFragment : Android.Support.V4.App.Fragment  
    {
        readonly Func<LayoutInflater, ViewGroup, Bundle, View> view;

        public ImageFragment(Func<LayoutInflater, ViewGroup, Bundle, View> view)
        {
            this.view = view;
        }

        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            base.OnCreateView(inflater, container, savedInstanceState);
            return view(inflater, container, savedInstanceState);
        }
    }
  • Many slider examples use FragmentPagerAdapter for ViewPager but this example will be using FragmentStatePagerAdapter because it only stores the saved instance state of fragments and destroys all the fragments when they lose focus
  • addFragmentView method will be adding Fragments into fragmentList in Activity where views will be inflating.
public class ImageFragmentStatePagerAdapter : FragmentStatePagerAdapter  
    {
        readonly List<Fragment> fragmentList = new List<Fragment>();

        public ImageFragmentStatePagerAdapter(Android.Support.V4.App.FragmentManager fragmentManager) : base (fragmentManager)
        {
        }

        public override int Count
        {
            get
            {
                return fragmentList.Count;
            }
        }

        public override Fragment GetItem(int position)
        {
            return fragmentList[position];
        }

        public void addFragmentView(Func<LayoutInflater, ViewGroup, Bundle, View> fragmentView)
        {
            fragmentList.Add(new ImageFragment(fragmentView));
        }
    }
  • The last step is populating data in Activity.
  • You need to define following variables at the top of Activity and you must implement AppCompatActivity to be able to call SupportFragmentManager instead of Activity.
ViewPager viewPager;  
ImageFragmentStatePagerAdapter imageFragmentPagerAdapter;  
List<string> imageList;  
  • Variables must be initialized before accessing them in OnCreate
viewPager = FindViewById<ViewPager>(Resource.Id.viewPager);  
            imageFragmentPagerAdapter = new ImageFragmentPagerAdapter(SupportFragmentManager);
            imageList = new List<string>();
  • Before populating data, you need to add image urls into imageList.
imageList.Add("ImageUrls");  
  • createImageFragment method will work for each url in list, you might call while deserializing Json data for example.
  • You need a library to download images from url, cache and show in ImageView. Glide is the currently best option for Android and it will care of everything about image.
 void createImageFragment(string url)
        {
            imageFragmentPagerAdapter.addFragmentView((arg1, arg2, arg3) => 
            {
                // Inflating View to access Image View
                var view = arg1.Inflate(Resource.Layout.ImageViewLayout, arg2, false);
                // Accessing Image from View
                var imageView = view.FindViewById<ImageView>(Resource.Id.imageView);
                // Loading image with Glide
                Glide.With(this).Load(url).Into(imageView);
                // Returning Image View
                return view;
            });                                     
        }
  • The last step is calling createImageFragment in foreach loop
foreach (var item in imageList)  
            {
                createImageFragment(item);
            }

viewPager.Adapter = imageFragmentPagerAdapter;  

Result :