1 /* 2 * Copyright (C) 2012 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 17 package com.android.dialer.util; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.graphics.Paint; 22 import android.os.PowerManager; 23 import android.provider.Settings; 24 import android.provider.Settings.Global; 25 import android.support.annotation.NonNull; 26 import android.text.TextUtils; 27 import android.util.TypedValue; 28 import android.view.View; 29 import android.view.ViewGroup; 30 import android.view.ViewTreeObserver.OnGlobalLayoutListener; 31 import android.view.ViewTreeObserver.OnPreDrawListener; 32 import android.widget.TextView; 33 import java.util.Locale; 34 35 /** Provides static functions to work with views */ 36 public class ViewUtil { 37 ViewUtil()38 private ViewUtil() {} 39 40 /** Similar to {@link Runnable} but takes a View parameter to operate on */ 41 public interface ViewRunnable { run(@onNull View view)42 void run(@NonNull View view); 43 } 44 45 /** 46 * Returns the width as specified in the LayoutParams 47 * 48 * @throws IllegalStateException Thrown if the view's width is unknown before a layout pass s 49 */ getConstantPreLayoutWidth(View view)50 public static int getConstantPreLayoutWidth(View view) { 51 // We haven't been layed out yet, so get the size from the LayoutParams 52 final ViewGroup.LayoutParams p = view.getLayoutParams(); 53 if (p.width < 0) { 54 throw new IllegalStateException( 55 "Expecting view's width to be a constant rather " + "than a result of the layout pass"); 56 } 57 return p.width; 58 } 59 60 /** 61 * Returns a boolean indicating whether or not the view's layout direction is RTL 62 * 63 * @param view - A valid view 64 * @return True if the view's layout direction is RTL 65 */ isViewLayoutRtl(View view)66 public static boolean isViewLayoutRtl(View view) { 67 return view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; 68 } 69 isRtl()70 public static boolean isRtl() { 71 return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL; 72 } 73 resizeText(TextView textView, int originalTextSize, int minTextSize)74 public static void resizeText(TextView textView, int originalTextSize, int minTextSize) { 75 final Paint paint = textView.getPaint(); 76 final int width = textView.getWidth(); 77 if (width == 0) { 78 return; 79 } 80 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, originalTextSize); 81 float ratio = width / paint.measureText(textView.getText().toString()); 82 if (ratio <= 1.0f) { 83 textView.setTextSize( 84 TypedValue.COMPLEX_UNIT_PX, Math.max(minTextSize, originalTextSize * ratio)); 85 } 86 } 87 88 /** Runs a piece of code just before the next draw, after layout and measurement */ doOnPreDraw( @onNull final View view, final boolean drawNextFrame, final Runnable runnable)89 public static void doOnPreDraw( 90 @NonNull final View view, final boolean drawNextFrame, final Runnable runnable) { 91 view.getViewTreeObserver() 92 .addOnPreDrawListener( 93 new OnPreDrawListener() { 94 @Override 95 public boolean onPreDraw() { 96 view.getViewTreeObserver().removeOnPreDrawListener(this); 97 runnable.run(); 98 return drawNextFrame; 99 } 100 }); 101 } 102 doOnPreDraw( @onNull final View view, final boolean drawNextFrame, final ViewRunnable runnable)103 public static void doOnPreDraw( 104 @NonNull final View view, final boolean drawNextFrame, final ViewRunnable runnable) { 105 view.getViewTreeObserver() 106 .addOnPreDrawListener( 107 new OnPreDrawListener() { 108 @Override 109 public boolean onPreDraw() { 110 view.getViewTreeObserver().removeOnPreDrawListener(this); 111 runnable.run(view); 112 return drawNextFrame; 113 } 114 }); 115 } 116 doOnGlobalLayout(@onNull final View view, final ViewRunnable runnable)117 public static void doOnGlobalLayout(@NonNull final View view, final ViewRunnable runnable) { 118 view.getViewTreeObserver() 119 .addOnGlobalLayoutListener( 120 new OnGlobalLayoutListener() { 121 @Override 122 public void onGlobalLayout() { 123 view.getViewTreeObserver().removeOnGlobalLayoutListener(this); 124 runnable.run(view); 125 } 126 }); 127 } 128 129 /** 130 * Returns {@code true} if animations should be disabled. 131 * 132 * <p>Animations should be disabled if {@link 133 * android.provider.Settings.Global#ANIMATOR_DURATION_SCALE} is set to 0 through system settings 134 * or the device is in power save mode. 135 */ areAnimationsDisabled(Context context)136 public static boolean areAnimationsDisabled(Context context) { 137 ContentResolver contentResolver = context.getContentResolver(); 138 PowerManager powerManager = context.getSystemService(PowerManager.class); 139 return Settings.Global.getFloat(contentResolver, Global.ANIMATOR_DURATION_SCALE, 1.0f) == 0 140 || powerManager.isPowerSaveMode(); 141 } 142 } 143