1/* 2 * Copyright (C) 2014 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 android.support.v4.view; 18 19import android.content.Context; 20import android.content.res.ColorStateList; 21import android.graphics.PorterDuff; 22import android.view.Display; 23import android.view.View; 24import android.view.ViewParent; 25import android.view.WindowManager; 26 27import java.lang.reflect.Field; 28 29class ViewCompatBase { 30 31 private static final String TAG = "ViewCompatBase"; 32 33 private static Field sMinWidthField; 34 private static boolean sMinWidthFieldFetched; 35 private static Field sMinHeightField; 36 private static boolean sMinHeightFieldFetched; 37 38 static ColorStateList getBackgroundTintList(View view) { 39 return (view instanceof TintableBackgroundView) 40 ? ((TintableBackgroundView) view).getSupportBackgroundTintList() 41 : null; 42 } 43 44 static void setBackgroundTintList(View view, ColorStateList tintList) { 45 if (view instanceof TintableBackgroundView) { 46 ((TintableBackgroundView) view).setSupportBackgroundTintList(tintList); 47 } 48 } 49 50 static PorterDuff.Mode getBackgroundTintMode(View view) { 51 return (view instanceof TintableBackgroundView) 52 ? ((TintableBackgroundView) view).getSupportBackgroundTintMode() 53 : null; 54 } 55 56 static void setBackgroundTintMode(View view, PorterDuff.Mode mode) { 57 if (view instanceof TintableBackgroundView) { 58 ((TintableBackgroundView) view).setSupportBackgroundTintMode(mode); 59 } 60 } 61 62 static boolean isLaidOut(View view) { 63 return view.getWidth() > 0 && view.getHeight() > 0; 64 } 65 66 static int getMinimumWidth(View view) { 67 if (!sMinWidthFieldFetched) { 68 try { 69 sMinWidthField = View.class.getDeclaredField("mMinWidth"); 70 sMinWidthField.setAccessible(true); 71 } catch (NoSuchFieldException e) { 72 // Couldn't find the field. Abort! 73 } 74 sMinWidthFieldFetched = true; 75 } 76 77 if (sMinWidthField != null) { 78 try { 79 return (int) sMinWidthField.get(view); 80 } catch (Exception e) { 81 // Field get failed. Oh well... 82 } 83 } 84 85 // We failed, return 0 86 return 0; 87 } 88 89 static int getMinimumHeight(View view) { 90 if (!sMinHeightFieldFetched) { 91 try { 92 sMinHeightField = View.class.getDeclaredField("mMinHeight"); 93 sMinHeightField.setAccessible(true); 94 } catch (NoSuchFieldException e) { 95 // Couldn't find the field. Abort! 96 } 97 sMinHeightFieldFetched = true; 98 } 99 100 if (sMinHeightField != null) { 101 try { 102 return (int) sMinHeightField.get(view); 103 } catch (Exception e) { 104 // Field get failed. Oh well... 105 } 106 } 107 108 // We failed, return 0 109 return 0; 110 } 111 112 static boolean isAttachedToWindow(View view) { 113 return view.getWindowToken() != null; 114 } 115 116 static void offsetTopAndBottom(View view, int offset) { 117 final int currentTop = view.getTop(); 118 view.offsetTopAndBottom(offset); 119 120 if (offset != 0) { 121 // We need to manually invalidate pre-honeycomb 122 final ViewParent parent = view.getParent(); 123 if (parent instanceof View) { 124 final int absOffset = Math.abs(offset); 125 ((View) parent).invalidate( 126 view.getLeft(), 127 currentTop - absOffset, 128 view.getRight(), 129 currentTop + view.getHeight() + absOffset); 130 } else { 131 view.invalidate(); 132 } 133 } 134 } 135 136 static void offsetLeftAndRight(View view, int offset) { 137 final int currentLeft = view.getLeft(); 138 view.offsetLeftAndRight(offset); 139 140 if (offset != 0) { 141 // We need to manually invalidate pre-honeycomb 142 final ViewParent parent = view.getParent(); 143 if (parent instanceof View) { 144 final int absOffset = Math.abs(offset); 145 ((View) parent).invalidate( 146 currentLeft - absOffset, 147 view.getTop(), 148 currentLeft + view.getWidth() + absOffset, 149 view.getBottom()); 150 } else { 151 view.invalidate(); 152 } 153 } 154 } 155 156 static Display getDisplay(View view) { 157 if (isAttachedToWindow(view)) { 158 final WindowManager wm = (WindowManager) view.getContext().getSystemService( 159 Context.WINDOW_SERVICE); 160 return wm.getDefaultDisplay(); 161 } 162 return null; 163 } 164 165} 166