1/* 2 * Copyright (C) 2015 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 17package com.android.setupwizardlib.test; 18 19import android.graphics.Bitmap; 20import android.graphics.Canvas; 21import android.graphics.Color; 22import android.graphics.Paint; 23import android.graphics.PorterDuff; 24import android.graphics.PorterDuffXfermode; 25import android.graphics.Xfermode; 26import android.graphics.drawable.ColorDrawable; 27import android.graphics.drawable.Drawable; 28import android.support.v7.widget.LinearLayoutManager; 29import android.support.v7.widget.RecyclerView; 30import android.test.AndroidTestCase; 31import android.test.suitebuilder.annotation.SmallTest; 32import android.view.View; 33import android.view.ViewGroup; 34 35import com.android.setupwizardlib.DividerItemDecoration; 36 37public class DividerItemDecorationTest extends AndroidTestCase { 38 39 @SmallTest 40 public void testDivider() { 41 final DividerItemDecoration decoration = new DividerItemDecoration(); 42 Drawable divider = new ColorDrawable(); 43 decoration.setDivider(divider); 44 assertSame("Divider should be same as set", divider, decoration.getDivider()); 45 } 46 47 @SmallTest 48 public void testDividerHeight() { 49 final DividerItemDecoration decoration = new DividerItemDecoration(); 50 decoration.setDividerHeight(123); 51 assertEquals("Divider height should be 123", 123, decoration.getDividerHeight()); 52 } 53 54 @SmallTest 55 public void testShouldDrawDividerBelowWithEitherCondition() { 56 // Set up the item decoration, with 1px red divider line 57 final DividerItemDecoration decoration = new DividerItemDecoration(); 58 Drawable divider = new ColorDrawable(Color.RED); 59 decoration.setDivider(divider); 60 decoration.setDividerHeight(1); 61 62 Bitmap bitmap = drawDecoration(decoration, true, true); 63 64 // Draw the expected result on a bitmap 65 Bitmap expectedBitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_4444); 66 Canvas expectedCanvas = new Canvas(expectedBitmap); 67 Paint paint = new Paint(); 68 paint.setColor(Color.RED); 69 expectedCanvas.drawRect(0, 5, 20, 6, paint); 70 expectedCanvas.drawRect(0, 10, 20, 11, paint); 71 expectedCanvas.drawRect(0, 15, 20, 16, paint); 72 // Compare the two bitmaps 73 assertBitmapEquals(expectedBitmap, bitmap); 74 75 bitmap.recycle(); 76 bitmap = drawDecoration(decoration, false, true); 77 // should still be the same. 78 assertBitmapEquals(expectedBitmap, bitmap); 79 80 bitmap.recycle(); 81 bitmap = drawDecoration(decoration, true, false); 82 // last item should not have a divider below it now 83 paint.setColor(Color.TRANSPARENT); 84 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 85 expectedCanvas.drawRect(0, 15, 20, 16, paint); 86 assertBitmapEquals(expectedBitmap, bitmap); 87 88 bitmap.recycle(); 89 bitmap = drawDecoration(decoration, false, false); 90 // everything should be transparent now 91 expectedCanvas.drawRect(0, 5, 20, 6, paint); 92 expectedCanvas.drawRect(0, 10, 20, 11, paint); 93 assertBitmapEquals(expectedBitmap, bitmap); 94 95 } 96 97 @SmallTest 98 public void testShouldDrawDividerBelowWithBothCondition() { 99 // Set up the item decoration, with 1px green divider line 100 final DividerItemDecoration decoration = new DividerItemDecoration(); 101 Drawable divider = new ColorDrawable(Color.GREEN); 102 decoration.setDivider(divider); 103 decoration.setDividerHeight(1); 104 decoration.setDividerCondition(DividerItemDecoration.DIVIDER_CONDITION_BOTH); 105 106 Bitmap bitmap = drawDecoration(decoration, true, true); 107 Paint paint = new Paint(); 108 paint.setColor(Color.GREEN); 109 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); 110 Bitmap expectedBitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_4444); 111 Canvas expectedCanvas = new Canvas(expectedBitmap); 112 expectedCanvas.drawRect(0, 5, 20, 6, paint); 113 expectedCanvas.drawRect(0, 10, 20, 11, paint); 114 expectedCanvas.drawRect(0, 15, 20, 16, paint); 115 // Should have all the dividers 116 assertBitmapEquals(expectedBitmap, bitmap); 117 118 bitmap.recycle(); 119 bitmap = drawDecoration(decoration, false, true); 120 paint.setColor(Color.TRANSPARENT); 121 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 122 expectedCanvas.drawRect(0, 5, 20, 6, paint); 123 expectedCanvas.drawRect(0, 10, 20, 11, paint); 124 assertBitmapEquals(expectedBitmap, bitmap); 125 126 bitmap.recycle(); 127 bitmap = drawDecoration(decoration, true, false); 128 // nothing should be drawn now. 129 expectedCanvas.drawRect(0, 15, 20, 16, paint); 130 assertBitmapEquals(expectedBitmap, bitmap); 131 132 bitmap.recycle(); 133 bitmap = drawDecoration(decoration, false, false); 134 assertBitmapEquals(expectedBitmap, bitmap); 135 } 136 137 private Bitmap drawDecoration(DividerItemDecoration decoration, final boolean allowDividerAbove, 138 final boolean allowDividerBelow) { 139 // Set up the canvas to be drawn 140 Bitmap bitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_4444); 141 Canvas canvas = new Canvas(bitmap); 142 143 // Set up recycler view with vertical linear layout manager 144 RecyclerView testRecyclerView = new RecyclerView(getContext()); 145 testRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 146 147 // Set up adapter with 3 items, each 5px tall 148 testRecyclerView.setAdapter(new RecyclerView.Adapter() { 149 @Override 150 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 151 final View itemView = new View(getContext()); 152 itemView.setMinimumWidth(20); 153 itemView.setMinimumHeight(5); 154 return ViewHolder.createInstance(itemView, allowDividerAbove, allowDividerBelow); 155 } 156 157 @Override 158 public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) { 159 } 160 161 @Override 162 public int getItemCount() { 163 return 3; 164 } 165 }); 166 167 testRecyclerView.layout(0, 0, 20, 20); 168 decoration.onDraw(canvas, testRecyclerView, null); 169 return bitmap; 170 } 171 172 private void assertBitmapEquals(Bitmap expected, Bitmap actual) { 173 assertEquals("Width should be the same", expected.getWidth(), actual.getWidth()); 174 assertEquals("Height should be the same", expected.getHeight(), actual.getHeight()); 175 for (int x = 0; x < expected.getWidth(); x++) { 176 for (int y = 0; y < expected.getHeight(); y++) { 177 assertEquals("Pixel at (" + x + ", " + y + ") should be the same", 178 expected.getPixel(x, y), actual.getPixel(x, y)); 179 } 180 } 181 } 182 183 private static class ViewHolder extends RecyclerView.ViewHolder 184 implements DividerItemDecoration.DividedViewHolder { 185 186 private boolean mAllowDividerAbove; 187 private boolean mAllowDividerBelow; 188 189 public static ViewHolder createInstance(View itemView, boolean allowDividerAbove, 190 boolean allowDividerBelow) { 191 return new ViewHolder(itemView, allowDividerAbove, allowDividerBelow); 192 } 193 194 private ViewHolder(View itemView, boolean allowDividerAbove, boolean allowDividerBelow) { 195 super(itemView); 196 mAllowDividerAbove = allowDividerAbove; 197 mAllowDividerBelow = allowDividerBelow; 198 } 199 200 @Override 201 public boolean isDividerAllowedAbove() { 202 return mAllowDividerAbove; 203 } 204 205 @Override 206 public boolean isDividerAllowedBelow() { 207 return mAllowDividerBelow; 208 } 209 } 210} 211