/* * Copyright (C) 2011 Google Inc. * * 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.android.utils.widget; import android.content.Context; import android.graphics.PixelFormat; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; /** * Provides a simple full-screen overlay. Behaves like a * {@link android.app.Dialog} but simpler. */ public class SimpleOverlay { private final Context mContext; private final WindowManager mWindowManager; private final ViewGroup mContentView; private final LayoutParams mParams; private final int mId; private SimpleOverlayListener mListener; private boolean mVisible = false; /** * Creates a new simple overlay. * * @param context The parent context. */ public SimpleOverlay(Context context) { this(context, 0); } /** * Creates a new simple overlay. * * @param context The parent context. * @param id An optional identifier for the overlay. */ public SimpleOverlay(Context context, int id) { mContext = context; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mContentView = new SilentFrameLayout(context); mParams = new WindowManager.LayoutParams(); mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; mParams.format = PixelFormat.TRANSLUCENT; mParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mId = id; } /** * @return The overlay context. */ public Context getContext() { return mContext; } /** * @return The overlay identifier, or {@code 0} if no identifier was * provided at construction. */ public int getId() { return mId; } /** * Sets the listener for overlay visibility callbacks. * * @param listener new listener */ public void setListener(SimpleOverlayListener listener) { mListener = listener; } /** * Shows the overlay. Calls the listener's * {@link SimpleOverlayListener#onShow(SimpleOverlay)} if available. */ public void show() { if (mVisible) { return; } mWindowManager.addView(mContentView, mParams); mVisible = true; if (mListener != null) { mListener.onShow(this); } onShow(); } /** * Hides the overlay. Calls the listener's * {@link SimpleOverlayListener#onHide(SimpleOverlay)} if available. */ public void hide() { if (!mVisible) { return; } mWindowManager.removeView(mContentView); mVisible = false; if (mListener != null) { mListener.onHide(this); } onHide(); } /** * Called after {@link #show()}. */ protected void onShow() { // Do nothing. } /** * Called after {@link #hide()}. */ void onHide() { // Do nothing. } /** * @return A copy of the current layout parameters. */ public LayoutParams getParams() { final LayoutParams copy = new LayoutParams(); copy.copyFrom(mParams); return copy; } /** * Sets the current layout parameters and applies them immediately. * * @param params The layout parameters to use. */ public void setParams(LayoutParams params) { mParams.copyFrom(params); if (mVisible) { mWindowManager.updateViewLayout(mContentView, mParams); } } /** * @return {@code true} if this overlay is visible. */ public boolean isVisible() { return mVisible; } /** * Inflates the specified resource ID and sets it as the content view. * * @param layoutResId The layout ID of the view to set as the content view. */ public void setContentView(int layoutResId) { final LayoutInflater inflater = LayoutInflater.from(mContext); inflater.inflate(layoutResId, mContentView); } /** * Sets the specified view as the content view. * * @param content The view to set as the content view. */ public void setContentView(View content) { mContentView.removeAllViews(); mContentView.addView(content); } /** * Finds and returns the view within the overlay content. * * @param id The ID of the view to return. * @return The view with the specified ID, or {@code null} if not found. */ public View findViewById(int id) { return mContentView.findViewById(id); } /** * Handles overlay visibility change callbacks. */ public interface SimpleOverlayListener { /** * Called after the overlay is displayed. * * @param overlay The overlay that was displayed. */ public void onShow(SimpleOverlay overlay); /** * Called after the overlay is hidden. * * @param overlay The overlay that was hidden. */ public void onHide(SimpleOverlay overlay); } private static class SilentFrameLayout extends FrameLayout { public SilentFrameLayout(Context context) { super(context); } @Override public boolean requestSendAccessibilityEvent(View view, AccessibilityEvent event) { // Never send accessibility events. return false; } @Override public void sendAccessibilityEventUnchecked(@NonNull AccessibilityEvent event) { // Never send accessibility events. } } }