天天看點

Android 高仿 IOS7 IPhone 解鎖 Slide To Unlock 附源碼

1. IPhone 解鎖 效果圖:

Android 高仿 IOS7 IPhone 解鎖 Slide To Unlock 附源碼

在最新的IOS7中,蘋果更改了解鎖方式,整個螢幕向右滑動都可以解鎖,不再局限在一個小的矩形中。這種文字加亮移動的效果還是繼承了下來。之前滑動最左邊的滑塊,中間文字會有漸變效果,這次文字會跟随着左邊的小圖示随着使用者向左滑動。

滑動觸發事件在蘋果大緻用在了3個地方,1.滑動解鎖,2.滑動關機,3.手機處于鎖住狀态來電,滑動接聽。我們來看下Android下的高仿實作。

2.需要實作的東西

1. 文字加亮移動效果(這個可能是最吸引眼球的地方)

2. 滑動一段距離,不夠觸發事件距離的時候就會彈回原來的地方

3. 超過解鎖距離,觸發事件(解鎖 || 關機 || 接聽電話)

4.使用者已較大加速度滑動,雖然沒有超過解鎖距離,但是也會解鎖,并且會有向右滑動慣性

5.使用者按下去,文字變白,動畫停止(滑動關機裡的效果)

3.文字加亮移動效果

3.1實作方法1:兩次邏輯,底下文字,上面圖檔快速滑動

第一感覺的做法是:底下是文字,文字上面有一張圖檔快速滑動。而且感覺這個動畫很熟悉,好像在哪裡看過?沒錯,在原生的Android系統中,開機動畫就是這樣的效果!

Android 高仿 IOS7 IPhone 解鎖 Slide To Unlock 附源碼

在Android 源碼的 \frameworks\base\core\res\assets\images 目錄下發現了兩張圖檔,驗證了我的想法:

Android 高仿 IOS7 IPhone 解鎖 Slide To Unlock 附源碼

但是這次我沒有用這樣的方法,:( 。有興趣的朋友可以試着做下,感覺不難。

3.2 實作方法2: 使用Android shader中的LinearGradient

LinearGradient是個什麼東西呢?可以給定幾個顔色,實作下面的效果。如果我們隻有兩種顔色,灰色和白色,邊上兩端都是灰色,中間白色,然後使用Android中的ValueAnimator改變位置也可以實作我們要的效果。這樣有兩個好處:1.邏輯比較單一,隻有文字。2.顔色比圖檔容易更改。

Android 高仿 IOS7 IPhone 解鎖 Slide To Unlock 附源碼

3.2.1 LinearGradient的使用

大家可以參考官方API: http://developer.android.com/reference/android/graphics/LinearGradient.html

publicLinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)

Create a shader that draws a linear gradient along a line.

Parameters

x0 The x-coordinate for the start of the gradient line
y0 The y-coordinate for the start of the gradient line
x1 The x-coordinate for the end of the gradient line
y1 The y-coordinate for the end of the gradient line
colors The colors to be distributed along the gradient line
positions May be null. The relative positions [0..1] of each corresponding color in the colors array. If this is null, the the colors are distributed evenly along the gradient line.
tile The Shader tiling mode

跟畫線段一樣,一個起點,一個終點,中間是顔色。主要講下最後一個tile的東西,像3.2中的圖檔那樣的效果需要定義為Shader.TileMode.REPEAT,重複的意思。我們這裡的需求是不一樣的,我們兩端需要補充,是以使用Shader.TileMode.CLAMP。

demo:

LinearGradient linearGradient = new LinearGradient(0, 0, 100, 100, new int[] {
        Color.RED, Color.GREEN, Color.BLUE, Color.WHITE }, null,
        Shader.TileMode.REPEAT);
Paint paint = new Paint();
paint.setShader(linearGradient);      

3.2.2 Android 中的動畫 ValueAnimator

顧名思義可以在一定時間内更改Value。下面是一個小小Demo(在1秒内,值從0到1不斷變化):

ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.i("update", ((Float) animation.getAnimatedValue()).toString());
    }
});
animation.setRepeatCount(Animation.INFINITE);//repeat animation
animation.start();      

注意我們還加上了重複次數,定義為無限,這樣就是我們想要的效果。

4.彈回去的動畫,Android ObjectAnimator

可以參考這篇文章​​《Android 高仿三星月曆》​​

這裡使用了ObjectAnimator中的下面的方法

