149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/* 249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project 349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * you may not use this file except in compliance with the License. 649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * You may obtain a copy of the License at 749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 1049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Unless required by applicable law or agreed to in writing, software 1149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 1249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * See the License for the specific language governing permissions and 1449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * limitations under the License. 1549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 1649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1749c78900da0d43140fb602431fb93212bd7f6c70Chris Banespackage android.support.v7.internal.widget; 1849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 191f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.graphics.Rect; 201f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.os.Build; 2149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewCompat; 221f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.util.Log; 2349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.View; 2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 254c5457da0e82b0090f03655545772ebb8cf4a978Chris Banesimport java.lang.reflect.InvocationTargetException; 261f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport java.lang.reflect.Method; 271f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 2849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/** 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @hide 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banespublic class ViewUtils { 321f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes private static final String TAG = "ViewUtils"; 331f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 341f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes private static Method sComputeFitSystemWindowsMethod; 351f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 361f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes static { 371f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 381f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes try { 391f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes sComputeFitSystemWindowsMethod = View.class.getDeclaredMethod( 401f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes "computeFitSystemWindows", Rect.class, Rect.class); 414c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes if (!sComputeFitSystemWindowsMethod.isAccessible()) { 424c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes sComputeFitSystemWindowsMethod.setAccessible(true); 434c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes } 441f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } catch (NoSuchMethodException e) { 454c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Log.d(TAG, "Could not find method computeFitSystemWindows. Oh well."); 461f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 471f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 481f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 4949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 5049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ViewUtils() {} 5149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 5249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static boolean isLayoutRtl(View view) { 5349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL; 5449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 5549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 5749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Merge two states as returned by {@link ViewCompat#getMeasuredState(android.view.View)} ()}. 5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param curState The current state as returned from a view or the result 5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * of combining multiple views. 6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param newState The new view state to combine. 6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return Returns a new integer reflecting the combination of the two 6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * states. 6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static int combineMeasuredStates(int curState, int newState) { 6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return curState | newState; 6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 671f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 681f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes /** 691f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes * Allow calling the hidden method {@code computeFitSystemWindows(Rect, Rect)} through 701f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes * reflection on {@code view}. 711f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes */ 721f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes public static void computeFitSystemWindows(View view, Rect inoutInsets, Rect outLocalInsets) { 731f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes if (sComputeFitSystemWindowsMethod != null) { 741f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes try { 751f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes sComputeFitSystemWindowsMethod.invoke(view, inoutInsets, outLocalInsets); 761f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } catch (Exception e) { 774c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Log.d(TAG, "Could not invoke computeFitSystemWindows", e); 781f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 791f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 801f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 811f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 821f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes /** 831f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes * Allow calling the hidden method {@code makeOptionalFitsSystem()} through reflection on 841f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes * {@code view}. 851f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes */ 861f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes public static void makeOptionalFitsSystemWindows(View view) { 874c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 881f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes try { 894c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes // We need to use getMethod() for makeOptionalFitsSystemWindows since both View 904c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes // and ViewGroup implement the method 914c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Method method = view.getClass().getMethod("makeOptionalFitsSystemWindows"); 924c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes if (!method.isAccessible()) { 934c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes method.setAccessible(true); 944c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes } 954c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes method.invoke(view); 964c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes } catch (NoSuchMethodException e) { 974c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Log.d(TAG, "Could not find method makeOptionalFitsSystemWindows. Oh well..."); 984c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes } catch (InvocationTargetException e) { 994c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e); 1004c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes } catch (IllegalAccessException e) { 1014c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e); 1021f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 1031f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 1041f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes } 10549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes} 106