1 /* 2 * Copyright 2019 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.car.apps.common.util; 18 19 import android.animation.Animator; 20 import android.animation.AnimatorListenerAdapter; 21 import android.annotation.NonNull; 22 import android.content.res.Resources; 23 import android.content.res.TypedArray; 24 import android.view.View; 25 import android.widget.TextView; 26 27 import androidx.annotation.Nullable; 28 import androidx.annotation.StringRes; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** 34 * Utility methods to operate over views. 35 */ 36 public class ViewUtils { 37 /** 38 * Hides a view using a fade-out animation 39 * 40 * @param view {@link View} to be hidden 41 * @param duration animation duration in milliseconds. 42 */ hideViewAnimated(@onNull View view, int duration)43 public static void hideViewAnimated(@NonNull View view, int duration) { 44 // Cancel existing animation to avoid race condition 45 // if show and hide are called at the same time 46 view.animate().cancel(); 47 48 if (!view.isLaidOut()) { 49 // If the view hasn't been displayed yet, just adjust visibility without animation 50 view.setVisibility(View.GONE); 51 return; 52 } 53 54 view.animate() 55 .setDuration(duration) 56 .setListener(hideViewAfterAnimation(view)) 57 .alpha(0f); 58 } 59 60 /** Returns an AnimatorListener that hides the view at the end. */ hideViewAfterAnimation(View view)61 public static Animator.AnimatorListener hideViewAfterAnimation(View view) { 62 return new AnimatorListenerAdapter() { 63 @Override 64 public void onAnimationEnd(Animator animation) { 65 view.setVisibility(View.GONE); 66 } 67 }; 68 } 69 70 /** 71 * Hides views using a fade-out animation 72 * 73 * @param views {@link View}s to be hidden 74 * @param duration animation duration in milliseconds. 75 */ 76 public static void hideViewsAnimated(@Nullable List<View> views, int duration) { 77 for (View view : views) { 78 if (view != null) { 79 hideViewAnimated(view, duration); 80 } 81 } 82 } 83 84 /** 85 * Shows a view using a fade-in animation 86 * 87 * @param view {@link View} to be shown 88 * @param duration animation duration in milliseconds. 89 */ 90 public static void showViewAnimated(@NonNull View view, int duration) { 91 // Cancel existing animation to avoid race condition 92 // if show and hide are called at the same time 93 view.animate().cancel(); 94 95 // Do the animation even if the view isn't laid out which is often the case for a view 96 // that isn't shown (otherwise the view just pops onto the screen... 97 98 view.animate() 99 .setDuration(duration) 100 .setListener(new AnimatorListenerAdapter() { 101 @Override 102 public void onAnimationStart(Animator animation) { 103 view.setVisibility(View.VISIBLE); 104 } 105 }) 106 .alpha(1f); 107 } 108 109 /** 110 * Shows views using a fade-out animation 111 * 112 * @param views {@link View}s to be shown. 113 * @param duration animation duration in milliseconds. 114 */ 115 public static void showViewsAnimated(@Nullable List<View> views, int duration) { 116 for (View view : views) { 117 if (view != null) { 118 showViewAnimated(view, duration); 119 } 120 } 121 } 122 123 /** Sets the visibility of the (optional) view to {@link View#VISIBLE} or {@link View#GONE}. */ 124 public static void setVisible(@Nullable View view, boolean visible) { 125 if (view != null) { 126 view.setVisibility(visible ? View.VISIBLE : View.GONE); 127 } 128 } 129 130 /** Sets the visibility of the views to {@link View#VISIBLE} or {@link View#GONE}. */ 131 public static void setVisible(@Nullable List<View> views, boolean visible) { 132 for (View view : views) { 133 setVisible(view, visible); 134 } 135 } 136 137 /** 138 * Sets the visibility of the (optional) view to {@link View#INVISIBLE} or {@link View#VISIBLE}. 139 */ 140 public static void setInvisible(@Nullable View view, boolean invisible) { 141 if (view != null) { 142 view.setVisibility(invisible ? View.INVISIBLE : View.VISIBLE); 143 } 144 } 145 146 /** Sets the text to the (optional) {@link TextView}. */ 147 public static void setText(@Nullable TextView view, @StringRes int resId) { 148 if (view != null) { 149 view.setText(resId); 150 } 151 } 152 153 /** Sets the text to the (optional) {@link TextView}. */ 154 public static void setText(@Nullable TextView view, CharSequence text) { 155 if (view != null) { 156 view.setText(text); 157 } 158 } 159 160 /** Sets the enabled state of the (optional) view. */ 161 public static void setEnabled(@Nullable View view, boolean enabled) { 162 if (view != null) { 163 view.setEnabled(enabled); 164 } 165 } 166 167 /** Sets the activated state of the (optional) view. */ 168 public static void setActivated(@Nullable View view, boolean activated) { 169 if (view != null) { 170 view.setActivated(activated); 171 } 172 } 173 174 /** Sets onClickListener for the (optional) view. */ 175 public static void setOnClickListener(@Nullable View view, @Nullable View.OnClickListener l) { 176 if (view != null) { 177 view.setOnClickListener(l); 178 } 179 } 180 181 /** Helper interface for {@link #getViewsById(View, Resources, int, Filter)} getViewsById}. */ 182 public interface Filter { 183 /** Returns whether a view should be added to the returned List. */ 184 boolean isValid(View view); 185 } 186 187 /** Get views from typed array. */ 188 public static List<View> getViewsById(@NonNull View root, @NonNull Resources res, int arrayId, 189 @Nullable Filter filter) { 190 TypedArray viewIds = res.obtainTypedArray(arrayId); 191 List<View> views = new ArrayList<>(viewIds.length()); 192 for (int i = 0; i < viewIds.length(); i++) { 193 int viewId = viewIds.getResourceId(i, 0); 194 if (viewId != 0) { 195 View view = root.findViewById(viewId); 196 if (view != null && (filter == null || filter.isValid(view))) { 197 views.add(view); 198 } 199 } 200 } 201 viewIds.recycle(); 202 return views; 203 } 204 } 205