278 lines
9.5 KiB
Java
278 lines
9.5 KiB
Java
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.hippo.util;
|
|
|
|
import android.app.Activity;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.view.WindowManager;
|
|
|
|
/**
|
|
* Helper for controlling the visibility of the System UI across the various API levels. To use
|
|
* this API, instantiate an instance of this class with the required level. The level specifies the
|
|
* extent to which the System UI's visibility is changed when you call {@link #hide()}
|
|
* or {@link #toggle()}.
|
|
*/
|
|
public final class SystemUiHelper {
|
|
|
|
/**
|
|
* In this level, the helper will toggle low profile mode.
|
|
*/
|
|
public static final int LEVEL_LOW_PROFILE = 0;
|
|
|
|
/**
|
|
* In this level, the helper will toggle the visibility of the status bar.
|
|
* If there is a navigation bar, it will toggle low profile mode.
|
|
*/
|
|
public static final int LEVEL_HIDE_STATUS_BAR = 1;
|
|
|
|
/**
|
|
* In this level, the helper will toggle the visibility of the navigation bar
|
|
* (if present and if possible) and status bar. In cases where the navigation
|
|
* bar is present but cannot be hidden, it will toggle low profile mode.
|
|
*/
|
|
public static final int LEVEL_LEAN_BACK = 2;
|
|
|
|
/**
|
|
* In this level, the helper will toggle the visibility of the navigation bar
|
|
* (if present and if possible) and status bar, in an immersive mode. This means that the app
|
|
* will continue to receive all touch events. The user can reveal the system bars with an
|
|
* inward swipe along the region where the system bars normally appear.
|
|
*
|
|
* <p>The {@link #FLAG_IMMERSIVE_STICKY} flag can be used to control how the system bars are
|
|
* displayed.
|
|
*/
|
|
public static final int LEVEL_IMMERSIVE = 3;
|
|
|
|
/**
|
|
* When this flag is set, the
|
|
* {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}
|
|
* flag will be set on older devices, making the status bar "float" on top
|
|
* of the activity layout. This is most useful when there are no controls at
|
|
* the top of the activity layout.
|
|
* <p>
|
|
* This flag isn't used on newer devices because the <a
|
|
* href="http://developer.android.com/design/patterns/actionbar.html">action
|
|
* bar</a>, the most important structural element of an Android app, should
|
|
* be visible and not obscured by the system UI.
|
|
*/
|
|
public static final int FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES = 0x1;
|
|
|
|
/**
|
|
* Used with {@link #LEVEL_IMMERSIVE}. When this flag is set, an inward swipe in the system
|
|
* bars areas will cause the system bars to temporarily appear in a semi-transparent state,
|
|
* but no flags are cleared, and your system UI visibility change listeners are not triggered.
|
|
* The bars automatically hide again after a short delay, or if the user interacts with the
|
|
* middle of the screen.
|
|
*/
|
|
public static final int FLAG_IMMERSIVE_STICKY = 0x2;
|
|
|
|
private static final String LOG_TAG = SystemUiHelper.class.getSimpleName();
|
|
|
|
private final SystemUiHelperImpl mImpl;
|
|
|
|
private final Handler mHandler;
|
|
private final Runnable mHideRunnable;
|
|
|
|
/**
|
|
* Construct a new SystemUiHelper.
|
|
*
|
|
* @param activity The Activity who's system UI should be changed
|
|
* @param level The level of hiding. Should be either {@link #LEVEL_LOW_PROFILE},
|
|
* {@link #LEVEL_HIDE_STATUS_BAR}, {@link #LEVEL_LEAN_BACK} or
|
|
* {@link #LEVEL_IMMERSIVE}
|
|
* @param flags Additional options. See {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES} and
|
|
* {@link #FLAG_IMMERSIVE_STICKY}
|
|
*/
|
|
public SystemUiHelper(Activity activity, int level, int flags) {
|
|
this(activity, level, flags, null);
|
|
}
|
|
|
|
/**
|
|
* Construct a new SystemUiHelper.
|
|
*
|
|
* @param activity The Activity who's system UI should be changed
|
|
* @param level The level of hiding. Should be either {@link #LEVEL_LOW_PROFILE},
|
|
* {@link #LEVEL_HIDE_STATUS_BAR}, {@link #LEVEL_LEAN_BACK} or
|
|
* {@link #LEVEL_IMMERSIVE}
|
|
* @param flags Additional options. See {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES} and
|
|
* {@link #FLAG_IMMERSIVE_STICKY}
|
|
* @param listener A listener which is called when the system visibility is changed
|
|
*/
|
|
public SystemUiHelper(Activity activity, int level, int flags,
|
|
OnVisibilityChangeListener listener) {
|
|
|
|
mHandler = new Handler(Looper.getMainLooper());
|
|
mHideRunnable = new HideRunnable();
|
|
|
|
// Create impl
|
|
mImpl = new SystemUiHelperImplKK(activity, level, flags, listener);
|
|
}
|
|
|
|
/**
|
|
* @return true if the system UI is currently showing. What this means depends on the mode this
|
|
* {@link SystemUiHelper} was instantiated with.
|
|
*/
|
|
public boolean isShowing() {
|
|
return mImpl.isShowing();
|
|
}
|
|
|
|
/**
|
|
* Show the system UI. What this means depends on the mode this {@link SystemUiHelper} was
|
|
* instantiated with.
|
|
*
|
|
* <p>Any currently queued delayed hide requests will be removed.
|
|
*/
|
|
public void show() {
|
|
// Ensure that any currently queued hide calls are removed
|
|
removeQueuedRunnables();
|
|
|
|
mImpl.show();
|
|
}
|
|
|
|
/**
|
|
* Hide the system UI. What this means depends on the mode this {@link SystemUiHelper} was
|
|
* instantiated with.
|
|
*
|
|
* <p>Any currently queued delayed hide requests will be removed.
|
|
*/
|
|
public void hide() {
|
|
// Ensure that any currently queued hide calls are removed
|
|
removeQueuedRunnables();
|
|
|
|
mImpl.hide();
|
|
}
|
|
|
|
/**
|
|
* Request that the system UI is hidden after a delay.
|
|
*
|
|
* <p>Any currently queued delayed hide requests will be removed.
|
|
*
|
|
* @param delayMillis The delay (in milliseconds) until the Runnable
|
|
* will be executed.
|
|
*/
|
|
public void delayHide(long delayMillis) {
|
|
// Ensure that any currently queued hide calls are removed
|
|
removeQueuedRunnables();
|
|
|
|
mHandler.postDelayed(mHideRunnable, delayMillis);
|
|
}
|
|
|
|
/**
|
|
* Toggle whether the system UI is displayed.
|
|
*/
|
|
public void toggle() {
|
|
if (mImpl.isShowing()) {
|
|
mImpl.hide();
|
|
} else {
|
|
mImpl.show();
|
|
}
|
|
}
|
|
|
|
private void removeQueuedRunnables() {
|
|
// Ensure that any currently queued hide calls are removed
|
|
mHandler.removeCallbacks(mHideRunnable);
|
|
}
|
|
|
|
/**
|
|
* A callback interface used to listen for system UI visibility changes.
|
|
*/
|
|
public interface OnVisibilityChangeListener {
|
|
/**
|
|
* Called when the system UI visibility has changed.
|
|
*
|
|
* @param visible True if the system UI is visible.
|
|
*/
|
|
void onVisibilityChange(boolean visible);
|
|
}
|
|
|
|
static abstract class SystemUiHelperImpl {
|
|
|
|
final Activity mActivity;
|
|
final int mLevel;
|
|
final int mFlags;
|
|
final OnVisibilityChangeListener mOnVisibilityChangeListener;
|
|
|
|
boolean mIsShowing = true;
|
|
|
|
SystemUiHelperImpl(Activity activity, int level, int flags,
|
|
OnVisibilityChangeListener onVisibilityChangeListener) {
|
|
mActivity = activity;
|
|
mLevel = level;
|
|
mFlags = flags;
|
|
mOnVisibilityChangeListener = onVisibilityChangeListener;
|
|
}
|
|
|
|
abstract void show();
|
|
|
|
abstract void hide();
|
|
|
|
boolean isShowing() {
|
|
return mIsShowing;
|
|
}
|
|
|
|
void setIsShowing(boolean isShowing) {
|
|
mIsShowing = isShowing;
|
|
|
|
if (mOnVisibilityChangeListener != null) {
|
|
mOnVisibilityChangeListener.onVisibilityChange(mIsShowing);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base implementation. Used on API level 10 and below.
|
|
*/
|
|
static class SystemUiHelperImplBase extends SystemUiHelperImpl {
|
|
|
|
SystemUiHelperImplBase(Activity activity, int level, int flags,
|
|
OnVisibilityChangeListener onVisibilityChangeListener) {
|
|
super(activity, level, flags, onVisibilityChangeListener);
|
|
|
|
if ((mFlags & SystemUiHelper.FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES) != 0) {
|
|
mActivity.getWindow().addFlags(
|
|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
|
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void show() {
|
|
if (mLevel > SystemUiHelper.LEVEL_LOW_PROFILE) {
|
|
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
setIsShowing(true);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void hide() {
|
|
if (mLevel > SystemUiHelper.LEVEL_LOW_PROFILE) {
|
|
mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
setIsShowing(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class HideRunnable implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
hide();
|
|
}
|
|
}
|
|
|
|
}
|