Android4.4之Keyguard--KeyguardSecurityViewHelper

KeyguardSecurityViewHelper

这个类的作用是帮助所有的KeyguardSecurityView实现两个基本方法:showBouncer和hideBouncer。

public static void showBouncer(SecurityMessageDisplay securityMessageDisplay, final View ecaView, Drawable bouncerFrame, int duration) {
    //1st securityMessageDisplay不为空,则直接调用它的showBouncer方法
    if (securityMessageDisplay != null) {
        securityMessageDisplay.showBouncer(duration);
    }

    //2nd ecaView不为空,则令其不可见,并设置为完全透明
    if (ecaView != null) {
	//如果duration>0,则需要渐进地达到不可见和完全透明的效果
        if (duration > 0) {
			//这里的0f表明最终目标是要达到透明度为0--完全透明
            Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f);
            anim.setDuration(duration);
            anim.addListener(new AnimatorListenerAdapter() {
                private boolean mCanceled;
                @Override
                public void onAnimationCancel(Animator animation) {
                    //如果在过程中用户取消,标记mCanceled并设置完全可见
                    mCanceled = true;
                    ecaView.setAlpha(1f);
                }
                @Override
                public void onAnimationEnd(Animator animation) {
		    //动画结束,如果不曾取消过,则设置其不可见
                    ecaView.setVisibility(mCanceled ? View.VISIBLE : View.INVISIBLE);
                }
            });
            anim.start();
        } else {
	    //不需动画效果,直接设置完全透明和不可见
            ecaView.setAlpha(0f);
            ecaView.setVisibility(View.INVISIBLE);
        }
    }

    //3nd bouncerFrame不为空,则设置其完全不透明
    if (bouncerFrame != null) {
        if (duration > 0) {
			//需要动画显示,则从0--完全透明到255--完全不透明	
            Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0, 255);
            anim.setDuration(duration);
            anim.start();
        } else {
			//不需要动画显示,则直接设置其完全不透明
            bouncerFrame.setAlpha(255);
        }
    }
}

从这里的分析可以看出,这里的操作取决于securityMessageDisplay、ecaView和bouncerFrame是否为空,它们分别代码三个view,执行不同的操作。

如果这三者都是空的,则什么也不做。

hideBouncer与showBouncer方法类似,只是效果刚好相反而已。


下面来看看这三个view到底是什么?

1. securityMessageDisplay

首先,它是SecurityMessageDisplay接口的实例,它其实是个KeyguardMessageArea:

mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);

//KeyguardMessageArea.java
public static class Helper implements SecurityMessageDisplay {
    KeyguardMessageArea mMessageArea;
    Helper(View v) {
        mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
        if (mMessageArea == null) {
            throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
        }
    }

    //它的操作很简单,只是要hideMessage
    public void showBouncer(int duration) {
        mMessageArea.hideMessage(duration, false);
        mMessageArea.mShowingBouncer = true;
    }
    ......
}

//这个方法因为调用时thenUpdate为false,因此我就把thenUpdate相关的删除了
//这个方法实际的工作就是令KeyguardMessageArea完全透明(KeyguardMessageArea extends TextView)
private void hideMessage(int duration, boolean thenUpdate) {
    if (duration > 0) {
        Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
        anim.setDuration(duration);
        anim.start();
    } else {
        setAlpha(0f);
    }
}

2. ecaView

这个ecaView实际是EmergencyCarrierArea。

以keyguard_pattern_view.xml为例,在它的布局文件中有如下:

<include layout="@layout/keyguard_eca"
	android:id="@+id/keyguard_selector_fade_container"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:orientation="vertical"
	android:layout_gravity="bottom|center_horizontal"
	android:gravity="center_horizontal" />
id为keyguard_selector_fade_container,include layout为keyguard_eca,它实际是一个引用,指向另一个layout:

values-land/alias.xml
<resources>
    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area_empty</item>
</resources>

keyguard_emergency_carrier_area_empty.xml
<!-- This is a blank layout to simplify implementation on landscape on phones
     it is referenced indirectly by keyguard_eca -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dip"
    android:layout_height="0dip"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_gravity="center_horizontal"
    android:layout_alignParentBottom="true">
</LinearLayout>

values-port/alias.xml
<resources>
    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
</resources>

对于alias.xml文件,有横屏和竖屏两种配置。

对于横屏,它指向的布局文件为keyguard_emergency_carrier_area_empty.xml

从文件名称、xml文件中的注释以及layout_width和layout_height的值都为0dip可以看出,这是一个不占空间的布局文件。忽略它。

对于竖屏,它指向的布局文件为keyguard_emergency_carrier_area.xml。

它就比较复杂了,其中有一个TextView和两个Button。

下面来看看各个KeyguardSecurityView的两个方法:showBouncer和hideBouncer

我们知道一共有11个KeyguardSecurityView的实例,这其中有两个比较特殊。

一般地,实现如下:

//onFinishInflate方法中
mEcaView = findViewById(R.id.keyguard_selector_fade_container);

第一个特殊的是KeyguardSelectorView

public void setCarrierArea(View carrierArea) {
    mFadeView = carrierArea;
    /// M: [ALPS00475227] To avoid blade shade while using marquee with alpha animation @{
    mFadeView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}

public void showBouncer(int duration) {
    mIsBouncing = true;
    KeyguardSecurityViewHelper.showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
}

//KeyguardHostView.java  getSecurityView方法
if (view instanceof KeyguardSelectorView) {
    KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
    View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
    selectorView.setCarrierArea(carrierText);
}

第二个特殊的是KeyguardAccountView

它的布局文件keyguard_account_view.xml中没有定义这个view,有如下注释

<!--  no room for ECA on this screen right now -->

因此它的showBouncer和hideBouncer的实现均为空实现。


3. mBouncerFrame

它是个Background,各view的实现基本与ecaView一致:KeyguardAccountView没有,KeyguardSelectorView使用上特殊一些

一般地:

View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
if (bouncerFrameView != null) {
    mBouncerFrame = bouncerFrameView.getBackground();
}
KeyguardSelectorView在布局文件中的id特殊

//onFinishInflate方法    
View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
mBouncerFrame = bouncerFrameView.getBackground();


关于透明度设置的API:

1. setAlpha

public void setAlpha (float alpha)
Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is completely transparent and 1 means the view is completely opaque.

protected boolean onSetAlpha (int alpha)
参数a为透明度,取值范围为0~255,数值越小越透明


2. public static ObjectAnimator ofInt (Object target, String propertyName, int... values)

Constructs and returns an ObjectAnimator that animates between int values.

A single value implies that that value is the one being animated to.

Two values imply a starting and ending values.

More than two values imply a starting value, values to animate through along the way, and an ending value (these values will be distributed evenly across the duration of the animation).






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值