AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】

时间:2021-06-17 17:17:26

先来说说LockScreen分类;

        一、无锁屏;

        二、锁屏:

                1、UnLockScreen:

                        图案锁、 PIN锁, 密码锁;

                2、LockScreen:

                        波纹锁;

 

           转载请表明出处:http://blog.csdn.net/wdaming1986/article/details/7753206

 

                 有图有真相------>

                     AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】

 

         接着我们来看看LockScreen的时序图:  

AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】

 

综上所述:

 1、createUnlockScreenFor()方法创建的是UnLockScreen界面,代码如下:

  1. View createUnlockScreenFor(UnlockMode unlockMode) {  
  2.        View unlockView = null;  
  3.   
  4.        if (DEBUG) Log.d(TAG,  
  5.                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);  
  6.   
  7.        if (unlockMode == UnlockMode.Pattern) {  
  8.            PatternUnlockScreen view = new PatternUnlockScreen(  
  9.                    mContext,  
  10.                    mConfiguration,  
  11.                    mLockPatternUtils,  
  12.                    mUpdateMonitor,  
  13.                    mKeyguardScreenCallback,  
  14.                    mUpdateMonitor.getFailedAttempts());  
  15.            view.setEnableFallback(mEnableFallback);  
  16.            unlockView = view;  
  17.        } else if (unlockMode == UnlockMode.SimPuk) {  
  18.            unlockView = new SimPukUnlockScreen(  
  19.                    mContext,  
  20.                    mConfiguration,  
  21.                    mUpdateMonitor,  
  22.                    mKeyguardScreenCallback,  
  23.                    mLockPatternUtils, MSimTelephonyManager.getDefault().getDefaultSubscription());  
  24.        } else if (unlockMode == UnlockMode.SimPin) {  
  25.            unlockView = new SimUnlockScreen(  
  26.                    mContext,  
  27.                    mConfiguration,  
  28.                    mUpdateMonitor,  
  29.                    mKeyguardScreenCallback,  
  30.                    mLockPatternUtils);  
  31.        } else if (unlockMode == UnlockMode.Account) {  
  32.            try {  
  33.                unlockView = new AccountUnlockScreen(  
  34.                        mContext,  
  35.                        mConfiguration,  
  36.                        mUpdateMonitor,  
  37.                        mKeyguardScreenCallback,  
  38.                        mLockPatternUtils);  
  39.            } catch (IllegalStateException e) {  
  40.                Log.i(TAG, "Couldn't instantiate AccountUnlockScreen"  
  41.                      + " (IAccountsService isn't available)");  
  42.                // TODO: Need a more general way to provide a  
  43.                // platform-specific fallback UI here.  
  44.                // For now, if we can't display the account login  
  45.                // unlock UI, just bring back the regular "Pattern" unlock mode.  
  46.   
  47.                // (We do this by simply returning a regular UnlockScreen  
  48.                // here.  This means that the user will still see the  
  49.                // regular pattern unlock UI, regardless of the value of  
  50.                // mUnlockScreenMode or whether or not we're in the  
  51.                // "permanently locked" state.)  
  52.                return createUnlockScreenFor(UnlockMode.Pattern);  
  53.            }  
  54.        } else if (unlockMode == UnlockMode.Password) {  
  55.            unlockView = new PasswordUnlockScreen(  
  56.                    mContext,  
  57.                    mConfiguration,  
  58.                    mLockPatternUtils,  
  59.                    mUpdateMonitor,  
  60.                    mKeyguardScreenCallback);  
  61.        } else {  
  62.            throw new IllegalArgumentException("unknown unlock mode " + unlockMode);  
  63.        }  
  64.        initializeTransportControlView(unlockView);  
  65.        initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled  
  66.   
  67.        mUnlockScreenMode = unlockMode;  
  68.        return unlockView;  
  69.    }  

 


