19c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri/* 29c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Copyright (C) 2017 The Android Open Source Project 39c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * 49c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Licensed under the Apache License, Version 2.0 (the "License"); 59c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * you may not use this file except in compliance with the License. 69c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * You may obtain a copy of the License at 79c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * 89c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * http://www.apache.org/licenses/LICENSE-2.0 99c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * 109c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Unless required by applicable law or agreed to in writing, software 119c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * distributed under the License is distributed on an "AS IS" BASIS, 129c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * See the License for the specific language governing permissions and 149c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * limitations under the License. 159c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 169c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 179c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiripackage android.support.v7.widget; 189c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 199c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiriimport android.support.annotation.IntDef; 209c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiriimport android.view.View; 219c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 229c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiriimport java.lang.annotation.Retention; 239c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiriimport java.lang.annotation.RetentionPolicy; 249c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 259c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri/** 269c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * A utility class used to check the boundaries of a given view within its parent view based on 279c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * a set of boundary flags. 289c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 299c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiriclass ViewBoundsCheck { 309c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 319c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int GT = 1 << 0; 329c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int EQ = 1 << 1; 339c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int LT = 1 << 2; 349c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 359c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 369c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int CVS_PVS_POS = 0; 379c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 389c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start should be strictly greater than parent view's start. 399c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 409c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_GT_PVS = GT << CVS_PVS_POS; 419c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 429c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 439c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start can be equal to its parent view's start. This flag follows with GT 449c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * or LT indicating greater (less) than or equal relation. 459c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 469c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_EQ_PVS = EQ << CVS_PVS_POS; 479c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 489c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 499c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start should be strictly less than parent view's start. 509c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 519c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_LT_PVS = LT << CVS_PVS_POS; 529c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 539c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 549c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int CVS_PVE_POS = 4; 559c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 569c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start should be strictly greater than parent view's end. 579c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 589c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_GT_PVE = GT << CVS_PVE_POS; 599c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 609c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 619c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start can be equal to its parent view's end. This flag follows with GT 629c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * or LT indicating greater (less) than or equal relation. 639c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 649c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_EQ_PVE = EQ << CVS_PVE_POS; 659c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 669c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 679c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's start should be strictly less than parent view's end. 689c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 699c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVS_LT_PVE = LT << CVS_PVE_POS; 709c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 719c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 729c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int CVE_PVS_POS = 8; 739c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 749c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end should be strictly greater than parent view's start. 759c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 769c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_GT_PVS = GT << CVE_PVS_POS; 779c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 789c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 799c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end can be equal to its parent view's start. This flag follows with GT 809c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * or LT indicating greater (less) than or equal relation. 819c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 829c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_EQ_PVS = EQ << CVE_PVS_POS; 839c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 849c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 859c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end should be strictly less than parent view's start. 869c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 879c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_LT_PVS = LT << CVE_PVS_POS; 889c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 899c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 909c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int CVE_PVE_POS = 12; 919c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 929c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end should be strictly greater than parent view's end. 939c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 949c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_GT_PVE = GT << CVE_PVE_POS; 959c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 969c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 979c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end can be equal to its parent view's end. This flag follows with GT 989c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * or LT indicating greater (less) than or equal relation. 999c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 1009c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_EQ_PVE = EQ << CVE_PVE_POS; 1019c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1029c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 1039c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The child view's end should be strictly less than parent view's end. 1049c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 1059c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int FLAG_CVE_LT_PVE = LT << CVE_PVE_POS; 1069c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1079c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static final int MASK = GT | EQ | LT; 1089c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1099c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final Callback mCallback; 1109c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri BoundFlags mBoundFlags; 1119c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 1129c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The set of flags that can be passed for checking the view boundary conditions. 1139c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * CVS in the flag name indicates the child view, and PV indicates the parent view.\ 1149c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * The following S, E indicate a view's start and end points, respectively. 1159c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * GT and LT indicate a strictly greater and less than relationship. 1169c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Greater than or equal (or less than or equal) can be specified by setting both GT and EQ (or 1179c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * LT and EQ) flags. 1189c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * For instance, setting both {@link #FLAG_CVS_GT_PVS} and {@link #FLAG_CVS_EQ_PVS} indicate the 1199c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * child view's start should be greater than or equal to its parent start. 1209c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 1219c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri @IntDef(flag = true, value = { 1229c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri FLAG_CVS_GT_PVS, FLAG_CVS_EQ_PVS, FLAG_CVS_LT_PVS, 1239c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri FLAG_CVS_GT_PVE, FLAG_CVS_EQ_PVE, FLAG_CVS_LT_PVE, 1249c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri FLAG_CVE_GT_PVS, FLAG_CVE_EQ_PVS, FLAG_CVE_LT_PVS, 1259c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri FLAG_CVE_EQ_PVE, FLAG_CVE_EQ_PVE, FLAG_CVE_LT_PVE 1269c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri }) 1279c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri @Retention(RetentionPolicy.SOURCE) 1289c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri public @interface ViewBounds {} 1299c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1309c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri ViewBoundsCheck(Callback callback) { 1319c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mCallback = callback; 1329c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags = new BoundFlags(); 1339c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1349c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1359c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri static class BoundFlags { 1369c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int mBoundFlags = 0; 1379c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int mRvStart, mRvEnd, mChildStart, mChildEnd; 1389c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1399c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri void setBounds(int rvStart, int rvEnd, int childStart, int childEnd) { 1409c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mRvStart = rvStart; 1419c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mRvEnd = rvEnd; 1429c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mChildStart = childStart; 1439c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mChildEnd = childEnd; 1449c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1459c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1469c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri void setFlags(@ViewBounds int flags, int mask) { 1479c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags = (mBoundFlags & ~mask) | (flags & mask); 1489c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1499c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1509c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri void addFlags(@ViewBounds int flags) { 1519c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags |= flags; 1529c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1539c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1549c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri void resetFlags() { 1559c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags = 0; 1569c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1579c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1589c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int compare(int x, int y) { 1599c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (x > y) { 1609c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return GT; 1619c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1629c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (x == y) { 1639c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return EQ; 1649c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1659c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return LT; 1669c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1679c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1689c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri boolean boundsMatch() { 1699c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (MASK << CVS_PVS_POS)) != 0) { 1709c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (compare(mChildStart, mRvStart) << CVS_PVS_POS)) == 0) { 1719c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return false; 1729c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1739c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1749c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1759c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (MASK << CVS_PVE_POS)) != 0) { 1769c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (compare(mChildStart, mRvEnd) << CVS_PVE_POS)) == 0) { 1779c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return false; 1789c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1799c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1809c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1819c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (MASK << CVE_PVS_POS)) != 0) { 1829c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (compare(mChildEnd, mRvStart) << CVE_PVS_POS)) == 0) { 1839c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return false; 1849c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1859c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1869c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1879c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (MASK << CVE_PVE_POS)) != 0) { 1889c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if ((mBoundFlags & (compare(mChildEnd, mRvEnd) << CVE_PVE_POS)) == 0) { 1899c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return false; 1909c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1919c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1929c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return true; 1939c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 1949c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri }; 1959c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 1969c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 1979c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Returns the first view starting from fromIndex to toIndex in views whose bounds lie within 1989c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * its parent bounds based on the provided preferredBoundFlags. If no match is found based on 1999c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * the preferred flags, and a nonzero acceptableBoundFlags is specified, the last view whose 2009c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * bounds lie within its parent view based on the acceptableBoundFlags is returned. If no such 2019c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * view is found based on either of these two flags, null is returned. 2029c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param fromIndex The view position index to start the search from. 2039c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param toIndex The view position index to end the search at. 2049c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param preferredBoundFlags The flags indicating the preferred match. Once a match is found 2059c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * based on this flag, that view is returned instantly. 2069c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param acceptableBoundFlags The flags indicating the acceptable match if no preferred match 2079c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * is found. If so, and if acceptableBoundFlags is non-zero, the 2089c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * last matching acceptable view is returned. Otherwise, null is 2099c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * returned. 2109c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @return The first view that satisfies acceptableBoundFlags or the last view satisfying 2119c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * acceptableBoundFlags boundary conditions. 2129c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 2139c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri View findOneViewWithinBoundFlags(int fromIndex, int toIndex, 2149c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri @ViewBounds int preferredBoundFlags, 2159c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri @ViewBounds int acceptableBoundFlags) { 2169c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final int start = mCallback.getParentStart(); 2179c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final int end = mCallback.getParentEnd(); 2189c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final int next = toIndex > fromIndex ? 1 : -1; 2199c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri View acceptableMatch = null; 2209c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri for (int i = fromIndex; i != toIndex; i += next) { 2219c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final View child = mCallback.getChildAt(i); 2229c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final int childStart = mCallback.getChildStart(child); 2239c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri final int childEnd = mCallback.getChildEnd(child); 2249c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.setBounds(start, end, childStart, childEnd); 2259c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (preferredBoundFlags != 0) { 2269c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.resetFlags(); 2279c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.addFlags(preferredBoundFlags); 2289c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (mBoundFlags.boundsMatch()) { 2299c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri // found a perfect match 2309c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return child; 2319c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2329c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2339c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (acceptableBoundFlags != 0) { 2349c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.resetFlags(); 2359c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.addFlags(acceptableBoundFlags); 2369c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (mBoundFlags.boundsMatch()) { 2379c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri acceptableMatch = child; 2389c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2399c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2409c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2419c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return acceptableMatch; 2429c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2439c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 2449c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 2459c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Returns whether the specified view lies within the boundary condition of its parent view. 2469c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param child The child view to be checked. 2479c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @param boundsFlags The flag against which the child view and parent view are matched. 2489c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * @return True if the view meets the boundsFlag, false otherwise. 2499c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 2509c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri boolean isViewWithinBoundFlags(View child, @ViewBounds int boundsFlags) { 2519c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.setBounds(mCallback.getParentStart(), mCallback.getParentEnd(), 2529c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mCallback.getChildStart(child), mCallback.getChildEnd(child)); 2539c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri if (boundsFlags != 0) { 2549c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.resetFlags(); 2559c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri mBoundFlags.addFlags(boundsFlags); 2569c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return mBoundFlags.boundsMatch(); 2579c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2589c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri return false; 2599c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2609c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri 2619c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri /** 2629c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * Callback provided by the user of this class in order to retrieve information about child and 2639c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri * parent boundaries. 2649c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri */ 2659c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri interface Callback { 2669c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int getChildCount(); 2679c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri View getParent(); 2689c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri View getChildAt(int index); 2699c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int getParentStart(); 2709c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int getParentEnd(); 2719c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int getChildStart(View view); 2729c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri int getChildEnd(View view); 2739c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri } 2749c0ad7d5adfbe51d85adcbc056b6183095d8aaedKeyvan Amiri} 275