天天看點

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

StatusBar

從相關的布局檔案xml中可以找到狀态欄主要的Layout:

  • 1 StatusBarWindowView是狀态欄根布局
  • 2 BackDropView
  • 3 ScrimView是狀态欄下拉後,背景,半透明灰色
  • 4 status_bar狀态欄的布局
  • 5 PanelHolder,下拉通知欄布局
<com.android.systemui.statusbar.phone.StatusBarWindowView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <com.android.systemui.statusbar.BackDropView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            >
        <ImageView android:id="@+id/backdrop_back"
                   android:layout_width="match_parent"
                   android:scaleType="centerCrop"
                   android:layout_height="match_parent" />
        <ImageView android:id="@+id/backdrop_front"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:scaleType="centerCrop"
                   android:visibility="invisible" />
    </com.android.systemui.statusbar.BackDropView>
    <com.android.systemui.statusbar.ScrimView
        android:id="@+id/scrim_behind"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no" />
    <include layout="@layout/status_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/status_bar_height" />
    <FrameLayout android:id="@+id/brightness_mirror"
                 android:layout_width="@dimen/notification_panel_width"
                 android:layout_height="wrap_content"
                 android:layout_gravity="@integer/notification_panel_layout_gravity"
                 android:paddingLeft="@dimen/notification_side_padding"
                 android:paddingRight="@dimen/notification_side_padding"
                 android:visibility="gone">
        <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:elevation="2dp"
                android:background="@drawable/brightness_mirror_background">
            <include layout="@layout/quick_settings_brightness_dialog"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content" />
        </FrameLayout>
    </FrameLayout>
    <com.android.systemui.statusbar.phone.PanelHolder
        android:id="@+id/panel_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent" >
        <include layout="@layout/status_bar_expanded"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </com.android.systemui.statusbar.phone.PanelHolder>
    <com.android.systemui.statusbar.ScrimView
        android:id="@+id/scrim_in_front"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no" />
</com.android.systemui.statusbar.phone.StatusBarWindowView>

           

ScrimView

将ScrimView的背景繪制成紅色,可以發現ScrimView的布局範圍,如下圖:

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

即在 ScrimView 中 執行 canvas.drawColor(Color.RED, mode);

public class ScrimView extends View
{
    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
            PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
            int color = mScrimColor;
            color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
                    Color.green(color), Color.blue(color));
            canvas.drawColor(Color.RED, mode);
        }
    }
}

           

PanelHolder

如果把PanelHolder也設定成紅色背景,也會出現上面的情況,而且狀态欄不能看到圖示&時間,說明PanelHolder在圖示、時間之上,而且寬度占滿螢幕

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror
【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

下拉通知欄布局

通過工具找到通知欄下拉後的布局

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

根布局為 super_status_bar.xml

<com.android.systemui.statusbar.phone.PanelHolder
        android:id="@+id/panel_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent" >
        <include layout="@layout/status_bar_expanded"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </com.android.systemui.statusbar.phone.PanelHolder>

           

從這段代碼看到,include的layout檔案為 status_bar_expanded.xml

status_bar_expanded.xml的檔案根布局為

com.android.systemui.statusbar.phone.NotificationPanelView
           

從dump view hierarchy工具擷取到的id為 notification_stack_scroller, 這個id在status_bar_expanded.xml 中,

NotificationPanelView是PanelView的子類

public class NotificationPanelView extends PanelView
           

PanelView繼承了FrameLayout

public abstract class PanelView extends FrameLayout
           

status_bar_expanded.xml下有幾個布局、控件

1 carrier_label: 顯示營運商标簽
2 keyguard_status_view.xml:鎖屏UI的時鐘資訊,将keyguard_status_area 布局包含在這裡面
3 emergency_calls_only: 緊急電話TextView
4 notification_container_parent: NotificationsQuickSettingsContainer 下拉通知欄布局容器
5 scroll_view:ObservableScrollView, 滾動視圖,包括快速設定按鈕布局、通知資訊分割線 reserve_notification_space等
6 notification_stack_scroller: NotificationStackScrollLayout 可滾動的通知欄布局
           

如果把notification_stack_scroller的width設定為match_parent,

<com.android.systemui.statusbar.stack.NotificationStackScrollLayout
            android:id="@+id/notification_stack_scroller"
            android:layout_width="@dimen/notification_panel_width"
            android:layout_height="match_parent"
            android:layout_gravity="@integer/notification_panel_layout_gravity"
            android:layout_marginBottom="@dimen/close_handle_underlap"
            android:importantForAccessibility="no" />

           

會有下面的效果。通知清單與螢幕等寬,說明NotificationStackScrollLayout是通知清單的容器布局

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

如果把ObservableScrollView, scroll_view 的width設定為match_parent,

<com.android.systemui.statusbar.phone.ObservableScrollView
            android:id="@+id/scroll_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="@integer/notification_panel_layout_gravity"
            android:scrollbars="none"
            android:overScrollMode="never"
            android:fillViewport="true">

           

會有下面效果。說明scroll_view是包含快捷按鍵的Layout布局

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

下拉通知欄頭部布局

布局檔案如下:

<include layout="@layout/status_bar_expanded_header" />
           
【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

根布局

<com.android.systemui.statusbar.phone.StatusBarHeaderView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    android:id="@+id/header"
    android:layout_width="@dimen/notification_panel_width"
    android:layout_height="@dimen/status_bar_header_height"
    android:layout_gravity="@integer/notification_panel_layout_gravity"
    android:paddingStart="@dimen/notification_side_padding"
    android:paddingEnd="@dimen/notification_side_padding"
    android:baselineAligned="false"
    android:elevation="4dp"
    android:background="@drawable/notification_header_bg"
    android:clickable="true"
    android:focusable="true"
    >

           

如果将android:layout_width="@dimen/notification_panel_width"改成match_parent,頭部布局會鋪滿螢幕

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

調節亮度 brightness_mirror

brightness_mirror是通過通知欄調節亮度時,彈出亮度框的布局

【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror
【Android系統源碼修改】如何分析SystemUI Layout 的組成StatusBarScrimViewPanelHolder下拉通知欄布局下拉通知欄頭部布局調節亮度 brightness_mirror

super_status_bar.xml

修改其width可以修改layout的寬度

<FrameLayout android:id="@+id/brightness_mirror"
                 android:layout_width="@dimen/notification_panel_width"
                 android:layout_height="wrap_content"
                 android:layout_gravity="@integer/notification_panel_layout_gravity"
                 android:paddingLeft="@dimen/notification_side_padding"
                 android:paddingRight="@dimen/notification_side_padding"
                 android:visibility="gone">