2、createLockScreen()就是创建LockScreen界面:

  1. View createLockScreen() {  
  2.         /*View lockView = new LockScreen( 
  3.                 mContext, 
  4.                 mConfiguration, 
  5.                 mLockPatternUtils, 
  6.                 mUpdateMonitor, 
  7.                 mKeyguardScreenCallback); 
  8.          initializeTransportControlView(lockView); 
  9.          return lockView;*/  
  10.           
  11.         long lockscreenType = 0;  
  12.         try{  
  13.             lockscreenType = android.provider.Settings.Secure.  
  14.                     getLong(mContext.getContentResolver(), "lockscreen.disabled");  
  15.         }catch(Exception e){  
  16.             e.printStackTrace();  
  17.         }  
  18.         View lockView = null;  
  19.          lockView = new LockScreen(  
  20.                     mContext,  
  21.                     mConfiguration,  
  22.                     mLockPatternUtils,  
  23.                     mUpdateMonitor,  
  24.                     mKeyguardScreenCallback);     
  25.          initializeTransportControlView(lockView);  
  26.         return lockView;  
  27. }  


我们来看看锁屏界面的流程:

 

step 1:创建LockScreen.java类——>先看看构造函数:

  1. LockScreen(Context context, Configuration configuration, LockPatternUtils lockPatternUtils,  
  2.            KeyguardUpdateMonitor updateMonitor,  
  3.            KeyguardScreenCallback callback) {  
  4.        super(context);  
  5.        mLockPatternUtils = lockPatternUtils;  
  6.        mUpdateMonitor = updateMonitor;  
  7.        mCallback = callback;  
  8.   
  9.        mEnableMenuKeyInLockScreen = shouldEnableMenuKey();  
  10.   
  11.        mCreationOrientation = configuration.orientation;  
  12.   
  13.        mKeyboardHidden = configuration.hardKeyboardHidden;  
  14.   
  15.        if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {  
  16.            Log.v(TAG, "***** CREATING LOCK SCREEN"new RuntimeException());  
  17.            Log.v(TAG, "Cur orient=" + mCreationOrientation  
  18.                    + " res orient=" + context.getResources().getConfiguration().orientation);  
  19.        }  
  20.   
  21.        final LayoutInflater inflater = LayoutInflater.from(context);  
  22.        if (DBG) Log.v(TAG, "Creation orientation = " + mCreationOrientation);  
  23.        if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {  
  24.            inflater.inflate(R.layout.keyguard_screen_tab_unlock, thistrue);  
  25.        } else {  
  26.            inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, thistrue);  
  27.        }  
  28.   
  29.        if (TelephonyManager.getDefault().isMultiSimEnabled()) {  
  30.            mStatusViewManager = new MSimKeyguardStatusViewManager(this, mUpdateMonitor,  
  31.                    mLockPatternUtils, mCallback, false);  
  32.        } else {  
  33.            mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor,  
  34.                    mLockPatternUtils, mCallback, false);  
  35.        }  
  36.   
  37.        setFocusable(true);  
  38.        setFocusableInTouchMode(true);  
  39.        setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);  
  40.   
  41.        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);  
  42.        // modify by wangxianming in 2012-06-22  
  43.        if (mAudioManager != null) {  
  44.         mSilentMode = isSilentMode();  
  45.        }  
  46.   
  47.        mUnlockWidget = findViewById(R.id.unlock_widget);  
  48.        if (mUnlockWidget instanceof SlidingTab) {  
  49.            SlidingTab slidingTabView = (SlidingTab) mUnlockWidget;  
  50.            slidingTabView.setHoldAfterTrigger(truefalse);  
  51.            slidingTabView.setLeftHintText(R.string.lockscreen_unlock_label);  
  52.            slidingTabView.setLeftTabResources(  
  53.                    R.drawable.ic_jog_dial_unlock,  
  54.                    R.drawable.jog_tab_target_green,  
  55.                    R.drawable.jog_tab_bar_left_unlock,  
  56.                    R.drawable.jog_tab_left_unlock);  
  57.            SlidingTabMethods slidingTabMethods = new SlidingTabMethods(slidingTabView);  
  58.            slidingTabView.setOnTriggerListener(slidingTabMethods);  
  59.            mUnlockWidgetMethods = slidingTabMethods;  
  60.        } else if (mUnlockWidget instanceof WaveView) {  
  61.            WaveView waveView = (WaveView) mUnlockWidget;  
  62.            WaveViewMethods waveViewMethods = new WaveViewMethods(waveView);  
  63.            waveView.setOnTriggerListener(waveViewMethods);  
  64.            mUnlockWidgetMethods = waveViewMethods;  
  65.        } else if (mUnlockWidget instanceof MultiWaveView) {  
  66.            MultiWaveView multiWaveView = (MultiWaveView) mUnlockWidget;  
  67.            MultiWaveViewMethods multiWaveViewMethods = new MultiWaveViewMethods(multiWaveView);  
  68.            multiWaveView.setOnTriggerListener(multiWaveViewMethods);  
  69.            mUnlockWidgetMethods = multiWaveViewMethods;  
  70.        } else {  
  71.            throw new IllegalStateException("Unrecognized unlock widget: " + mUnlockWidget);  
  72.        }  
  73.   
  74.        // Update widget with initial ring state  
  75.        mUnlockWidgetMethods.updateResources();  
  76.   
  77.        if (DBG) Log.v(TAG, "*** LockScreen accel is "  
  78.                + (mUnlockWidget.isHardwareAccelerated() ? "on":"off"));  
  79.    }  

 


