1 /*
2  * Copyright (C) 2018 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.permissioncontroller.role.utils;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorListenerAdapter;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.view.animation.AnimationUtils;
24 import android.view.animation.Interpolator;
25 
26 import androidx.annotation.NonNull;
27 
28 /**
29  * Utility methods about UI.
30  */
31 public class UiUtils {
32 
UiUtils()33     private UiUtils() {}
34 
35     /**
36      * Set enabled state on a view and its children recursively.
37      *
38      * @see androidx.preference.Preference#setEnabledStateOnViews
39      *
40      * @param view the view to be set to enabled or not
41      * @param enabled whether the view should be enabled
42      */
setViewTreeEnabled(@onNull View view, boolean enabled)43     public static void setViewTreeEnabled(@NonNull View view, boolean enabled) {
44         view.setEnabled(enabled);
45         if (view instanceof ViewGroup) {
46             ViewGroup viewGroup = (ViewGroup) view;
47             int childCount = viewGroup.getChildCount();
48             for (int i = 0; i < childCount; ++i) {
49                 View childView = viewGroup.getChildAt(i);
50                 setViewTreeEnabled(childView, enabled);
51             }
52         }
53     }
54 
55     /**
56      * Set whether a view is shown.
57      *
58      * @param view the view to be set to shown or not
59      * @param shown whether the view should be shown
60      */
setViewShown(@onNull View view, boolean shown)61     public static void setViewShown(@NonNull View view, boolean shown) {
62         if (shown && view.getVisibility() == View.VISIBLE && view.getAlpha() == 1) {
63             // This cancels any on-going animation.
64             view.animate()
65                     .alpha(1)
66                     .setDuration(0);
67             return;
68         } else if (!shown && (view.getVisibility() != View.VISIBLE || view.getAlpha() == 0)) {
69             // This cancels any on-going animation.
70             view.animate()
71                     .alpha(0)
72                     .setDuration(0);
73             view.setVisibility(View.INVISIBLE);
74             return;
75         }
76         if (shown && view.getVisibility() != View.VISIBLE) {
77             view.setAlpha(0);
78             view.setVisibility(View.VISIBLE);
79         }
80         int duration = view.getResources().getInteger(android.R.integer.config_mediumAnimTime);
81         Interpolator interpolator = AnimationUtils.loadInterpolator(view.getContext(), shown
82                 ? android.R.interpolator.fast_out_slow_in
83                 : android.R.interpolator.fast_out_linear_in);
84         view.animate()
85                 .alpha(shown ? 1 : 0)
86                 .setDuration(duration)
87                 .setInterpolator(interpolator)
88                 // Always update the listener or the view will try to reuse the previous one.
89                 .setListener(shown ? null : new AnimatorListenerAdapter() {
90                     private boolean mCanceled = false;
91                     @Override
92                     public void onAnimationCancel(@NonNull Animator animator) {
93                         mCanceled = true;
94                     }
95                     @Override
96                     public void onAnimationEnd(@NonNull Animator animator) {
97                         if (!mCanceled) {
98                             view.setVisibility(View.INVISIBLE);
99                         }
100                     }
101                 });
102     }
103 }
104