1

I'm currently working on an application in Xamarin.Android. In this application, I use several ViewPagers, and I never had any problem with it since yesterday.

At the beginning of my app, I got a kind of animated tour, this is a simple activity containing a ViewPager, which uses 4 fragments (each fragment has one video in it) and so we can scroll horizontally to go further on the tour. Below you can see a screenshot of it : enter image description here

But I have a problem occurring on all android devices which are not on Android 7 (Android 4 and previous are not supported, so my problem occurs only on Android 5 and 6). When I scroll horizontally on this ViewPager, kind of black bars appear on the left and on the right of each video. I suppose this is not happening on Android 7 because the OS manages videos better. Below you have an example :

enter image description here

Here my video is occupying 100% of the screen space, but it happens also when the video is smaller, I reduced the size of one of them to show you :

enter image description here

Those black bars are not fixed, by that I mean they kind of move randomly on the screen while I scroll horizontally. I put the background color of almost everything in white, but it has no effect. I really think this is Android having difficulties while moving a video on the screen, while this video is still being played. But this is so ugly, it provides a bad UX and this is very important to me and my team to be able to fix this problem.

Here you have the code, if it can help you :

animated_tour.axml (the axml for the activity)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vp_animated_tour"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white" />

AnimatedTourActivity.cs (the activity class)

[Activity(Label = "AnimatedTourActivity", Theme = "@style/AppTheme")]
public class AnimatedTourActivity : AppCompatActivity
{

    public AnimatedTourViewModel Vm
    {
        get
        {
            return App.Locator.AnimatedTour;
        }
    }

    private ViewPager _viewPager;

    public ViewPager ViewPager
    {
        get
        {
            return this._viewPager ?? (this._viewPager = this.FindViewById<ViewPager>(Resource.Id.vp_animated_tour));
        }
    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        SetContentView(Resource.Layout.animated_tour);
        base.OnCreate(savedInstanceState);

        Window.SetFlags(Android.Views.WindowManagerFlags.Fullscreen, Android.Views.WindowManagerFlags.Fullscreen);

        // On bloque en mode portrait
        RequestedOrientation = Android.Content.PM.ScreenOrientation.Portrait;
        this.ViewPager.Adapter = new AnimatedTourAdapter(this.SupportFragmentManager);

        if (Android.OS.Build.VERSION.SdkInt <= BuildVersionCodes.Lollipop)
            this.ViewPager.OffscreenPageLimit = 1;
        else
            this.ViewPager.OffscreenPageLimit = 3;
    }
}

One of the four AXML files for a fragment containing a video

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <FrameLayout
            android:id="@+id/placeholder"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white" />
        <VideoView
            android:id="@+id/vv_animated_tour_2"
            android:layout_gravity="center"
            android:layout_height="match_parent"
            android:layout_width="match_parent" />
    </FrameLayout>
    <LinearLayout
        android:id="@+id/ll_animated_tour_description"
        android:layout_marginTop="350dp"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:textSize="23dp"
            android:fontFamily="fonts/AvenirLTStd-Book.otf"
            android:textColor="@color/general_text_color_grey"
            android:text="@string/animated_tour_family_management" />
        <TextView
            android:layout_marginTop="15dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:paddingRight="33dp"
            android:paddingLeft="33dp"
            android:textSize="19.5dp"
            android:fontFamily="fonts/AvenirLTStd-Book.otf"
            android:textColor="@color/animated_tour_description"
            android:text="@string/animated_tour_family_management_description" />
    </LinearLayout>
    <ImageView
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="100dp"
        android:background="@drawable/DOTS_2" />
</RelativeLayout>

AnimatedTourFragment.cs (the common fragment class)

public class AnimatedTourFragment : SupportV4.Fragment
{
    static AnimatedTourFragment fragment;

    private const string TEMPLATED_ANIMATED_TOUR_RESOURCE_ID = "resource_id";
    private const string TEMPLATED_ANIMATED_TOUR_VIDEO_RESOURCE_ID = "video_resource_id";
    private const string TEMPLATED_ANIMATED_TOUR_NUMBER = "number";


    public AnimatedTourFragment()
    {

    }

    public static AnimatedTourFragment NewInstance(int number, int resourceId, int videoResourceId)
    {
        fragment = new AnimatedTourFragment();
        Bundle args = new Bundle();

        args.PutInt(TEMPLATED_ANIMATED_TOUR_RESOURCE_ID, resourceId);
        args.PutInt(TEMPLATED_ANIMATED_TOUR_NUMBER, number);
        args.PutInt(TEMPLATED_ANIMATED_TOUR_VIDEO_RESOURCE_ID, videoResourceId);


        fragment.Arguments = args;

        return fragment;
    }


    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        //return base.OnCreateView(inflater, container, savedInstanceState);
        var resourceId = Arguments.GetInt(TEMPLATED_ANIMATED_TOUR_RESOURCE_ID, 0);
        var number = Arguments.GetInt(TEMPLATED_ANIMATED_TOUR_NUMBER, 1);
        var videoResourceId = Arguments.GetInt(TEMPLATED_ANIMATED_TOUR_VIDEO_RESOURCE_ID, 0);

        var view = inflater.Inflate(resourceId, container, false);

        var videoViewId = this.Activity.Resources.GetIdentifier(string.Format("vv_animated_tour_{0}", number), "id", this.Activity.PackageName);

        var videoView = view.FindViewById<VideoView>(videoViewId);
        videoView.SetOnPreparedListener(new VideoLoop());
        videoView.SetVideoURI(Android.Net.Uri.Parse("android.resource://" + this.Activity.PackageName + "/" + videoResourceId));
        videoView.Start();

        var goButton = view.FindViewById<Button>(Resource.Id.bt_animated_tour_go);
        goButton?.SetCommand("Click", (this.Activity as AnimatedTourActivity).Vm.NavigateToHomeCommand);

        return view;
    }

}


public class VideoLoop : Java.Lang.Object, Android.Media.MediaPlayer.IOnPreparedListener
{
    public void OnPrepared(MediaPlayer mp)
    {
        mp.Looping = true;
    }

}

Thanks for your help !

1 Answers1

1

VideoView extends SurfaceView, the main limitation of SurfaceView is that it's not ideal for translation, animation, and moving, this can cause your problem.

What you need is a TextureView based video player. You can try to search for third-party lib.

Or you may try to create such one by yourself, here is some Java resources you may refer to:

Playing video on TextureView

TextureVideoView.java.

Grace Feng
  • 16,564
  • 2
  • 22
  • 45
  • Thank you very much ! I used the first link you've put into your answer, and I translated the code from Java to C#. Everything is fine now ! – Antoni Maniscalco Aug 02 '17 at 12:16