Step 2:在Step 1步骤中根据横竖屏来加载横竖屏的布局:

  1. if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {  
  2.             inflater.inflate(R.layout.keyguard_screen_tab_unlock, thistrue);  
  3.         } else {  
  4.             inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, thistrue);  
  5.         }  

 


Step 3:来看看竖屏的布局文件的代码:

  1. <GridLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:gravity="center_horizontal">  
  7.     <!-- 锁屏界面加载数字时钟 -->  
  8.     <com.android.internal.widget.DigitalClock android:id="@+id/time"  
  9.         android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin"  
  10.         android:layout_marginBottom="12dip"  
  11.         android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin"  
  12.         android:layout_gravity="right">  
  13.   
  14.         <!-- Because we can't have multi-tone fonts, we render two TextViews, one on  
  15.         top of the other. Hence the redundant layout... -->  
  16.         <TextView android:id="@+id/timeDisplayBackground"  
  17.             android:layout_width="wrap_content"  
  18.             android:layout_height="wrap_content"  
  19.             android:singleLine="true"  
  20.             android:ellipsize="none"  
  21.             android:textSize="@dimen/keyguard_lockscreen_clock_font_size"  
  22.             android:textAppearance="?android:attr/textAppearanceMedium"  
  23.             android:layout_marginBottom="6dip"  
  24.             android:textColor="@color/lockscreen_clock_background"  
  25.             />  
  26.   
  27.         <TextView android:id="@+id/timeDisplayForeground"  
  28.             android:layout_width="wrap_content"  
  29.             android:layout_height="wrap_content"  
  30.             android:singleLine="true"  
  31.             android:ellipsize="none"  
  32.             android:textSize="@dimen/keyguard_lockscreen_clock_font_size"  
  33.             android:textAppearance="?android:attr/textAppearanceMedium"  
  34.             android:layout_marginBottom="6dip"  
  35.             android:textColor="@color/lockscreen_clock_foreground"  
  36.             android:layout_alignLeft="@id/timeDisplayBackground"  
  37.             android:layout_alignTop="@id/timeDisplayBackground"  
  38.             />  
  39.   
  40.     </com.android.internal.widget.DigitalClock>  
  41.   
  42.     <LinearLayout  
  43.         android:orientation="horizontal"  
  44.         android:layout_gravity="right"  
  45.         android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin">  
  46.         <!-- 锁屏界面加载日期 -->  
  47.         <TextView  
  48.             android:id="@+id/date"  
  49.             android:layout_width="wrap_content"  
  50.             android:layout_height="wrap_content"  
  51.             android:singleLine="true"  
  52.             android:ellipsize="marquee"  
  53.             android:textAppearance="?android:attr/textAppearanceMedium"  
  54.             android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"  
  55.             />  
  56.         <!-- 锁屏界面加载闹钟状态 -->  
  57.         <TextView  
  58.             android:id="@+id/alarm_status"  
  59.             android:layout_width="wrap_content"  
  60.             android:layout_height="wrap_content"  
  61.             android:layout_marginLeft="16dip"  
  62.             android:singleLine="true"  
  63.             android:ellipsize="marquee"  
  64.             android:textAppearance="?android:attr/textAppearanceMedium"  
  65.             android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"  
  66.             android:drawablePadding="4dip"  
  67.             />  
  68.   
  69.     </LinearLayout>  
  70.     <!-- 锁屏界面加载充电状态 -->  
  71.     <TextView  
  72.         android:id="@+id/status1"  
  73.         android:layout_gravity="right"  
  74.         android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin"  
  75.         android:singleLine="true"  
  76.         android:ellipsize="marquee"  
  77.         android:textAppearance="?android:attr/textAppearanceMedium"  
  78.         android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"  
  79.         android:drawablePadding="4dip"  
  80.         />  
  81.   
  82.     <Space android:layout_gravity="fill" />  
  83.         <RelativeLayout  
  84.         android:layout_width="match_parent"  
  85.         android:layout_height="302dip">  
  86.         <!-- 锁屏界面加载波纹的锁屏 -->  
  87.         <com.android.internal.widget.multiwaveview.MultiWaveView  
  88.             android:id="@+id/unlock_widget"  
  89.             android:orientation="horizontal"  
  90.             android:layout_width="match_parent"  
  91.             android:layout_height="match_parent"  
  92.             android:layout_alignParentBottom="true"  
  93.   
  94.             android:targetDrawables="@array/lockscreen_targets_with_camera"  
  95.             android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"  
  96.             android:directionDescriptions="@array/lockscreen_direction_descriptions"  
  97.             android:handleDrawable="@drawable/ic_lockscreen_handle"  
  98.             android:waveDrawable="@drawable/ic_lockscreen_outerring"  
  99.             android:outerRadius="@dimen/multiwaveview_target_placement_radius"  
  100.             android:snapMargin="@dimen/multiwaveview_snap_margin"  
  101.             android:hitRadius="@dimen/multiwaveview_hit_radius"  
  102.             android:rightChevronDrawable="@drawable/ic_lockscreen_chevron_right"  
  103.             android:horizontalOffset="0dip"  
  104.             android:verticalOffset="60dip"  
  105.             android:feedbackCount="3"  
  106.             android:vibrationDuration="20"  
  107.             />  
  108.         <!-- 锁屏界面加载运营商状态 -->  
  109.         <TextView  
  110.             android:id="@+id/carrier"  
  111.             android:layout_width="fill_parent"  
  112.             android:layout_height="wrap_content"  
  113.             android:layout_alignParentBottom="true"  
  114.             android:layout_marginBottom="12dip"  
  115.             android:gravity="center_horizontal"  
  116.             android:singleLine="true"  
  117.             android:ellipsize="marquee"  
  118.             android:textAppearance="?android:attr/textAppearanceMedium"  
  119.             android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"  
  120.             android:textColor="?android:attr/textColorSecondary"  
  121.             />  
  122.   
  123.     </RelativeLayout>  
  124.   
  125.     <LinearLayout  
  126.         android:orientation="horizontal"  
  127.         android:layout_width="match_parent"  
  128.         style="?android:attr/buttonBarStyle"  
  129.         android:gravity="center"  
  130.         android:weightSum="2">  
  131.         <!-- 锁屏界面加载紧急拨号按钮 -->  
  132.         <Button android:id="@+id/emergencyCallButton"  
  133.             android:layout_gravity="center_horizontal"  
  134.             android:layout_width="0dip"  
  135.             android:layout_height="wrap_content"  
  136.             android:layout_weight="1"  
  137.             style="?android:attr/buttonBarButtonStyle"  
  138.             android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"  
  139.             android:text="@*android:string/lockscreen_emergency_call"  
  140.             android:drawableLeft="@*android:drawable/lockscreen_emergency_button"  
  141.             android:drawablePadding="0dip"  
  142.             android:visibility="gone"  
  143.         />  
  144.   
  145.     </LinearLayout>  
  146.   
  147. </GridLayout>  


 

