19648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov/* 29648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * Copyright (C) 2011 The Android Open Source Project 39648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * 49648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 59648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * you may not use this file except in compliance with the License. 69648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * You may obtain a copy of the License at 79648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * 89648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 99648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * 109648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software 119648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 129648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * See the License for the specific language governing permissions and 149648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * limitations under the License. 159648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov */ 169648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 179648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovpackage android.support.v4.view; 189648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 199648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovimport android.os.Build; 209648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovimport android.view.View; 219648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovimport android.view.ViewGroup; 229648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 239648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 249648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov/** 250574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Helper for accessing features in {@link ViewGroup} 260574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * introduced after API level 4 in a backwards compatible fashion. 279648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov */ 289648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganovpublic class ViewGroupCompat { 299648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 30b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell /** 31b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * This constant is a {@link #setLayoutMode(ViewGroup, int) layoutMode}. 32b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * Clip bounds are the raw values of {@link android.view.View#getLeft() left}, 33b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * {@link android.view.View#getTop() top}, 34b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * {@link android.view.View#getRight() right} and {@link android.view.View#getBottom() bottom}. 35b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell */ 36b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; 37b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 38b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell /** 39b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * This constant is a {@link #setLayoutMode(ViewGroup, int) layoutMode}. 40b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * Optical bounds describe where a widget appears to be. They sit inside the clip 41b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * bounds which need to cover a larger area to allow other effects, 42b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * such as shadows and glows, to be drawn. 43b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell */ 44b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; 45b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 469648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov interface ViewGroupCompatImpl { 479648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov public boolean onRequestSendAccessibilityEvent(ViewGroup group, View child, 489648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov AccessibilityEvent event); 491b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell 501b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell public void setMotionEventSplittingEnabled(ViewGroup group, boolean split); 51b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public int getLayoutMode(ViewGroup group); 52b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public void setLayoutMode(ViewGroup group, int mode); 539648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 549648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 559648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov static class ViewGroupCompatStubImpl implements ViewGroupCompatImpl { 569648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov public boolean onRequestSendAccessibilityEvent( 579648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov ViewGroup group, View child, AccessibilityEvent event) { 589648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov return true; 599648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 601b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell 611b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell public void setMotionEventSplittingEnabled(ViewGroup group, boolean split) { 621b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell // no-op, didn't exist. 631b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell } 64b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 65b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell @Override 66b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public int getLayoutMode(ViewGroup group) { 67b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell return LAYOUT_MODE_CLIP_BOUNDS; 68b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 69b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 70b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell @Override 71b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public void setLayoutMode(ViewGroup group, int mode) { 72b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell // no-op, didn't exist. Views only support clip bounds. 73b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 741b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell } 751b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell 761b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell static class ViewGroupCompatHCImpl extends ViewGroupCompatStubImpl { 771b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell @Override 781b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell public void setMotionEventSplittingEnabled(ViewGroup group, boolean split) { 791b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell ViewGroupCompatHC.setMotionEventSplittingEnabled(group, split); 801b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell } 819648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 829648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 831b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell static class ViewGroupCompatIcsImpl extends ViewGroupCompatHCImpl { 849648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov @Override 859648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov public boolean onRequestSendAccessibilityEvent( 869648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov ViewGroup group, View child, AccessibilityEvent event) { 879648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov return ViewGroupCompatIcs.onRequestSendAccessibilityEvent(group, child, event); 889648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 899648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 909648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 91b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell static class ViewGroupCompatJellybeanMR2Impl extends ViewGroupCompatIcsImpl { 92b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell @Override 93b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public int getLayoutMode(ViewGroup group) { 94b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell return ViewGroupCompatJellybeanMR2.getLayoutMode(group); 95b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 96b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 97b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell @Override 98b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public void setLayoutMode(ViewGroup group, int mode) { 99b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell ViewGroupCompatJellybeanMR2.setLayoutMode(group, mode); 100b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 101b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 102b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 1039648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov static final ViewGroupCompatImpl IMPL; 1049648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov static { 1051b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell final int version = Build.VERSION.SDK_INT; 106b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell if (version >= 18) { 107b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell IMPL = new ViewGroupCompatJellybeanMR2Impl(); 108b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } else if (version >= 14) { 1099648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov IMPL = new ViewGroupCompatIcsImpl(); 1101b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell } else if (version >= 11) { 1111b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell IMPL = new ViewGroupCompatHCImpl(); 1129648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } else { 1139648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov IMPL = new ViewGroupCompatStubImpl(); 1149648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 1159648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 1169648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 1179648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov /* 1189648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * Hide the constructor. 1199648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov */ 1209648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov private ViewGroupCompat() { 1219648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 1229648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 1239648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov 1249648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov /** 1259648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * Called when a child has requested sending an {@link AccessibilityEvent} and 1269648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * gives an opportunity to its parent to augment the event. 1279648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * <p> 1289648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * If an {@link AccessibilityDelegateCompat} has been specified via calling 1299648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1309648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * {@link AccessibilityDelegateCompat#onRequestSendAccessibilityEvent(ViewGroup, View, 1319648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * AccessibilityEvent)} is responsible for handling this call. 1329648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * </p> 1339648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * 1349648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * @param group The group whose method to invoke. 1359648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * @param child The child which requests sending the event. 1369648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * @param event The event to be sent. 1379648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov * @return True if the event should be sent. 1389648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov */ 1399648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov public static boolean onRequestSendAccessibilityEvent(ViewGroup group, View child, 1409648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov AccessibilityEvent event) { 1419648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov return IMPL.onRequestSendAccessibilityEvent(group, child, event); 1429648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov } 1431b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell 1441b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell /** 1451b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * Enable or disable the splitting of MotionEvents to multiple children during touch event 1461b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * dispatch. This behavior is enabled by default for applications that target an 1471b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * SDK version of 11 (Honeycomb) or newer. On earlier platform versions this feature 1481b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * was not supported and this method is a no-op. 1491b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * 1501b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * <p>When this option is enabled MotionEvents may be split and dispatched to different child 1511b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * views depending on where each pointer initially went down. This allows for user interactions 1521b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * such as scrolling two panes of content independently, chording of buttons, and performing 1531b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * independent gestures on different pieces of content. 1541b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * 1551b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * @param group ViewGroup to modify 1561b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * @param split <code>true</code> to allow MotionEvents to be split and dispatched to multiple 1571b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * child views. <code>false</code> to only allow one child view to be the target of 1581b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell * any MotionEvent received by this ViewGroup. 1591b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell */ 1601b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell public static void setMotionEventSplittingEnabled(ViewGroup group, boolean split) { 1611b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell IMPL.setMotionEventSplittingEnabled(group, split); 1621b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell } 163b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 164b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell /** 165b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * Returns the basis of alignment during layout operations on this ViewGroup: 166b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}. 167b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * <p> 168b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * If no layoutMode was explicitly set, either programmatically or in an XML resource, 169b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * the method returns the layoutMode of the view's parent ViewGroup if such a parent exists, 170b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * otherwise the method returns a default value of {@link #LAYOUT_MODE_CLIP_BOUNDS}. 171b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * 172b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * @return the layout mode to use during layout operations 173b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * 174b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * @see #setLayoutMode(ViewGroup, int) 175b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell */ 176b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public static int getLayoutMode(ViewGroup group) { 177b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell return IMPL.getLayoutMode(group); 178b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 179b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell 180b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell /** 181b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * Sets the basis of alignment during the layout of this ViewGroup. 182b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or 183b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * {@link #LAYOUT_MODE_OPTICAL_BOUNDS}. 184b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * 185b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * @param mode the layout mode to use during layout operations 186b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * 187b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell * @see #getLayoutMode(ViewGroup) 188b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell */ 189b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell public static void setLayoutMode(ViewGroup group, int mode) { 190b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell IMPL.setLayoutMode(group, mode); 191b12ba0547b2fad1c4dfc12dec36c5e7893974e67Adam Powell } 1929648c538bac4f04145c118cc41168d1d7a536312Svetoslav Ganov} 193