ItemTouchHelperTest.java revision 8a11e6829c522aa1efcc903afa4c01d337082eab
1e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar/* 2e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar * Copyright (C) 2015 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 17e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarpackage android.support.v7.widget.helper; 18e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 19754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.v7.widget.helper.ItemTouchHelper.END; 20754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.v7.widget.helper.ItemTouchHelper.LEFT; 21754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.v7.widget.helper.ItemTouchHelper.RIGHT; 22754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.v7.widget.helper.ItemTouchHelper.START; 23754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.v7.widget.helper.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; 308a11e6829c522aa1efcc903afa4c01d337082eabChris Craikimport android.support.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; 356d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikasimport android.support.testutils.PollingCheck; 36350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapardimport android.support.v4.util.Pair; 370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.support.v7.util.TouchUtils; 38e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport android.support.v7.widget.BaseRecyclerViewInstrumentationTest; 39e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport android.support.v7.widget.RecyclerView; 40e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport android.support.v7.widget.WrappedRecyclerView; 41e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport android.view.Gravity; 42350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapardimport android.view.View; 4345d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas 4445d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport org.junit.Test; 4545d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikasimport org.junit.runner.RunWith; 46e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 47e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport java.util.ArrayList; 48e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarimport java.util.List; 49e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 5035232c6eaeb9b99f390cb8ef0ac83bf45fa0b3faAurimas Liutikas@LargeTest 510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar@RunWith(AndroidJUnit4.class) 52e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyarpublic class ItemTouchHelperTest extends BaseRecyclerViewInstrumentationTest { 53e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 54350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private static class RecyclerViewState { 55350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public TestAdapter mAdapter; 56350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public TestLayoutManager mLayoutManager; 57350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public WrappedRecyclerView mWrappedRecyclerView; 58350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 59e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 60e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private LoggingCalback mCalback; 61e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 62e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private LoggingItemTouchHelper mItemTouchHelper; 63e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 64e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private Boolean mSetupRTL; 65e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 66e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public ItemTouchHelperTest() { 67e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(false); 68e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 69e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 70350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private RecyclerViewState setupRecyclerView() throws Throwable { 71350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard RecyclerViewState rvs = new RecyclerViewState(); 72350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView = inflateWrappedRV(); 73350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mAdapter = new TestAdapter(10); 74350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager = new TestLayoutManager() { 75e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 76e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 77e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar detachAndScrapAttachedViews(recycler); 78e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar layoutRange(recycler, 0, Math.min(5, state.getItemCount())); 79e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar layoutLatch.countDown(); 80e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 81e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 82e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 83e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean canScrollHorizontally() { 84e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return false; 85e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 86e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 87e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 88e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean supportsPredictiveItemAnimations() { 89e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return false; 90e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 91e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar }; 92350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setFakeRTL(mSetupRTL); 93350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setAdapter(rvs.mAdapter); 94350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mWrappedRecyclerView.setLayoutManager(rvs.mLayoutManager); 95350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return rvs; 96350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 97350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 98350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard private RecyclerViewState setupItemTouchHelper(final RecyclerViewState rvs, int dragDirs, 99350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard int swipeDirs) throws Throwable { 100e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mCalback = new LoggingCalback(dragDirs, swipeDirs); 101e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mItemTouchHelper = new LoggingItemTouchHelper(mCalback); 10242e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas mActivityRule.runOnUiThread(new Runnable() { 103629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar @Override 104629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar public void run() { 105350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(rvs.mWrappedRecyclerView); 106629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar } 107629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar }); 108629687bba8da1a73c48d8fe87393a13581ce46caYigit Boyar 109350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return rvs; 110e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 111e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeLeft() throws Throwable { 114e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(LEFT, LEFT | RIGHT, -getActivity().getWindow().getDecorView().getWidth()); 115e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 116e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeRight() throws Throwable { 119e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(RIGHT, LEFT | RIGHT, getActivity().getWindow().getDecorView().getWidth()); 120e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 121e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeStart() throws Throwable { 124e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(START, START | END, -getActivity().getWindow().getDecorView().getWidth()); 125e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 126e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 1270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeEnd() throws Throwable { 129e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(END, START | END, getActivity().getWindow().getDecorView().getWidth()); 130e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 131e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 132fb06780abd4844c38173c183afff0fca3d954193Aurimas Liutikas // Test is disabled as it is flaky. 133fb06780abd4844c38173c183afff0fca3d954193Aurimas Liutikas @Suppress 13445d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN_MR1) 1350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeStartInRTL() throws Throwable { 137e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSetupRTL = true; 138e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(START, START | END, getActivity().getWindow().getDecorView().getWidth()); 139e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 140e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 14145d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN_MR1) 1420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar @Test 1430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar public void swipeEndInRTL() throws Throwable { 144e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSetupRTL = true; 145e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar basicSwipeTest(END, START | END, -getActivity().getWindow().getDecorView().getWidth()); 146e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 147e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 148350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Test 149350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void attachToNullRecycleViewDuringLongPress() throws Throwable { 150350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), END, 0); 151350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 152350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 153350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 154350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 155350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerView.ViewHolder target = mRecyclerView 156350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard .findViewHolderForAdapterPosition(1); 157350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard target.itemView.setOnLongClickListener(new View.OnLongClickListener() { 158350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 159350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public boolean onLongClick(View v) { 160350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(null); 161350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return false; 162350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 163350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 164350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard TouchUtils.longClickView(getInstrumentation(), target.itemView); 165350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 166350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 167350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Test 168350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void attachToAnotherRecycleViewDuringLongPress() throws Throwable { 169350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs2 = setupRecyclerView(); 170350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs2.mLayoutManager.expectLayouts(1); 171350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mActivityRule.runOnUiThread(new Runnable() { 172350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 173350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public void run() { 174350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard getActivity().getContainer().addView(rvs2.mWrappedRecyclerView); 175350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 176350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 177350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs2.mLayoutManager.waitForLayout(1); 178350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 179350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), END, 0); 180350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 181350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 182350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 183350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 184350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerView.ViewHolder target = mRecyclerView 185350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard .findViewHolderForAdapterPosition(1); 186350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard target.itemView.setOnLongClickListener(new View.OnLongClickListener() { 187350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 188350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public boolean onLongClick(View v) { 189350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mItemTouchHelper.attachToRecyclerView(rvs2.mWrappedRecyclerView); 190350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return false; 191350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 192350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard }); 193350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard TouchUtils.longClickView(getInstrumentation(), target.itemView); 194350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard assertEquals(0, mCalback.mHasDragFlag.size()); 195350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 196350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 197e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public void basicSwipeTest(int dir, int swipeDirs, int targetX) throws Throwable { 198350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard final RecyclerViewState rvs = setupItemTouchHelper(setupRecyclerView(), 0, swipeDirs); 199350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 200350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard setRecyclerView(rvs.mWrappedRecyclerView); 201350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 202e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 203e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final RecyclerView.ViewHolder target = mRecyclerView 204e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar .findViewHolderForAdapterPosition(1); 2050a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar TouchUtils.dragViewToX(getInstrumentation(), target.itemView, Gravity.CENTER, targetX); 206277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas 207277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas PollingCheck.waitFor(1000, new PollingCheck.PollingCheckCondition() { 208277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas @Override 209277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas public boolean canProceed() { 210277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas return mCalback.getSwipe(target) != null; 211277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas } 212277b9d6d56ba5a21240710b27c6e431498392a08Aurimas Liutikas }); 213e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final SwipeRecord swipe = mCalback.getSwipe(target); 214e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertNotNull(swipe); 215e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(dir, swipe.dir); 216e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(1, mItemTouchHelper.mRecoverAnimations.size()); 217e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(1, mItemTouchHelper.mPendingCleanup.size()); 218e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar // get rid of the view 219350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.expectLayouts(1); 220350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mAdapter.deleteAndNotify(1, 1); 221350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard rvs.mLayoutManager.waitForLayout(1); 222e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar waitForAnimations(); 223e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(0, mItemTouchHelper.mRecoverAnimations.size()); 224e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertEquals(0, mItemTouchHelper.mPendingCleanup.size()); 225e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar assertTrue(mCalback.isCleared(target)); 226e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 227e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 228e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private void waitForAnimations() throws InterruptedException { 229e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar while (mRecyclerView.getItemAnimator().isRunning()) { 230e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar Thread.sleep(100); 231e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 232e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 233e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 234e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class LoggingCalback extends SimpleCallback { 235e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 236e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<MoveRecord> mMoveRecordList = new ArrayList<MoveRecord>(); 237e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 238e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<SwipeRecord> mSwipeRecords = new ArrayList<SwipeRecord>(); 239e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 240e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private List<RecyclerView.ViewHolder> mCleared = new ArrayList<RecyclerView.ViewHolder>(); 241e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 242350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard public List<Pair<RecyclerView, RecyclerView.ViewHolder>> mHasDragFlag = new ArrayList<>(); 243350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 24445d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas LoggingCalback(int dragDirs, int swipeDirs) { 245e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(dragDirs, swipeDirs); 246e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 247e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 248e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2498a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public boolean onMove(@NonNull RecyclerView recyclerView, 2508a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder viewHolder, 2518a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder target) { 252e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mMoveRecordList.add(new MoveRecord(viewHolder, target)); 253e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return true; 254e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 255e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 256e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2578a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { 258e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mSwipeRecords.add(new SwipeRecord(viewHolder, direction)); 259e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 260e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 261e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public MoveRecord getMove(RecyclerView.ViewHolder vh) { 262e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar for (MoveRecord move : mMoveRecordList) { 263e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar if (move.from == vh) { 264e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return move; 265e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 266e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 267e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return null; 268e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 269e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 270e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar @Override 2718a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void clearView(@NonNull RecyclerView recyclerView, 2728a11e6829c522aa1efcc903afa4c01d337082eabChris Craik @NonNull RecyclerView.ViewHolder viewHolder) { 273e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super.clearView(recyclerView, viewHolder); 274e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar mCleared.add(viewHolder); 275e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 276e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 277350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard @Override 278350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard boolean hasDragFlag(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 279350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard mHasDragFlag.add(new Pair<>(recyclerView, viewHolder)); 280350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard return super.hasDragFlag(recyclerView, viewHolder); 281350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard } 282350a38a3cc040891c3f94b1fd9c1642aa29a7db3shepshapard 283e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public SwipeRecord getSwipe(RecyclerView.ViewHolder vh) { 284e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar for (SwipeRecord swipe : mSwipeRecords) { 285e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar if (swipe.viewHolder == vh) { 286e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return swipe; 287e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 288e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 289e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return null; 290e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 291e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 292e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public boolean isCleared(RecyclerView.ViewHolder vh) { 293e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar return mCleared.contains(vh); 294e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 295e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 296e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 297e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class LoggingItemTouchHelper extends ItemTouchHelper { 298e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 299e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public LoggingItemTouchHelper(Callback callback) { 300e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar super(callback); 301e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 302e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 303e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 304e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class SwipeRecord { 305e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 306e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar RecyclerView.ViewHolder viewHolder; 307e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 308e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar int dir; 309e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 310e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar public SwipeRecord(RecyclerView.ViewHolder viewHolder, int dir) { 311e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.viewHolder = viewHolder; 312e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.dir = dir; 313e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 314e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 315e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 316e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar private static class MoveRecord { 317e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 318e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar final int fromPos, toPos; 319e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 320e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar RecyclerView.ViewHolder from, to; 321e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar 32245d07c8efb62ee378db48884989e5b05b5494981Aurimas Liutikas MoveRecord(RecyclerView.ViewHolder from, RecyclerView.ViewHolder to) { 323e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.from = from; 324e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar this.to = to; 325e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar fromPos = from.getAdapterPosition(); 326e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar toPos = to.getAdapterPosition(); 327e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 328e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar } 329e71a1df9b3c0e1bd3c21a1b3dd20a41790d4a950Yigit Boyar} 330