Step 4:在Step 3中重点看com.android.internal.widget.multiwaveview.MultiWaveView这个自定义的view,这个view是处理ICS4.0锁屏的拖拽的功能,具体代码如下:

  1.  public MultiWaveView(Context context, AttributeSet attrs) {  
  2.         super(context, attrs);  
  3.         Resources res = context.getResources();  
  4. 。。。 。。。  
  5. 加载资源  
  6. 。。。 。。。  
  7. }  

 

通过onMeasure()来计算自定义view的大小:

  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  2.        final int minimumWidth = getSuggestedMinimumWidth();  
  3.        final int minimumHeight = getSuggestedMinimumHeight();  
  4.        int viewWidth = resolveMeasured(widthMeasureSpec, minimumWidth);  
  5.        int viewHeight = resolveMeasured(heightMeasureSpec, minimumHeight);  
  6.        setMeasuredDimension(viewWidth, viewHeight);  
  7.    }  


 

通过onLayout()来加载布局:

  1. protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  
  2.        super.onLayout(changed, left, top, right, bottom);  
  3.        final int width = right - left;  
  4.        final int height = bottom - top;  
  5.        float newWaveCenterX = mHorizontalOffset + Math.max(width, mOuterRing.getWidth() ) / 2;  
  6.        float newWaveCenterY = mVerticalOffset + Math.max(height, mOuterRing.getHeight()) / 2;  
  7.        if (newWaveCenterX != mWaveCenterX || newWaveCenterY != mWaveCenterY) {  
  8.            if (mWaveCenterX == 0 && mWaveCenterY == 0) {  
  9.                performInitialLayout(newWaveCenterX, newWaveCenterY);  
  10.            }  
  11.            mWaveCenterX = newWaveCenterX;  
  12.            mWaveCenterY = newWaveCenterY;  
  13.   
  14.            mOuterRing.setX(mWaveCenterX);  
  15.            mOuterRing.setY(Math.max(mWaveCenterY, mWaveCenterY));  
  16.   
  17.            updateTargetPositions();  
  18.        }  
  19.        if (DEBUG) dump();  
  20.    }  


