ItemTouchHelperTest.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
1e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 3e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * 4e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * you may not use this file except in compliance with the License. 6e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * You may obtain a copy of the License at 7e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * 8e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * 10e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * See the License for the specific language governing permissions and 14e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * limitations under the License. 15e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar */ 16e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.recyclerview.widget; 18e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.ItemTouchHelper.END; 20ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.ItemTouchHelper.LEFT; 21ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.ItemTouchHelper.RIGHT; 22ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.ItemTouchHelper.START; 23ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback; 240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar 25754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertEquals; 26754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertNotNull; 27754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertTrue; 2845d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas 2945d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport android.os.Build; 30ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull; 3135232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikasimport android.support.test.filters.LargeTest; 3245d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport android.support.test.filters.SdkSuppress; 33fb06780abd4844c38173c183afff0fca3d954193Aurimas Liutikasimport android.support.test.filters.Suppress; 340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.support.test.runner.AndroidJUnit4; 35ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.util.Pair; 36ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas 37e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport android.view.Gravity; 38350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapardimport android.view.View; 3945d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas 4045d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport org.junit.Test; 4145d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport org.junit.runner.RunWith; 42e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 43e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport java.util.ArrayList; 44e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport java.util.List; 45e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 4667171c81b114f5a858dd55ec712cb584f255fc93Aurimas Liutikasimport androidx.testutils.PollingCheck; 4767171c81b114f5a858dd55ec712cb584f255fc93Aurimas Liutikas 4835232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas@LargeTest 490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar@RunWith(AndroidJUnit4.class) 50e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarpublic class ItemTouchHelperTest extends BaseRecyclerViewInstrumentationTest { 51e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 52350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private static class RecyclerViewState { 53350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public TestAdapter mAdapter; 54350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public TestLayoutManager mLayoutManager; 55350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public WrappedRecyclerView mWrappedRecyclerView; 56350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 57e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 58e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private LoggingCalback mCalback; 59e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 60e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private LoggingItemTouchHelper mItemTouchHelper; 61e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 62e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private Boolean mSetupRTL; 63e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 64e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public ItemTouchHelperTest() { 65e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(false); 66e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 67e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 68350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private RecyclerViewState setupRecyclerView() throws Throwable { 69350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard RecyclerViewState rvs = new RecyclerViewState(); 70350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView = inflateWrappedRV(); 71350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mAdapter = new TestAdapter(10); 72350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager = new TestLayoutManager() { 73e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 74e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 75e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar detachAndScrapAttachedViews(recycler); 76e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar layoutRange(recycler, 0, Math.min(5, state.getItemCount())); 77e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar layoutLatch.countDown(); 78e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 79e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 80e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 81e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean canScrollHorizontally() { 82e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return false; 83e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 84e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 85e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 86e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean supportsPredictiveItemAnimations() { 87e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return false; 88e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 89e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar }; 90350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setFakeRTL(mSetupRTL); 91350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setAdapter(rvs.mAdapter); 92350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setLayoutManager(rvs.mLayoutManager); 93350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return rvs; 94350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 95350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 96350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private RecyclerViewState setupItemTouchHelper(final RecyclerViewState rvs, int dragDirs, 97350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard int swipeDirs) throws Throwable { 98e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mCalback = new LoggingCalback(dragDirs, swipeDirs); 99e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mItemTouchHelper = new LoggingItemTouchHelper(mCalback); 10042e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas mActivityRule.runOnUiThread(new Runnable() { 101629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar @Override 102629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar public void run() { 103350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(rvs.mWrappedRecyclerView); 104629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar } 105629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar }); 106629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar 107350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return rvs; 108e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 109e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeLeft() throws Throwable { 112e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(LEFT, LEFT | RIGHT, -getActivity().getWindow().getDecorView().getWidth()); 113e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 114e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeRight() throws Throwable { 117e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(RIGHT, LEFT | RIGHT, getActivity().getWindow().getDecorView().getWidth()); 118e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 119e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeStart() throws Throwable { 122e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(START, START | END, -getActivity().getWindow().getDecorView().getWidth()); 123e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 124e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeEnd() throws Throwable { 127e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(END, START | END, getActivity().getWindow().getDecorView().getWidth()); 128e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 129e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 130fb06780abd4844c38173c183afff0fca3d954193Aurimas Liutikas // Test is disabled as it is flaky. 131fb06780abd4844c38173c183afff0fca3d954193Aurimas Liutikas @Suppress 13245d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN_MR1) 1330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeStartInRTL() throws Throwable { 135e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSetupRTL = true; 136e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(START, START | END, getActivity().getWindow().getDecorView().getWidth()); 137e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 138e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 13945d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN_MR1) 1400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeEndInRTL() throws Throwable { 142e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSetupRTL = true; 143e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(END, START | END, -getActivity().getWindow().getDecorView().getWidth()); 144e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 145e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 146350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Test 147350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void attachToNullRecycleViewDuringLongPress() throws Throwable { 148350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), END, 0); 149350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 150350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 151350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 152350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 153350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerView.ViewHolder target = mRecyclerView 154350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard .findViewHolderForAdapterPosition(1); 155350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard target.itemView.setOnLongClickListener(new View.OnLongClickListener() { 156350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 157350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public boolean onLongClick(View v) { 158350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(null); 159350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return false; 160350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 161350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 162350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard TouchUtils.longClickView(getInstrumentation(), target.itemView); 163350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 164350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 165350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Test 166350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void attachToAnotherRecycleViewDuringLongPress() throws Throwable { 167350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs2 = setupRecyclerView(); 168350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs2.mLayoutManager.expectLayouts(1); 169350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mActivityRule.runOnUiThread(new Runnable() { 170350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 171350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void run() { 172350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard getActivity().getContainer().addView(rvs2.mWrappedRecyclerView); 173350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 174350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 175350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs2.mLayoutManager.waitForLayout(1); 176350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 177350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), END, 0); 178350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 179350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 180350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 181350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 182350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerView.ViewHolder target = mRecyclerView 183350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard .findViewHolderForAdapterPosition(1); 184350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard target.itemView.setOnLongClickListener(new View.OnLongClickListener() { 185350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 186350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public boolean onLongClick(View v) { 187350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(rvs2.mWrappedRecyclerView); 188350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return false; 189350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 190350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 191350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard TouchUtils.longClickView(getInstrumentation(), target.itemView); 192350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard assertEquals(0, mCalback.mHasDragFlag.size()); 193350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 194350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 195e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public void basicSwipeTest(int dir, int swipeDirs, int targetX) throws Throwable { 196350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), 0, swipeDirs); 197350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 198350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 199350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 200e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 201e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final RecyclerView.ViewHolder target = mRecyclerView 202e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar .findViewHolderForAdapterPosition(1); 2030a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar TouchUtils.dragViewToX(getInstrumentation(), target.itemView, Gravity.CENTER, targetX); 204277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas 205277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas PollingCheck.waitFor(1000, new PollingCheck.PollingCheckCondition() { 206277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas @Override 207277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas public boolean canProceed() { 208277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas return mCalback.getSwipe(target) != null; 209277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas } 210277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas }); 211e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final SwipeRecord swipe = mCalback.getSwipe(target); 212e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertNotNull(swipe); 213e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(dir, swipe.dir); 214e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(1, mItemTouchHelper.mRecoverAnimations.size()); 215e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(1, mItemTouchHelper.mPendingCleanup.size()); 216e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar // get rid of the view 217350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 218350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mAdapter.deleteAndNotify(1, 1); 219350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 220e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar waitForAnimations(); 221e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(0, mItemTouchHelper.mRecoverAnimations.size()); 222e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(0, mItemTouchHelper.mPendingCleanup.size()); 223e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertTrue(mCalback.isCleared(target)); 224e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 225e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 226e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private void waitForAnimations() throws InterruptedException { 227e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar while (mRecyclerView.getItemAnimator().isRunning()) { 228e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar Thread.sleep(100); 229e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 230e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 231e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 232e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class LoggingCalback extends SimpleCallback { 233e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 234e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<MoveRecord> mMoveRecordList = new ArrayList<MoveRecord>(); 235e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 236e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<SwipeRecord> mSwipeRecords = new ArrayList<SwipeRecord>(); 237e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 238e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<RecyclerView.ViewHolder> mCleared = new ArrayList<RecyclerView.ViewHolder>(); 239e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 240350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public List<Pair<RecyclerView, RecyclerView.ViewHolder>> mHasDragFlag = new ArrayList<>(); 241350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 24245d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas LoggingCalback(int dragDirs, int swipeDirs) { 243e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(dragDirs, swipeDirs); 244e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 245e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 246e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2478a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public boolean onMove(@NonNull RecyclerView recyclerView, 2488a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder viewHolder, 2498a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder target) { 250e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mMoveRecordList.add(new MoveRecord(viewHolder, target)); 251e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return true; 252e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 253e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 254e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2558a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { 256e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSwipeRecords.add(new SwipeRecord(viewHolder, direction)); 257e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 258e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 259e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public MoveRecord getMove(RecyclerView.ViewHolder vh) { 260e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar for (MoveRecord move : mMoveRecordList) { 261e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar if (move.from == vh) { 262e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return move; 263e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 264e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 265e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return null; 266e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 267e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 268e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2698a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void clearView(@NonNull RecyclerView recyclerView, 2708a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder viewHolder) { 271e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super.clearView(recyclerView, viewHolder); 272e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mCleared.add(viewHolder); 273e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 274e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 275350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 276350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard boolean hasDragFlag(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 277350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mHasDragFlag.add(new Pair<>(recyclerView, viewHolder)); 278350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return super.hasDragFlag(recyclerView, viewHolder); 279350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 280350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 281e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public SwipeRecord getSwipe(RecyclerView.ViewHolder vh) { 282e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar for (SwipeRecord swipe : mSwipeRecords) { 283e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar if (swipe.viewHolder == vh) { 284e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return swipe; 285e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 286e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 287e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return null; 288e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 289e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 290e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean isCleared(RecyclerView.ViewHolder vh) { 291e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return mCleared.contains(vh); 292e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 293e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 294e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 295e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class LoggingItemTouchHelper extends ItemTouchHelper { 296e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 297e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public LoggingItemTouchHelper(Callback callback) { 298e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(callback); 299e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 300e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 301e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 302e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class SwipeRecord { 303e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 304e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar RecyclerView.ViewHolder viewHolder; 305e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 306e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar int dir; 307e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 308e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public SwipeRecord(RecyclerView.ViewHolder viewHolder, int dir) { 309e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.viewHolder = viewHolder; 310e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.dir = dir; 311e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 312e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 313e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 314e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class MoveRecord { 315e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 316e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final int fromPos, toPos; 317e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 318e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar RecyclerView.ViewHolder from, to; 319e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 32045d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas MoveRecord(RecyclerView.ViewHolder from, RecyclerView.ViewHolder to) { 321e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.from = from; 322e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.to = to; 323e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar fromPos = from.getAdapterPosition(); 324e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar toPos = to.getAdapterPosition(); 325e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 326e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 327e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar} 328