1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package androidx.recyclerview.widget; 17 18 import static androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL; 19 import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertTrue; 23 24 import android.graphics.Rect; 25 import android.support.test.filters.MediumTest; 26 import android.view.View; 27 import android.view.ViewGroup; 28 29 import androidx.annotation.NonNull; 30 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 import org.junit.runners.Parameterized; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 @MediumTest 39 @RunWith(Parameterized.class) 40 public class GridLayoutManagerCustomSizeInScrollDirectionTest extends BaseGridLayoutManagerTest { 41 @Parameterized.Parameters(name = "addDecorOffsets:{1},addMargins:{2},config:{0}") 42 public static List<Object[]> getParams() { 43 List<Object[]> params = new ArrayList<>(); 44 Boolean[] options = new Boolean[]{true, false}; 45 for (boolean addMargins : options) { 46 for (boolean addDecorOffsets : options) { 47 params.add(new Object[] { 48 new Config(3, HORIZONTAL, false), addDecorOffsets, addMargins}); 49 params.add(new Object[] { 50 new Config(3, VERTICAL, false), addDecorOffsets, addMargins}); 51 } 52 } 53 return params; 54 } 55 56 private final boolean mAddDecorOffsets; 57 private final boolean mAddMargins; 58 private final Config mConfig; 59 60 public GridLayoutManagerCustomSizeInScrollDirectionTest(Config config, boolean addDecorOffsets, 61 boolean addMargins) { 62 mConfig = config; 63 mAddDecorOffsets = addDecorOffsets; 64 mAddMargins = addMargins; 65 } 66 67 @Test 68 public void customSizeInScrollDirectionTest() throws Throwable { 69 final int decorOffset = mAddDecorOffsets ? 7 : 0; 70 final int margin = mAddMargins ? 11 : 0; 71 final int[] sizePerPosition = new int[]{3, 5, 9, 21, 3, 5, 9, 6, 9, 1}; 72 final int[] expectedSizePerPosition = new int[]{9, 9, 9, 21, 3, 5, 9, 9, 9, 1}; 73 74 final GridTestAdapter testAdapter = new GridTestAdapter(10) { 75 @Override 76 public void onBindViewHolder(@NonNull TestViewHolder holder, 77 int position) { 78 super.onBindViewHolder(holder, position); 79 ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) 80 holder.itemView.getLayoutParams(); 81 if (layoutParams == null) { 82 layoutParams = new ViewGroup.MarginLayoutParams( 83 ViewGroup.LayoutParams.WRAP_CONTENT, 84 ViewGroup.LayoutParams.WRAP_CONTENT); 85 holder.itemView.setLayoutParams(layoutParams); 86 } 87 final int size = sizePerPosition[position]; 88 if (mConfig.mOrientation == HORIZONTAL) { 89 layoutParams.width = size; 90 layoutParams.leftMargin = margin; 91 layoutParams.rightMargin = margin; 92 } else { 93 layoutParams.height = size; 94 layoutParams.topMargin = margin; 95 layoutParams.bottomMargin = margin; 96 } 97 } 98 }; 99 testAdapter.setFullSpan(3, 5); 100 final RecyclerView rv = setupBasic(mConfig, testAdapter); 101 if (mAddDecorOffsets) { 102 rv.addItemDecoration(new RecyclerView.ItemDecoration() { 103 @Override 104 public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 105 RecyclerView.State state) { 106 if (mConfig.mOrientation == HORIZONTAL) { 107 outRect.set(decorOffset, 0, decorOffset, 0); 108 } else { 109 outRect.set(0, decorOffset, 0, decorOffset); 110 } 111 } 112 }); 113 } 114 waitForFirstLayout(rv); 115 116 assertTrue("[test sanity] some views should be laid out", 117 mRecyclerView.getChildCount() > 0); 118 for (int i = 0; i < mRecyclerView.getChildCount(); i++) { 119 View child = mRecyclerView.getChildAt(i); 120 final int size = mConfig.mOrientation == HORIZONTAL ? child.getWidth() 121 : child.getHeight(); 122 assertEquals("child " + i + " should have the size specified in its layout params", 123 expectedSizePerPosition[i], size); 124 } 125 checkForMainThreadException(); 126 } 127 } 128