14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 34143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 44143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 54143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * you may not use this file except in compliance with the License. 64143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * You may obtain a copy of the License at 74143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 84143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 94143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Unless required by applicable law or agreed to in writing, software 114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * See the License for the specific language governing permissions and 144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * limitations under the License. 154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.recyclerview.widget; 174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 18ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL; 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL; 204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.content.Context; 224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Color; 234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.AttributeSet; 244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View; 254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.ViewGroup; 264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 27c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikasimport androidx.annotation.NonNull; 28c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikasimport androidx.core.util.Pair; 29c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikas 308a11e6829c522aa1efcc903afa4c01d337082eabChris Craikimport org.hamcrest.BaseMatcher; 318a11e6829c522aa1efcc903afa4c01d337082eabChris Craikimport org.hamcrest.Description; 328a11e6829c522aa1efcc903afa4c01d337082eabChris Craik 334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.ArrayList; 344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Collections; 354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List; 364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.concurrent.atomic.AtomicLong; 374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarabstract public class BaseWrapContentWithAspectRatioTest extends BaseRecyclerViewInstrumentationTest { 394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final BaseWrapContentTest.WrapContentConfig mWrapContentConfig; 404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected BaseWrapContentWithAspectRatioTest( 424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar BaseWrapContentTest.WrapContentConfig wrapContentConfig) { 434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mWrapContentConfig = wrapContentConfig; 444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int getSize(View view, int orientation) { 474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (orientation == VERTICAL) { 484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return view.getHeight(); 494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return view.getWidth(); 514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class LoggingView extends View { 544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar MeasureBehavior mBehavior; 564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void setBehavior(MeasureBehavior behavior) { 584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mBehavior = behavior; 594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public LoggingView(Context context) { 624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(context); 634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public LoggingView(Context context, AttributeSet attrs) { 664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(context, attrs); 674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public LoggingView(Context context, AttributeSet attrs, int defStyleAttr) { 704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(context, attrs, defStyleAttr); 714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public LoggingView(Context context, AttributeSet attrs, int defStyleAttr, 744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int defStyleRes) { 754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(context, attrs, defStyleAttr, defStyleRes); 764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mBehavior.onMeasure(this, widthMeasureSpec, heightMeasureSpec); 814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super.onLayout(changed, left, top, right, bottom); 864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mBehavior.onLayout(changed, left, top, right, bottom); 874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void setMeasured(int w, int h) { 904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar setMeasuredDimension(w, h); 914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void prepareLayoutParams() { 944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mBehavior.setLayoutParams(this); 954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class AspectRatioMeasureBehavior extends MeasureBehavior { 994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Float ratio; 1014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int control; 1024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public AspectRatioMeasureBehavior(int desiredW, int desiredH, int wMode, int hMode) { 1044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(desiredW, desiredH, wMode, hMode); 1054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public AspectRatioMeasureBehavior aspectRatio(int control, float ratio) { 1084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.control = control; 1094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.ratio = ratio; 1104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return this; 1114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 1144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void onMeasure(LoggingView view, int wSpec, 1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int hSpec) { 1164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super.onMeasure(view, wSpec, hSpec); 1174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (control == VERTICAL) { 1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar view.setMeasured(getSecondary(view.getMeasuredHeight()), 1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar view.getMeasuredHeight()); 1204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else if (control == HORIZONTAL) { 1214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar view.setMeasured(view.getMeasuredWidth(), 1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar getSecondary(view.getMeasuredWidth())); 1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int getSecondary(int controlSize) { 1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return (int) (controlSize * ratio); 1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class MeasureBehavior { 1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private static final AtomicLong idCounter = new AtomicLong(0); 1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public List<Pair<Integer, Integer>> measureSpecs = new ArrayList<>(); 1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public List<Pair<Integer, Integer>> layouts = new ArrayList<>(); 1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int desiredW, desiredH; 1364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final long mId = idCounter.incrementAndGet(); 1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 138de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar ViewGroup.MarginLayoutParams layoutParams; 1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public MeasureBehavior(int desiredW, int desiredH, int wMode, int hMode) { 1414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.desiredW = desiredW; 1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.desiredH = desiredH; 143de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar layoutParams = new ViewGroup.MarginLayoutParams( 1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wMode, hMode 1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ); 1464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 148de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar public MeasureBehavior withMargins(int left, int top, int right, int bottom) { 149de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar layoutParams.leftMargin = left; 150de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar layoutParams.topMargin = top; 151de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar layoutParams.rightMargin = right; 152de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar layoutParams.bottomMargin = bottom; 153de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar return this; 154de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar } 155de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar 1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public long getId() { 1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return mId; 1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void onMeasure(LoggingView view, int wSpec, int hSpec) { 1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar measureSpecs.add(new Pair<>(wSpec, hSpec)); 1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar view.setMeasured( 1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager.chooseSize(wSpec, desiredW, 0), 1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager.chooseSize(hSpec, desiredH, 0)); 1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int getSpec(int position, int orientation) { 1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (orientation == VERTICAL) { 1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return measureSpecs.get(position).second; 1704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 1714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return measureSpecs.get(position).first; 1724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void setLayoutParams(LoggingView view) { 1764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar view.setLayoutParams(layoutParams); 1774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void onLayout(boolean changed, int left, int top, int right, int bottom) { 1804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (changed) { 1814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layouts.add(new Pair<>(right - left, bottom - top)); 1824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class WrapContentViewHolder extends RecyclerView.ViewHolder { 1884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LoggingView mView; 1904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentViewHolder(ViewGroup parent) { 1924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar super(new LoggingView(parent.getContext())); 1934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mView = (LoggingView) itemView; 1944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mView.setBackgroundColor(Color.GREEN); 1954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class WrapContentAdapter extends RecyclerView.Adapter<WrapContentViewHolder> { 1994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<MeasureBehavior> behaviors = new ArrayList<>(); 2014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentAdapter(MeasureBehavior... behaviors) { 2034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Collections.addAll(this.behaviors, behaviors); 2044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2078a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public WrapContentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 2084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return new WrapContentViewHolder(parent); 2094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2128a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void onBindViewHolder(@NonNull WrapContentViewHolder holder, int position) { 2134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar holder.mView.setBehavior(behaviors.get(position)); 2144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar holder.mView.prepareLayoutParams(); 2154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int getItemCount() { 2194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return behaviors.size(); 2204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class MeasureSpecMatcher extends BaseMatcher<Integer> { 2244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private boolean checkSize = false; 2264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private boolean checkMode = false; 2274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private int mSize; 2284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private int mMode; 2294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public static MeasureSpecMatcher is(int size, int mode) { 2314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar MeasureSpecMatcher matcher = new MeasureSpecMatcher(size, mode); 2324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkSize = true; 2334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkMode = true; 2344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return matcher; 2354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public static MeasureSpecMatcher size(int size) { 2384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar MeasureSpecMatcher matcher = new MeasureSpecMatcher(size, 0); 2394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkSize = true; 2404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkMode = false; 2414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return matcher; 2424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public static MeasureSpecMatcher mode(int mode) { 2454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar MeasureSpecMatcher matcher = new MeasureSpecMatcher(0, mode); 2464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkSize = false; 2474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar matcher.checkMode = true; 2484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return matcher; 2494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private MeasureSpecMatcher(int size, int mode) { 2524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mSize = size; 2534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mMode = mode; 2544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean matches(Object item) { 2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (item == null) { 2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return false; 2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Integer intValue = (Integer) item; 2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int size = View.MeasureSpec.getSize(intValue); 2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int mode = View.MeasureSpec.getMode(intValue); 2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkSize && size != mSize) { 2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return false; 2674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkMode && mode != mMode) { 2694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return false; 2704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return true; 2724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void describeMismatch(Object item, Description description) { 2764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Integer intValue = (Integer) item; 2774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int size = View.MeasureSpec.getSize(intValue); 2784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int mode = View.MeasureSpec.getMode(intValue); 2794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkSize && size != mSize) { 2804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar description.appendText(" Expected size was ").appendValue(mSize) 2814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar .appendText(" but received size is ").appendValue(size); 2824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkMode && mode != mMode) { 2844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar description.appendText(" Expected mode was ").appendValue(modeName(mMode)) 2854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar .appendText(" but received mode is ").appendValue(modeName(mode)); 2864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 2904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void describeTo(Description description) { 2914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkSize) { 2924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar description.appendText(" Measure spec size:").appendValue(mSize); 2934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (checkMode) { 2954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar description.appendText(" Measure spec mode:").appendValue(modeName(mMode)); 2964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private static String modeName(int mode) { 3004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar switch (mode) { 3014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar case View.MeasureSpec.AT_MOST: 3024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "at most"; 3034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar case View.MeasureSpec.EXACTLY: 3044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "exactly"; 3054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar default: 3064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "unspecified"; 3074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar} 311