ระบบการจัดการ SystemUIOverlayWindow
ทำให้คุณแสดงและ
จัดการมุมมองใน SystemUIOverlayWindow
ปัจจุบันหน้าต่างนี้ใช้สำหรับการดู
ซึ่งรวมถึงตัวสลับผู้ใช้แบบเต็มหน้าจอ แผงการแจ้งเตือน และการล็อกปุ่ม หน้านี้จะไม่มีลักษณะดังนี้
- สร้างข้อจำกัดเกี่ยวกับสิ่งที่ OEM สามารถเพิ่มในหน้าต่างได้
- บังคับให้คุณใช้บทคัดย่อที่อธิบายไว้ในหน้านี้
ภาพรวม
คุณสามารถใช้ระบบการจัดการ SystemUIOverlayWindow
เพื่อแสดงมุมมอง เช่น
ประกาศทางกฎหมาย, ตัวสลับผู้ใช้แบบเต็มหน้าจอ, กล้องมองหลัง, การควบคุมระบบปรับอากาศ (HVAC) และการล็อกปุ่มกด ช่วงเวลานี้
อยู่นอกพื้นที่ของแอป ทำให้คุณสามารถควบคุมการเรียงลำดับ Z ของมุมมองได้
ทริกเกอร์เปิดเผย/จำกัด และการปรับแต่งโดยรวม ซึ่งรวมถึงตำแหน่งการดู ขนาด ความโปร่งใส
และสี ในขณะเดียวกัน คุณไม่จำเป็นต้องกังวลเกี่ยวกับสถานะของแถบระบบหรือ
ออบเจ็กต์ UI ของระบบที่ต้องซ่อนหรือแสดงเมื่อซ่อนหรือแสดงมุมมองที่เกี่ยวข้อง
ในการใช้ประโยชน์จาก SystemUIOverlayWindow
คุณต้องสร้างตัวควบคุมการดูสำหรับมุมมองของคุณ
สื่อกลาง ระบบจะส่งสื่อกลางไปยังตัวควบคุมสถานะส่วนกลางของหน้าต่าง สื่อกลางมุมมองเหล่านี้:
- พิกัดระหว่างตัวควบคุมมุมมอง
- ตรรกะทางธุรกิจภายในบริษัทสำหรับตัวควบคุมการดู
ดูผู้ควบคุมข้อมูล (ประสานงานโดยผู้ไกล่เกลี่ยการดู)
- มุมมองของตัวเอง
- สร้างตัวตั้งค่าซึ่ง
OverlayViewsMediator
สามารถแนบตรรกะทางธุรกิจได้ - สร้างภาพเคลื่อนไหวที่เผยให้เห็นและซ่อนเร้นของมุมมองเหล่านั้น
SystemUIOverlayWindow
บัญชีดูแลจัดการ ซึ่งเป็นคอมโพเนนต์ SystemUI ทำหน้าที่เป็นจุดแรกเข้าไปยัง
เริ่มต้นและลงทะเบียนสื่อกลางด้วยตัวควบคุมสถานะส่วนกลาง ขณะที่ตัวควบคุมสถานะส่วนกลาง
เชื่อมโยงกับตัวควบคุมมุมมองในลักษณะที่สื่อกลางสามารถเรียกใช้ตัวควบคุมการดูได้โดยตรง
เพื่อแสดงและซ่อนมุมมองในหน้าต่าง
OverlayViewController
OverlayViewController
รับผิดชอบข้อมูลพร็อพเพอร์ตี้ที่แสดงใน SystemUIOverlayWindow
และควบคุมลักษณะการแสดงผล
แสดงและซ่อนแล้ว และยังทำให้สามารถแนบ Listener ที่จำเป็นเพื่อให้ลิงก์ได้
กับตรรกะทางธุรกิจ
ลายเซ็นเมธอดที่สำคัญ
/**
* Owns a {@link View} that is present in SystemUIOverlayWindow
.
*/
public class OverlayViewController {
/**
* Shows content of {@link OverlayViewController}.
*
* Should be used to show view externally and in particular by {@link OverlayViewMediator}.
*/
public final void start();
/**
* Hides content of {@link OverlayViewController}.
*
* Should be used to hide view externally and in particular by {@link OverlayViewMediator}.
*/
public final void stop();
/**
* Inflate layout owned by controller.
*/
public final void inflate(ViewGroup baseLayout);
/**
* Called once inflate finishes.
*/
protected void onFinishInflate();
/**
* Returns {@code true} if layout owned by controller has been inflated.
*/
public final boolean isInflated();
/**
* Subclasses should override this method to implement reveal animations and implement logic
* specific to when the layout owned by the controller is shown.
*
* Should only be overridden by Superclass but not called by any {@link OverlayViewMediator}.
*/
protected void showInternal();
/**
* Subclasses should override this method to implement conceal animations and implement logic
* specific to when the layout owned by the controller is hidden.
*
* Should only be overridden by Superclass but not called by any {@link OverlayViewMediator}.
*/
protected void hideInternal();
/**
* Provides access to layout owned by controller.
*/
protected final View getLayout();
/** Returns the {@link OverlayViewGlobalStateController}. */
protected final OverlayViewGlobalStateController getOverlayViewGlobalStateController();
/** Returns whether the view controlled by this controller is visible. */
public final boolean isVisible();
/**
* Returns the ID of the focus area that should receive focus when this view is the
* topmost view or {@link View#NO_ID} if there is no focus area.
*/
@IdRes
protected int getFocusAreaViewId();
/** Returns whether the view controlled by this controller has rotary focus. */
protected final boolean hasRotaryFocus();
/**
* Sets whether this view allows rotary focus. This should be set to {@code true} for the
* topmost layer in the overlay window and {@code false} for the others.
*/
public void setAllowRotaryFocus(boolean allowRotaryFocus);
/**
* Refreshes the rotary focus in this view if we are in rotary mode. If the view already has
* rotary focus, it leaves the focus alone. Returns {@code true} if a new view was focused.
*/
public boolean refreshRotaryFocusIfNeeded();
/**
* Returns {@code true} if heads up notifications should be displayed over this view.
*/
protected boolean shouldShowHUN();
/**
* Returns {@code true} if navigation bar insets should be displayed over this view. Has no
* effect if {@link #shouldFocusWindow} returns {@code false}.
*/
protected boolean shouldShowNavigationBarInsets();
/**
* Returns {@code true} if status bar insets should be displayed over this view. Has no
* effect if {@link #shouldFocusWindow} returns {@code false}.
*/
protected boolean shouldShowStatusBarInsets();
/**
* Returns {@code true} if this view should be hidden during the occluded state.
*/
protected boolean shouldShowWhenOccluded();
/**
* Returns {@code true} if the window should be focued when this view is visible. Note that
* returning {@code false} here means that {@link #shouldShowStatusBarInsets} and
* {@link #shouldShowNavigationBarInsets} will have no effect.
*/
protected boolean shouldFocusWindow();
/**
* Returns {@code true} if the window should use stable insets. Using stable insets means that
* even when system bars are temporarily not visible, inset from the system bars will still be
* applied.
*
* NOTE: When system bars are hidden in transient mode, insets from them will not be applied
* even when the system bars become visible. Setting the return value to {@true} here can
* prevent the OverlayView from overlapping with the system bars when that happens.
*/
protected boolean shouldUseStableInsets();
/**
* Returns the insets types to fit to the sysui overlay window when this
* {@link OverlayViewController} is in the foreground.
*/
@WindowInsets.Type.InsetsType
protected int getInsetTypesToFit();
/**
* Optionally returns the sides of enabled system bar insets to fit to the sysui overlay window
* when this {@link OverlayViewController} is in the foreground.
*
* For example, if the bottom and left system bars are enabled and this method returns
* WindowInsets.Side.LEFT, then the inset from the bottom system bar will be ignored.
*
* NOTE: By default, this method returns {@link #INVALID_INSET_SIDE}, so insets to fit are
* defined by {@link #getInsetTypesToFit()}, and not by this method, unless it is overridden
* by subclasses.
*
* NOTE: {@link #NO_INSET_SIDE} signifies no insets from any system bars will be honored. Each
* {@link OverlayViewController} can first take this value and add sides of the system bar
* insets to honor to it.
*
* NOTE: If getInsetSidesToFit is overridden to return {@link WindowInsets.Side}, it always
* takes precedence over {@link #getInsetTypesToFit()}. That is, the return value of {@link
* #getInsetTypesToFit()} will be ignored.
*/
@WindowInsets.Side.InsetsSide
protected int getInsetSidesToFit();
}
OverlayPanelViewController
ตัวควบคุม OverlayPanelViewController
ขยาย OverlayViewController
และเพิ่มความสามารถในการลากภาพเคลื่อนไหวไปยังคลาสซูเปอร์คลาส
OverlayViewMediator
OverlayViewMediator
ใช้ตรรกะทางธุรกิจที่เปิดเผยหรือซ่อนไว้
อินสแตนซ์ OverlayViewController
หลายอินสแตนซ์ ดังนั้นในลักษณะดังกล่าวจะจัดการ
การประสานงานระหว่างตัวควบคุมมุมมอง
/** * Controls when to show and hide {@link OverlayViewController}(s). */ public interface OverlayViewMediator { /** * Register listeners that could use ContentVisibilityAdjuster to show/hide content. * * Note that we do not unregister listeners because SystemUI components are expected to live * for the lifecycle of the device. */ void registerListeners(); /** * Allows for post-inflation callbacks and listeners to be set inside required {@link * OverlayViewController}(s). */ void setupOverlayContentViewControllers(); }
SystemUIOverlayWindowManager
SystemUIOverlayWindowManager
มีหน้าที่เป็นออบเจ็กต์ SystemUI ที่ให้บริการจุดแรกเข้าสำหรับ
SystemUIOverlayWindow
ระบบจัดการเพื่อเริ่มต้นและลงทะเบียน
OverlayViewMediator
อินสแตนซ์ที่มี OverlayViewGlobalStateController
มุมมองโฆษณาซ้อนทับ GlobalStateController
OverlayViewGlobalStateController
รับสายจาก
OverlayViewController
อินสแตนซ์เพื่อเปิดเผยหรือปิดบังตัวเอง ดังนั้นจึงยัง
เก็บสถานะของสิ่งที่แสดงหรือซ่อนใน SystemUIOverlayWindow
คุณสามารถดูขั้นตอนการแสดงรายการได้ที่ด้านล่าง
ซ่อนโฟลว์มุมมอง
ดูภาพประกอบขั้นตอนการซ่อนได้ที่ด้านล่าง
ลายเซ็นเมธอดแบบสาธารณะ
ลายเซ็นเมธอดสาธารณะมีการเข้ารหัสดังนี้
/**
* This controller is responsible for the following:
* <p><ul>
* <li>Holds the global state for SystemUIOverlayWindow.
* <li>Allows {@link SystemUIOverlayWindowManager} to register {@link OverlayViewMediator}(s).
* <li>Enables {@link OverlayViewController)(s) to reveal/conceal themselves while respecting the
* global state of SystemUIOverlayWindow.
* </ul>
*/
@SysUISingleton
public class OverlayViewGlobalStateController {
/**
* Register {@link OverlayViewMediator} to use in SystemUIOverlayWindow
.
*/
public void registerMediator(OverlayViewMediator overlayViewMediator);
/**
* Show content in Overlay Window using {@link OverlayPanelViewController}.
*
* This calls {@link OverlayViewGlobalStateController#showView(OverlayViewController, Runnable)}
* where the runnable is nullified since the actual showing of the panel is handled by the
* controller itself.
*/
public void showView(OverlayPanelViewController panelViewController);
/**
* Show content in Overlay Window using {@link OverlayViewController}.
*/
public void showView(OverlayViewController viewController, @Nullable Runnable show);
/**
* Hide content in Overlay Window using {@link OverlayPanelViewController}.
*
* This calls {@link OverlayViewGlobalStateController#hideView(OverlayViewController, Runnable)}
* where the runnable is nullified since the actual hiding of the panel is handled by the
* controller itself.
*/
public void hideView(OverlayPanelViewController panelViewController);
/**
* Hide content in Overlay Window using {@link OverlayViewController}.
*/
public void hideView(OverlayViewController viewController, @Nullable Runnable hide);
/** Returns {@code true} is the window is visible. */
public boolean isWindowVisible();
/**
* Sets the {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flag of the
* sysui overlay window.
*/
public void setWindowNeedsInput(boolean needsInput);
/** Returns {@code true} if the window is focusable. */
public boolean isWindowFocusable();
/** Sets the focusable flag of the sysui overlawy window. */
public void setWindowFocusable(boolean focusable);
/** Inflates the view controlled by the given view controller. */
public void inflateView(OverlayViewController viewController);
/**
* Return {@code true} if OverlayWindow is in a state where HUNs should be displayed above it.
*/
public boolean shouldShowHUN();
/**
* Set the OverlayViewWindow to be in occluded or unoccluded state. When OverlayViewWindow is
* occluded, all views mounted to it that are not configured to be shown during occlusion will
* be hidden.
*/
public void setOccluded(boolean occluded);
}
วิธีเพิ่มมุมมองไปยัง SysUIOverlayWindow
โปรดดูรายละเอียดที่ Codelab
ขั้นตอนที่ 1: เพิ่ม ViewStub ลงใน SysUIOverlayWindow
เพิ่มViewStub
ไปยัง
เลย์เอาต์หน้าต่าง
ขั้นตอนที่ 2: สร้าง OverlayViewController
ใช้ ViewStub
ใหม่เพื่อสร้าง Injectable ใหม่
OverlayViewController
ขั้นตอนที่ 3: OverlayViewMediator
สร้าง Injectable ใหม่
OverlayViewMediator
หรือใช้รายการที่มีอยู่ (ข้ามขั้นตอนที่ 4) และลงทะเบียน Listener เพื่อซ่อนหรือแสดง
OverlayViewController
ขั้นตอนที่ 4: กำหนดค่า OverlayViewMediator ใหม่
เพิ่มOverlayViewMediator
ใหม่ไปยัง
OverlayWindowModule
และ ถึง
config_carSystemUIOverlayViewsMediator
ข้อควรระวัง
เมื่อ SysUIPrimaryWindow
ครอบคลุมทั้งหน้าจอ องค์ประกอบใดก็ตามที่อยู่ใต้หน้าต่าง
ไม่บันทึกเหตุการณ์การแตะ ดังนั้นเมื่อหน้าต่างครอบคลุมทั้งหน้าจอยกเว้นเนื้อหา
ปล่อยพื้นที่ว่างไว้บางส่วน คุณสามารถเลือก
ที่จะเบลอพื้นที่เชิงลบและแนบ Listener ได้
เพื่อปิดเนื้อหาในหน้าต่างนั้น