最近在看android4.4 Keyguard 锁屏这块,趁没有忘记之前,做个笔记供自己以后快速的查看,文中有错误之处还望大家指正出来。
首先从最直观的入手----界面布局,刚接触 Keyguard时,发现它的布局还是有点复杂的,Keyguard 里的布局基本上都是采用FrameLayout来进行的,下面就从xml文件大致看下Keyguard的布局。
1. keyguard_host_view.xml,这个布局 port 和 land 的时候是不一样的,land是用作平板上的布局,不做分析。
<com.android.keyguard.KeyguardHostView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
android:id="@+id/keyguard_host_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.android.keyguard.SlidingChallengeLayout
android:id="@+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
androidprv:layout_childType="pageDeleteDropTarget">
<include layout="@layout/keyguard_widget_remove_drop_target"
android:id="@+id/keyguard_widget_pager_delete_target"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
androidprv:layout_childType="widgets">
<include layout="@layout/keyguard_widget_pager"
android:id="@+id/app_widget_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</FrameLayout>
<View android:layout_width="match_parent"
android:layout_height="match_parent"
androidprv:layout_childType="scrim"
android:background="#99000000" />
<com.android.keyguard.KeyguardSecurityContainer
android:id="@+id/keyguard_security_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
androidprv:layout_maxHeight="@dimen/keyguard_security_height"
androidprv:layout_childType="challenge"
android:padding="0dp"
android:gravity="bottom|center_horizontal">
<com.android.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="@dimen/keyguard_security_view_margin"
android:gravity="center">
</com.android.keyguard.KeyguardSecurityViewFlipper>
</com.android.keyguard.KeyguardSecurityContainer>
<ImageButton
android:layout_width="match_parent"
android:layout_height="@dimen/kg_widget_pager_bottom_padding"
androidprv:layout_childType="expandChallengeHandle"
android:focusable="true"
android:background="@null"
android:src="@drawable/keyguard_expand_challenge_handle"
android:scaleType="center"
android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
</com.android.keyguard.SlidingChallengeLayout>
</com.android.keyguard.KeyguardHostView>
这其实就是一个FrameLayout,KeyguardHostView 继承自 KeyguardViewBase,他们都是一个FrameLayout,Keyguard除一个Layout之外,其他的View,Layout都是基于这个Layout来的。
在分析这个布局之前,我们分析下KeyguardHostView是怎么添加上去的,我们知道Keyguard的布局都是采用FrameLayout,一层层叠加上去的,KeyguardHostView并不是最底层那个Layout。那么最底层的那层View是什么呢?
Keyguard 最底层的那个View,并没有采用xml布局的方式,而是直接写在java文件里,在KeyguardViewManager.java 这个类当中,有个ViewManagerHost 内部类,这就是我们要找的View,Keyguard 中所有的布局都是在ViewManagerHost基础上添加的,keyguard_host_view 就是第一个被加进来的,也从keyguard_host_view开始展开。
下面我们再来看看keyguard_host_view这个xml文件,最外层是SlidingChallengeLayout,主要用来处理一些交互,然后是 keyguard_widget_remove_drop_target,这个界面是我们拖动keyguard widget时会显示的删除按钮,接下来是 keyguard_widget_pager,这个主要是用来添加widget用,再接下来是KeyguardSecurityContainer 和KeyguardSecurityViewFlipper,这个就是锁的界面,我们一些图案,PIN锁屏方式都是通过这个View展示出来的。最后是一个ImageButton 就是一个锁的按钮,在进入到不同widget pager切换滑动时,这个按钮就会显示出来,锁屏图案就会隐藏,点击这个按钮可以显示锁屏图案退出widget pager滑动。这就是KeyguardHostView的大体布局。
2. keyguard_account_view.xml, 账户登录解锁,在忘记密码时,你可以登录一个Google账号进行解锁。
3. keyguard_add_widget.xml,这是供添加锁屏widget用,这里主要是一个 keyguard_add_widget_view ImageView,可以通过点击该ImageView进行widget的添加。
4. keyguard_emergency_carrier_area.xml 显示紧急拨号,和忘记密码按钮。
5. keyguard_face_unlock_view.xml,该界面主要是面部解锁布局。
6. keyguard_glow_pad_view.xml,通过 GlowPadView 这个View,你也可以自己很容易实现一个类似的拖拽界面。
7. keyguard_message_area.xml, 这其实是一个 TextView 主要是显示一些信息的,如充电状态,机主信息
8. keyguard_password_view.xml,这个就是密码锁屏的界面了
9. keyguard_pattern_view.xml 图案锁屏界面
10. keyguard_pin_view.xml PIN码锁屏界面
11. keyguard_selector_view.xml 这个就是默认 SecurityMode 为 None的默认锁屏界面
12. keyguard_sim_puk_view.xml,PUK码锁屏界面
13. keyguard_status_area.xml, 日期和闹钟信息
14. keyguard_status_view.xml,这个是时钟信息,将keyguard_status_area 布局包含在这里面
15. keyguard_transport_control_view.xml 显示音乐播放器的widget
16. keyguard_widget_pager.xml,注意这个port 和 land 的布局是不同的,这个KeyguardWidgetPager 主要是实现了不同widget页面间的滑动
上面的这些锁屏方式布局,如keyguard_pattern_view.xml, keyguard_selector_view.xml,keyguard_pin_view.xml,等等,都是加载到 KeyguardSecurityViewFlipper
这个容器当中的,这就是Keyguard的一些布局文件,这些布局基本上是根据不同的状态加载或显示出来的,慢慢的分析这些文件,Keyguard的布局也就渐渐的变得清晰了
接下来的文章将会根据代码来分析锁屏的流程。