Search code examples
c#androidandroid-viewpagerxamarin.androidandroid-pageradapter

ViewPager/PagerAdapter shows all views on first page


What's happening
The ViewPager in my app shows all views I instantiated on page one. If I instantiate two views for example, both views are shown in page one, and the second page is just blank.

Images showing the problem
As you can see below, page one contains both pages and page two is empty.

Page one Page two

I can't figure out why this is happening. Have been struggling with this for a long time now. I tried not to add the view to the adapter, adding the view and also providing the index, not inflating it but creating an ImageView in the adapter, etc.

What am I missing? Any help would be appreciated!

Code
Activity

[Activity(Label = "Foto's", ScreenOrientation = ScreenOrientation.Portrait)]
public class PicturesActivity : BaseActivity
{
    private ImagePagerAdapter _imageAdapter;
    private List<string> _filePaths;
    private ViewPager _viewPager;

    private const int _maxPictures = 5;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.Pictures);
        _viewPager = FindViewById<ViewPager>(Resource.Id.ViewPager);
    }

    protected override void OnStart()
    {
        base.OnStart();

        _imageAdapter = new ImagePagerAdapter(this, _filePaths);
        _viewPager.Adapter = _imageAdapter;
        _viewPager.SetCurrentItem(0, false);
    }
}

PagerAdapter

internal class ImagePagerAdapter : PagerAdapter
{
    Activity _activity;
    List<string> _filePaths;

    public ImagePagerAdapter(Activity activity, List<string> filePaths)
    {
        _activity = activity;
        _filePaths = filePaths;
    }

    public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
    {
        var view = _activity.LayoutInflater.Inflate(Resource.Layout.PicturePageItem, container, false);
        var imageView = view.FindViewById<ImageView>(Resource.Id.ImageView);
        var filePath = _filePaths[position];

        DisplayMetrics metrics = _activity.Resources.DisplayMetrics;
        using (var bitmap = BitmapHelper.GetResizedBitmap(filePath, new Size(metrics.WidthPixels, metrics.HeightPixels)))
            imageView.SetImageBitmap(bitmap);

        container.JavaCast<ViewPager>().AddView(view);
        return view;
    }

    public override void DestroyItem(ViewGroup container, int position, Java.Lang.Object @object)
    {
        var view = (LinearLayout)@object;
        var imageView = view.FindViewById<ImageView>(Resource.Id.ImageView);

        if (imageView != null && imageView.Drawable != null)
        {
            imageView.Drawable.Dispose();
            imageView.SetImageBitmap(null);
        }

        container.JavaCast<ViewPager>().RemoveView(view);
    }

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

    public override bool IsViewFromObject(View view, Java.Lang.Object @object)
    {
        return view is LinearLayout;
    }
}

Pictures layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    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="match_parent" />
</LinearLayout>

PicturePageItem layout (adapter page layout)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/ImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside" />
</LinearLayout>

Solution

  • I think the problem may be due to your method IsViewFromObject().

    This method is called to compare the View with the Key Object. Your version is always returning true so the ViewPager thinks all your views are on the same page.

    You should modify your code like this:

    public override bool IsViewFromObject(View view, Java.Lang.Object @object)
    {
        return (object)view == @object;
    }
    

    For more details, see:

    http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html