public static ObjectAnimatorofFloat(Object target, String propertyName, float... values)

target 要進行動畫的控件
propertyName 要更改的屬性名稱,一般控件裡SetXX後面的值,比如一個控件可以SetRotation,那麼Rotation就是一個屬性名稱
values 屬性更改的兩個值,從開始到結束

Demo:

// left move animation
        ObjectAnimator animLeftMove = ObjectAnimator.ofFloat(mLinearLayout,  
                "x", mLinearLayout.getX(), -54).setDuration(  
                1000);  
        animLeftMove.start();      

5.得到使用者滑動的速率 VelocityTracker

具體可以參考Android API: http://developer.android.com/reference/android/view/VelocityTracker.html

主要 要知道Android中有這麼個東西,用途很廣的,比如PageView兩頁之間快速滑動,ListView快速等。它可以得到x軸和y軸上的加速度,我們這裡隻需要用到x軸上的。

demo:

@Override
  public boolean onTouchEvent(MotionEvent event) {
    
        
        if (mVelocityTracker == null) {
      mVelocityTracker = VelocityTracker.obtain();
    }

    mVelocityTracker.addMovement(event);
        
       velocityTracker.computeCurrentVelocity(1000);//should compute first

    int velocityX = (int) velocityTracker.getXVelocity();//get volocity in x

    
    if(velocityX > mMinVelocityXToUnlock){
      //unlock Success;
      return true;
    }
        return true;
  }      

6.Android中的自定義控件

核心用的技術講完了,扯下Android中的自定義控件。我們寫的這個如果要複用的話,最好的方式就是封裝成一個控件。把文字,解鎖難度等成為控件屬性,這樣就友善了。

6.1 第一步 attrs.xml中定義需要用的屬性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- =============================== -->
    <!-- GradientView class attributes -->
    <!-- =============================== -->
    <declare-styleable name="GradientView">
        <attr name="StringToShow" format="reference"/>
        <attr name="TextSize" format="dimension"/>
        <attr name="TextColor" format="integer"/>
        <attr name="SlideColor" format="integer"/>
    </declare-styleable>
</resources>      

比如這裡我們定義了4個屬性。分别是要顯示的文字,文字大小,文字顔色,滑動顔色。

6.2 第二步,建立一個類繼承你想要擴充的類

public class GradientView extends View {
  private int  mTextSize;
  int      mDefaultColor;
  int             mSlideColor;
  private int mWidth,mHeight;
  private String mStringToShow;
  private Paint mTextPaint;
  private float mTextHeight;
  
  public GradientView(Context context) {
    super(context);
  }
  
  public GradientView(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GradientView);
    mStringToShow = a.getString(R.styleable.GradientView_StringToShow) ;
    mTextSize = (int)a.getDimension(R.styleable.GradientView_TextSize, 40);
    mDefaultColor = a.getColor(R.styleable.GradientView_TextColor, Color.GRAY);
    mSlideColor = a.getColor(R.styleable.GradientView_SlideColor, Color.WHITE);
    a.recycle();
        
    mTextPaint = new Paint();
    mTextPaint.setAntiAlias(true);
    mTextPaint.setColor(mSlideColor);
    mTextPaint.setTextSize(mTextSize); 
    mTextPaint.setTextAlign(Paint.Align.CENTER);
    
    mTextHeight = mTextPaint.ascent();
    
  }

  @Override
  protected void onDraw(Canvas canvas) {
    //draw something
  } 

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mWidth = MeasureSpec.getSize(widthMeasureSpec);
    mHeight = MeasureSpec.getSize(heightMeasureSpec);
  }
  
  
}      

6.3 布局檔案中使用我們自定義的控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:prvandroid="http://schemas.android.com/apk/res/com.waitingfy.iosunlock"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    tools:context=".MainActivity" >

    <com.waitingfy.iosunlock.GradientView
         android:id="@+id/gradientView"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_centerVertical="true"
         android:layout_marginLeft="@dimen/gradient_view_margin_left"
         prvandroid:StringToShow="@string/slide_to_unlock_string"
         prvandroid:TextSize="@dimen/gradient_text_size"
         prvandroid:TextColor="@color/gradient_text_color"
         prvandroid:SlideColor="@color/gradient_slide_text_color"
         />    
</RelativeLayout>      

注意這個命名空間 xmlns:prvandroid="http://schemas.android.com/apk/res/com.waitingfy.iosunlock"

6. 源碼下載下傳

7.附Android 原生開機動畫