Step 5:来看看触摸屏幕时的事件处理onTouchEvent()代码如下:

  1. @Override  
  2.    public boolean onTouchEvent(MotionEvent event) {  
  3.        final int action = event.getAction();  
  4.   
  5.        boolean handled = false;  
  6.        switch (action) {  
  7.            case MotionEvent.ACTION_DOWN:  
  8.                handleDown(event);  
  9.                handled = true;  
  10.                break;  
  11.   
  12.            case MotionEvent.ACTION_MOVE:  
  13.                handleMove(event);  
  14.                handled = true;  
  15.                break;  
  16.   
  17.            case MotionEvent.ACTION_UP:  
  18.                handleMove(event);  
  19.                handleUp(event);  
  20.                handled = true;  
  21.                break;  
  22.   
  23.            case MotionEvent.ACTION_CANCEL:  
  24.                handleMove(event);  
  25.                handled = true;  
  26.                break;  
  27.        }  
  28.        invalidate();  
  29.        return handled ? true : super.onTouchEvent(event);  
  30.    }  


通过handleMove()来处理移动事件:

  1. private void handleMove(MotionEvent event) {  
  2.        if (!mDragging) {  
  3.            trySwitchToFirstTouchState(event);  
  4.            return;  
  5.        }  
  6.   
  7.        int activeTarget = -1;  
  8.        final int historySize = event.getHistorySize();  
  9.        for (int k = 0; k < historySize + 1; k++) {  
  10.            float x = k < historySize ? event.getHistoricalX(k) : event.getX();  
  11.            float y = k < historySize ? event.getHistoricalY(k) : event.getY();  
  12.            float tx = x - mWaveCenterX;  
  13.            float ty = y - mWaveCenterY;  
  14.            float touchRadius = (float) Math.sqrt(dist2(tx, ty));  
  15.            final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;  
  16.            float limitX = mWaveCenterX + tx * scale;  
  17.            float limitY = mWaveCenterY + ty * scale;  
  18.   
  19.            boolean singleTarget = mTargetDrawables.size() == 1;  
  20.            if (singleTarget) {  
  21.                // Snap to outer ring if there's only one target  
  22.                float snapRadius = mOuterRadius - mSnapMargin;  
  23.                if (touchRadius > snapRadius) {  
  24.                    activeTarget = 0;  
  25.                    x = limitX;  
  26.                    y = limitY;  
  27.                }  
  28.            } else {  
  29.                // If there's more than one target, snap to the closest one less than hitRadius away.  
  30.                float best = Float.MAX_VALUE;  
  31.                final float hitRadius2 = mHitRadius * mHitRadius;  
  32.                for (int i = 0; i < mTargetDrawables.size(); i++) {  
  33.                    // Snap to the first target in range  
  34.                    TargetDrawable target = mTargetDrawables.get(i);  
  35.                    float dx = limitX - target.getX();  
  36.                    float dy = limitY - target.getY();  
  37.                    float dist2 = dx*dx + dy*dy;  
  38.                    if (target.isValid() && dist2 < hitRadius2 && dist2 < best) {  
  39.                        activeTarget = i;  
  40.                        best = dist2;  
  41.                    }  
  42.                }  
  43.                x = limitX;  
  44.                y = limitY;  
  45.            }  
  46.            if (activeTarget != -1) {  
  47.                switchToState(STATE_SNAP, x,y);  
  48.                float newX = singleTarget ? limitX : mTargetDrawables.get(activeTarget).getX();  
  49.                float newY = singleTarget ? limitY : mTargetDrawables.get(activeTarget).getY();  
  50.                moveHandleTo(newX, newY, false);  
  51.                TargetDrawable currentTarget = mTargetDrawables.get(activeTarget);  
  52.                if (currentTarget.hasState(TargetDrawable.STATE_FOCUSED)) {  
  53.                    currentTarget.setState(TargetDrawable.STATE_FOCUSED);  
  54.                    mHandleDrawable.setAlpha(0.0f);  
  55.                }  
  56.            } else {  
  57.                switchToState(STATE_TRACKING, x, y);  
  58.                moveHandleTo(x, y, false);  
  59.                mHandleDrawable.setAlpha(1.0f);  
  60.            }  
  61.        }  
  62.   
  63.        // Draw handle outside parent's bounds  
  64.        invalidateGlobalRegion(mHandleDrawable);  
  65.   
  66.        if (mActiveTarget != activeTarget && activeTarget != -1) {  
  67.            dispatchGrabbedEvent(activeTarget);  
  68.            if (AccessibilityManager.getInstance(mContext).isEnabled()) {  
  69.                String targetContentDescription = getTargetDescription(activeTarget);  
  70.                announceText(targetContentDescription);  
  71.            }  
  72.        }  
  73.        mActiveTarget = activeTarget;  
  74.    }  

