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 
17 package com.example.android.visualgamecontroller.util;
18 
19 import android.app.Activity;
20 import android.os.Build;
21 import android.view.View;
22 
23 /**
24  * A utility class that helps with showing and hiding system UI such as the
25  * status bar and navigation/system bar. This class uses backward-compatibility
26  * techniques described in <a href=
27  * "http://developer.android.com/training/backward-compatible-ui/index.html">
28  * Creating Backward-Compatible UIs</a> to ensure that devices running any
29  * version of Android OS are supported. More specifically, there are separate
30  * implementations of this abstract class: for newer devices,
31  * {@link #getInstance} will return a {@link SystemUiHiderHoneycomb} instance,
32  * while on older devices {@link #getInstance} will return a
33  * {@link SystemUiHiderBase} instance.
34  * <p>
35  * For more on system bars, see <a href=
36  * "http://developer.android.com/design/get-started/ui-overview.html#system-bars"
37  * > System Bars</a>.
38  *
39  * @see android.view.View#setSystemUiVisibility(int)
40  * @see android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
41  */
42 public abstract class SystemUiHider {
43     /**
44      * When this flag is set, the
45      * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}
46      * flag will be set on older devices, making the status bar "float" on top
47      * of the activity layout. This is most useful when there are no controls at
48      * the top of the activity layout.
49      * <p>
50      * This flag isn't used on newer devices because the <a
51      * href="http://developer.android.com/design/patterns/actionbar.html">action
52      * bar</a>, the most important structural element of an Android app, should
53      * be visible and not obscured by the system UI.
54      */
55     public static final int FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES = 0x1;
56 
57     /**
58      * When this flag is set, {@link #show()} and {@link #hide()} will toggle
59      * the visibility of the status bar. If there is a navigation bar, show and
60      * hide will toggle low profile mode.
61      */
62     public static final int FLAG_FULLSCREEN = 0x2;
63 
64     /**
65      * When this flag is set, {@link #show()} and {@link #hide()} will toggle
66      * the visibility of the navigation bar, if it's present on the device and
67      * the device allows hiding it. In cases where the navigation bar is present
68      * but cannot be hidden, show and hide will toggle low profile mode.
69      */
70     public static final int FLAG_HIDE_NAVIGATION = FLAG_FULLSCREEN | 0x4;
71 
72     /**
73      * The activity associated with this UI hider object.
74      */
75     protected Activity mActivity;
76 
77     /**
78      * The view on which {@link View#setSystemUiVisibility(int)} will be called.
79      */
80     protected View mAnchorView;
81 
82     /**
83      * The current UI hider flags.
84      *
85      * @see #FLAG_FULLSCREEN
86      * @see #FLAG_HIDE_NAVIGATION
87      * @see #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES
88      */
89     protected int mFlags;
90 
91     /**
92      * The current visibility callback.
93      */
94     protected OnVisibilityChangeListener mOnVisibilityChangeListener = sNoOpListener;
95 
96     /**
97      * Creates and returns an instance of {@link SystemUiHider} that is
98      * appropriate for this device. The object will be either a
99      * {@link SystemUiHiderBase} or {@link SystemUiHiderHoneycomb} depending on
100      * the device.
101      *
102      * @param activity The activity whose window's system UI should be
103      *            controlled by this class.
104      * @param anchorView The view on which
105      *            {@link View#setSystemUiVisibility(int)} will be called.
106      * @param flags Either 0 or any combination of {@link #FLAG_FULLSCREEN},
107      *            {@link #FLAG_HIDE_NAVIGATION}, and
108      *            {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES}.
109      */
getInstance(Activity activity, View anchorView, int flags)110     public static SystemUiHider getInstance(Activity activity, View anchorView, int flags) {
111         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
112             return new SystemUiHiderHoneycomb(activity, anchorView, flags);
113         } else {
114             return new SystemUiHiderBase(activity, anchorView, flags);
115         }
116     }
117 
SystemUiHider(Activity activity, View anchorView, int flags)118     protected SystemUiHider(Activity activity, View anchorView, int flags) {
119         mActivity = activity;
120         mAnchorView = anchorView;
121         mFlags = flags;
122     }
123 
124     /**
125      * Sets up the system UI hider. Should be called from
126      * {@link Activity#onCreate}.
127      */
setup()128     public abstract void setup();
129 
130     /**
131      * Returns whether or not the system UI is visible.
132      */
isVisible()133     public abstract boolean isVisible();
134 
135     /**
136      * Hide the system UI.
137      */
hide()138     public abstract void hide();
139 
140     /**
141      * Show the system UI.
142      */
show()143     public abstract void show();
144 
145     /**
146      * Toggle the visibility of the system UI.
147      */
toggle()148     public void toggle() {
149         if (isVisible()) {
150             hide();
151         } else {
152             show();
153         }
154     }
155 
156     /**
157      * Registers a callback, to be triggered when the system UI visibility
158      * changes.
159      */
setOnVisibilityChangeListener(OnVisibilityChangeListener listener)160     public void setOnVisibilityChangeListener(OnVisibilityChangeListener listener) {
161         if (listener == null) {
162             listener = sNoOpListener;
163         }
164 
165         mOnVisibilityChangeListener = listener;
166     }
167 
168     /**
169      * A no-op callback for use when there is no other listener set.
170      */
171     private static OnVisibilityChangeListener sNoOpListener = new OnVisibilityChangeListener() {
172         @Override
173         public void onVisibilityChange(boolean visible) {
174         }
175     };
176 
177     /**
178      * A callback interface used to listen for system UI visibility changes.
179      */
180     public interface OnVisibilityChangeListener {
181         /**
182          * Called when the system UI visibility has changed.
183          *
184          * @param visible True if the system UI is visible.
185          */
onVisibilityChange(boolean visible)186         public void onVisibilityChange(boolean visible);
187     }
188 }
189