/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.support.v7.widget; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import android.support.test.InstrumentationRegistry; import android.test.suitebuilder.annotation.MediumTest; import android.view.View; import java.util.ArrayList; import java.util.List; import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL; import static org.junit.Assert.*; @RunWith(Parameterized.class) public class LinearLayoutManagerPrepareForDropTest extends BaseLinearLayoutManagerTest { final BaseLinearLayoutManagerTest.Config mConfig; final SelectTargetChildren mSelectTargetChildren; public LinearLayoutManagerPrepareForDropTest( Config config, SelectTargetChildren selectTargetChildren) { mConfig = config; mSelectTargetChildren = selectTargetChildren; } @Parameterized.Parameters(name = "{0}_{1}") public static Iterable params() { SelectTargetChildren[] selectors = new SelectTargetChildren[]{ new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{1, 0}; } }, new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{0, 1}; } }, new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{childCount - 1, childCount - 2}; } }, new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{childCount - 2, childCount - 1}; } }, new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{childCount / 2, childCount / 2 + 1}; } }, new SelectTargetChildren() { @Override public int[] selectTargetChildren(int childCount) { return new int[]{childCount / 2 + 1, childCount / 2}; } } }; List variations = new ArrayList<>(); for (SelectTargetChildren selector : selectors) { for (BaseLinearLayoutManagerTest.Config config : createBaseVariations()) { variations.add(new Object[]{config, selector}); } } return variations; } @Test @MediumTest public void prepareForDropTest() throws Throwable { final Config config = (Config) mConfig.clone(); config.mTestAdapter = new BaseRecyclerViewInstrumentationTest.TestAdapter(100) { @Override public void onBindViewHolder(BaseRecyclerViewInstrumentationTest.TestViewHolder holder, int position) { super.onBindViewHolder(holder, position); if (config.mOrientation == HORIZONTAL) { final int base = mLayoutManager.getWidth() / 5; final int itemRand = holder.mBoundItem.mText.hashCode() % base; holder.itemView.setMinimumWidth(base + itemRand); } else { final int base = mLayoutManager.getHeight() / 5; final int itemRand = holder.mBoundItem.mText.hashCode() % base; holder.itemView.setMinimumHeight(base + itemRand); } } }; setupByConfig(config, true); mLayoutManager.expectLayouts(1); scrollToPosition(mTestAdapter.getItemCount() / 2); mLayoutManager.waitForLayout(1); int[] positions = mSelectTargetChildren.selectTargetChildren(mRecyclerView.getChildCount()); final View fromChild = mLayoutManager.getChildAt(positions[0]); final int fromPos = mLayoutManager.getPosition(fromChild); final View onChild = mLayoutManager.getChildAt(positions[1]); final int toPos = mLayoutManager.getPosition(onChild); final OrientationHelper helper = mLayoutManager.mOrientationHelper; final int dragCoordinate; final boolean towardsHead = toPos < fromPos; final int referenceLine; if (config.mReverseLayout == towardsHead) { referenceLine = helper.getDecoratedEnd(onChild); dragCoordinate = referenceLine + 3 - helper.getDecoratedMeasurement(fromChild); } else { referenceLine = helper.getDecoratedStart(onChild); dragCoordinate = referenceLine - 3; } mLayoutManager.expectLayouts(2); final int x, y; if (config.mOrientation == HORIZONTAL) { x = dragCoordinate; y = fromChild.getTop(); } else { y = dragCoordinate; x = fromChild.getLeft(); } runTestOnUiThread(new Runnable() { @Override public void run() { mTestAdapter.moveInUIThread(fromPos, toPos); mTestAdapter.notifyItemMoved(fromPos, toPos); mLayoutManager.prepareForDrop(fromChild, onChild, x, y); } }); mLayoutManager.waitForLayout(2); assertSame(fromChild, mRecyclerView.findViewHolderForAdapterPosition(toPos).itemView); // make sure it has the position we wanted if (config.mReverseLayout == towardsHead) { assertEquals(referenceLine, helper.getDecoratedEnd(fromChild)); } else { assertEquals(referenceLine, helper.getDecoratedStart(fromChild)); } } protected interface SelectTargetChildren { int[] selectTargetChildren(int childCount); } }