1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.providers.media.photopicker.ui; 18 19 import android.content.Context; 20 import android.view.View; 21 22 import androidx.viewpager2.widget.CompositePageTransformer; 23 import androidx.viewpager2.widget.MarginPageTransformer; 24 import androidx.viewpager2.widget.ViewPager2; 25 26 import com.android.providers.media.R; 27 import com.android.providers.media.photopicker.data.MuteStatus; 28 import com.android.providers.media.photopicker.data.model.Item; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** 34 * A wrapper class to assist in initializing {@link ViewPager2} and {@link PreviewAdapter}. This 35 * class also supports some of {@link ViewPager2} and {@link PreviewAdapter} methods to avoid 36 * exposing these objects outside this class. 37 * The class also supports registering {@link ViewPager2.OnPageChangeCallback} and unregister the 38 * same onDestroy(). 39 */ 40 class ViewPager2Wrapper { 41 private final ViewPager2 mViewPager; 42 private final PreviewAdapter mAdapter; 43 private final List<ViewPager2.OnPageChangeCallback> mOnPageChangeCallbacks = new ArrayList<>(); 44 ViewPager2Wrapper(ViewPager2 viewPager, List<Item> selectedItems, MuteStatus muteStatus)45 ViewPager2Wrapper(ViewPager2 viewPager, List<Item> selectedItems, MuteStatus muteStatus) { 46 mViewPager = viewPager; 47 48 final Context context = mViewPager.getContext(); 49 50 mAdapter = new PreviewAdapter(context, muteStatus); 51 mAdapter.updateItemList(selectedItems); 52 mViewPager.setAdapter(mAdapter); 53 54 CompositePageTransformer compositePageTransformer = new CompositePageTransformer(); 55 compositePageTransformer.addTransformer(new MarginPageTransformer( 56 context.getResources().getDimensionPixelSize(R.dimen.preview_viewpager_margin))); 57 compositePageTransformer.addTransformer(new PlayerPageTransformer()); 58 mViewPager.setPageTransformer(compositePageTransformer); 59 } 60 61 /** 62 * Registers given {@link ViewPager2.OnPageChangeCallback} to the {@link ViewPager2}. This class 63 * also takes care of unregistering the callback onDestroy() 64 */ addOnPageChangeCallback(ViewPager2.OnPageChangeCallback onPageChangeCallback)65 public void addOnPageChangeCallback(ViewPager2.OnPageChangeCallback onPageChangeCallback) { 66 mOnPageChangeCallbacks.add(onPageChangeCallback); 67 mViewPager.registerOnPageChangeCallback(onPageChangeCallback); 68 } 69 getItemAt(int position)70 public Item getItemAt(int position) { 71 return getItemAtInternal(position); 72 } 73 getCurrentItem()74 public Item getCurrentItem() { 75 return getItemAtInternal(mViewPager.getCurrentItem()); 76 } 77 getItemAtInternal(int position)78 private Item getItemAtInternal(int position) { 79 return mAdapter.getItem(position); 80 } 81 onStop()82 public void onStop() { 83 mAdapter.onStop(); 84 } 85 onStart()86 public void onStart() { 87 // TODO(b/197083539): Restore the playback state here. 88 // This forces PageTransformer#transformPage call and assists in ExoPlayer initialization. 89 mViewPager.requestTransform(); 90 } 91 onDestroy()92 public void onDestroy() { 93 for (ViewPager2.OnPageChangeCallback callback : mOnPageChangeCallbacks) { 94 mViewPager.unregisterOnPageChangeCallback(callback); 95 } 96 mOnPageChangeCallbacks.clear(); 97 mAdapter.onDestroy(); 98 } 99 100 private class PlayerPageTransformer implements ViewPager2.PageTransformer { 101 @Override transformPage(View view, float position)102 public void transformPage(View view, float position) { 103 // We are only interested in position == 0.0. Only position=0.0 indicates that the page 104 // is selected. 105 if (position != 0) return; 106 107 mAdapter.onHandlePageSelected(view); 108 } 109 } 110 } 111