blob: 1a4d225ea54e1ff769e6e046d2aa50cf83af95df [file] [log] [blame]
/*
* 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.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import android.graphics.Rect;
import android.test.suitebuilder.annotation.MediumTest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static android.support.v7.widget.StaggeredGridLayoutManager.GAP_HANDLING_NONE;
import static org.junit.Assert.assertNull;
@RunWith(Parameterized.class)
@MediumTest
public class StaggeredGridLayoutManagerGapTest extends BaseStaggeredGridLayoutManagerTest {
private final Config mConfig;
private final int mDeletePosition;
private final int mDeleteCount;
public StaggeredGridLayoutManagerGapTest(Config config, int deletePosition, int deleteCount) {
mConfig = config;
mDeletePosition = deletePosition;
mDeleteCount = deleteCount;
}
@Parameterized.Parameters(name = "config={0} deletePos={1} deleteCount={2}")
public static List<Object[]> getParams() throws CloneNotSupportedException {
List<Config> variations = createBaseVariations();
List<Object[]> params = new ArrayList<>();
for (Config config : variations) {
for (int deleteCount = 1; deleteCount < config.mSpanCount * 2; deleteCount++) {
for (int deletePosition = config.mSpanCount - 1;
deletePosition < config.mSpanCount + 2; deletePosition++) {
params.add(new Object[]{config.clone(), deletePosition, deleteCount});
}
}
}
return params;
}
@Test
public void gapAtTheBeginningOfTheListTest() throws Throwable {
if (mConfig.mSpanCount < 2 || mConfig.mGapStrategy == GAP_HANDLING_NONE) {
return;
}
if (mConfig.mItemCount < 100) {
mConfig.itemCount(100);
}
setupByConfig(mConfig);
final RecyclerView.Adapter adapter = mAdapter;
waitFirstLayout();
// scroll far away
smoothScrollToPosition(mConfig.mItemCount / 2);
checkForMainThreadException();
// assert to be deleted child is not visible
assertNull(" test sanity, to be deleted child should be invisible",
mRecyclerView.findViewHolderForLayoutPosition(mDeletePosition));
// delete the child and notify
mAdapter.deleteAndNotify(mDeletePosition, mDeleteCount);
getInstrumentation().waitForIdleSync();
mLayoutManager.expectLayouts(1);
smoothScrollToPosition(0);
mLayoutManager.waitForLayout(2);
checkForMainThreadException();
// due to data changes, first item may become visible before others which will cause
// smooth scrolling to stop. Triggering it twice more is a naive hack.
// Until we have time to consider it as a bug, this is the only workaround.
smoothScrollToPosition(0);
Thread.sleep(500);
checkForMainThreadException();
smoothScrollToPosition(0);
Thread.sleep(500);
checkForMainThreadException();
// some animations should happen and we should recover layout
final Map<Item, Rect> actualCoords = mLayoutManager.collectChildCoordinates();
// now layout another RV with same adapter
removeRecyclerView();
setupByConfig(mConfig);
mRecyclerView.setAdapter(adapter);// use same adapter so that items can be matched
waitFirstLayout();
final Map<Item, Rect> desiredCoords = mLayoutManager.collectChildCoordinates();
assertRectSetsEqual(" when an item from the start of the list is deleted, "
+ "layout should recover the state once scrolling is stopped",
desiredCoords, actualCoords);
checkForMainThreadException();
}
}