1a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak/* 2a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * Copyright (C) 2018 The Android Open Source Project 3a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * 4a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * Licensed under the Apache License, Version 2.0 (the "License"); 5a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * you may not use this file except in compliance with the License. 6a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * You may obtain a copy of the License at 7a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * 8a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * http://www.apache.org/licenses/LICENSE-2.0 9a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * 10a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * Unless required by applicable law or agreed to in writing, software 11a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * distributed under the License is distributed on an "AS IS" BASIS, 12a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * See the License for the specific language governing permissions and 14a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak * limitations under the License. 15a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak */ 16a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 17a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakpackage androidx.viewpager2.widget.swipe; 18a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 19a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport static org.hamcrest.Matchers.allOf; 20a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport static org.hamcrest.Matchers.greaterThanOrEqualTo; 21a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport static org.hamcrest.Matchers.lessThanOrEqualTo; 22a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport static org.junit.Assert.assertThat; 23a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 24a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport androidx.fragment.app.Fragment; 25a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport androidx.viewpager2.widget.ViewPager2; 26a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 27a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport java.util.Random; 28a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakimport java.util.concurrent.atomic.AtomicInteger; 29a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 30a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzakpublic class FragmentAdapterActivity extends BaseActivity { 31a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak private static final Random RANDOM = new Random(); 32a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 33a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak private AtomicInteger mAttachCount = new AtomicInteger(0); 34a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak private AtomicInteger mDestroyCount = new AtomicInteger(0); 35a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak private PageFragment[] mFragments; 36a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 37a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 38a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak protected void setAdapter() { 39a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mFragments = new PageFragment[mTotalPages]; 40a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 41a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak ViewPager2.FragmentProvider fragmentProvider = new ViewPager2.FragmentProvider() { 42a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak final boolean[] mWasEverAttached = new boolean[mTotalPages]; 43a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 44a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 45a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public Fragment getItem(final int position) { 46a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak PageFragment fragment = PageFragment.create(valueForPosition(position)); 47a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 48a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak fragment.mOnAttachListener = new PageFragment.EventListener() { 49a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 50a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public void onEvent(PageFragment fragment) { 51a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mAttachCount.incrementAndGet(); 52a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mWasEverAttached[position] = true; 53a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 54a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak }; 55a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 56a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak fragment.mOnDestroyListener = new PageFragment.EventListener() { 57a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 58a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public void onEvent(PageFragment fragment) { 59a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mDestroyCount.incrementAndGet(); 60a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 61a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak }; 62a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 63a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak return mFragments[position] = fragment; 64a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 65a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 66a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak private int valueForPosition(int position) { 67a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak // only supply correct value ones; then rely on it being kept by Fragment state 68a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak return mWasEverAttached[position] 69a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak ? RANDOM.nextInt() // junk value to be overridden by state saved value 70a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak : position; 71a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 72a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 73a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 74a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public int getCount() { 75a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak return mTotalPages; 76a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 77a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak }; 78a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 79a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mViewPager.setAdapter(getSupportFragmentManager(), fragmentProvider, 80a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak ViewPager2.FragmentRetentionPolicy.SAVE_STATE); 81a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 82a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 83a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 84a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public void updatePage(int pageIx, int newValue) { 85a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak mFragments[pageIx].updateValue(newValue); 86a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 87a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak 88a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak @Override 89a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak public void validateState() { 90a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak assertThat(mAttachCount.get() - mDestroyCount.get(), 91a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(4))); 92a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak } 93a6b9e5ba410f128dc61ca899153ab05b16ae5023Jakub Gielzak} 94