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 :
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 :
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 :
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 !