以上主要工作是绘制拖拽的参数以及绘制出来。通过invalidate()来主动刷屏幕;

 

在onDraw()方法中实现绘制图形,代码如下:

  1. @Override  
  2. protected void onDraw(Canvas canvas) {  
  3.     mOuterRing.draw(canvas);  
  4.     for (TargetDrawable target : mTargetDrawables) {  
  5.         if (target != null) {  
  6.             target.draw(canvas);  
  7.         }  
  8.     }  
  9.     for (TargetDrawable target : mChevronDrawables) {  
  10.         if (target != null) {  
  11.             target.draw(canvas);  
  12.         }  
  13.     }  
  14.     mHandleDrawable.draw(canvas);  
  15. }  


在handleMove()方法中——>trySwitchToFirstTouchState(event);——>switchToState()——>doFinish();

——>setGrabbedState() ————>  mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);

设置回调。

 

Step 6: LockScreen.java中有个内部类,监听这个移动事件的状态,——> 代码如下:

  1. class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener,  
  2.            UnlockWidgetCommonMethods {  
  3.   
  4.        private final MultiWaveView mMultiWaveView;  
  5.        private boolean mCameraDisabled;  
  6.   
  7.        MultiWaveViewMethods(MultiWaveView multiWaveView) {  
  8.            mMultiWaveView = multiWaveView;  
  9.            final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager()  
  10.                    .getCameraDisabled(null);  
  11.            if (cameraDisabled) {  
  12.                Log.v(TAG, "Camera disabled by Device Policy");  
  13.                mCameraDisabled = true;  
  14.            } else {  
  15.                // Camera is enabled if resource is initially defined for MultiWaveView  
  16.                // in the lockscreen layout file  
  17.                mCameraDisabled = mMultiWaveView.getTargetResourceId()  
  18.                        != R.array.lockscreen_targets_with_camera;  
  19.            }  
  20.        }  
  21.   
  22.        public void updateResources() {  
  23.            int resId;  
  24.            if (mCameraDisabled) {  
  25.                // Fall back to showing ring/silence if camera is disabled by DPM...  
  26.                resId = mSilentMode ? R.array.lockscreen_targets_when_silent  
  27.                    : R.array.lockscreen_targets_when_soundon;  
  28.            } else {  
  29.                resId = R.array.lockscreen_targets_with_camera;  
  30.            }  
  31.            mMultiWaveView.setTargetResources(resId);  
  32.        }  
  33.   
  34.        public void onGrabbed(View v, int handle) {  
  35.   
  36.        }  
  37.   
  38.        public void onReleased(View v, int handle) {  
  39.   
  40.        }  
  41.   
  42.        public void onTrigger(View v, int target) {  
  43.            if (target == 0 || target == 1) { // 0 = unlock/portrait, 1 = unlock/landscape  
  44.                mCallback.goToUnlockScreen();  
  45.            } else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape  
  46.                if (!mCameraDisabled) {  
  47.                    // Start the Camera  
  48.                    Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);  
  49.                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  50.                    mContext.startActivity(intent);  
  51.                    mCallback.goToUnlockScreen();  
  52.                } else {  
  53.                    toggleRingMode();  
  54.                    mUnlockWidgetMethods.updateResources();  
  55.                    mCallback.pokeWakelock();  
  56.                }  
  57.            }  
  58.        }  
  59.   
  60.        public void onGrabbedStateChange(View v, int handle) {  
  61.            // Don't poke the wake lock when returning to a state where the handle is  
  62.            // not grabbed since that can happen when the system (instead of the user)  
  63.            // cancels the grab.  
  64.            if (handle != MultiWaveView.OnTriggerListener.NO_HANDLE) {  
  65.                mCallback.pokeWakelock();  
  66.            }  
  67.        }  
  68.   
  69.        public View getView() {  
  70.            return mMultiWaveView;  
  71.        }  
  72.   
  73.        public void reset(boolean animate) {  
  74.            mMultiWaveView.reset(animate);  
  75.        }  
  76.   
  77.        public void ping() {  
  78.            mMultiWaveView.ping();  
  79.        }  
  80.    }  


重点看public void onTrigger()这个方法,用于处理拖拽启动那个activity,一个启动camera,一个正常解锁。

 

锁屏的大概这个流程就是这个样子了,大家应该会一目了然了。由于时间仓促,难免有点纰漏,希望大家指正错误,如有不解的地方,欢迎留言探讨!!!