Android 仿HTC拉环解锁波浪效果

受Android4.0 滑动解锁波纹效果启发,模拟出HTC拉环解锁波浪。

上代码:

package com.android.internal.widget.htcmultiwaveview;

import java.util.ArrayList;

import com.android.internal.widget.multiwaveview.TargetDrawable;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.android.internal.R;

public class ChervonView extends View {

	private static final int CHEVRON_INCREMENTAL_DELAY = 160;
	private static final long CHEVRON_ANIMATION_DURATION = 650;
	private static final String TAG = "ChervonView";
	private int mFeedbackCount;
	private ArrayList<TargetDrawable> mChevronDrawables = new ArrayList<TargetDrawable>();
	private Drawable mTopChervonDrawable;
	private ArrayList<Tweener> mChevronAnimations = new ArrayList<Tweener>();
	private AnimatorUpdateListener mUpdateListener = new AnimatorUpdateListener() {
		
		@Override
		public void onAnimationUpdate(ValueAnimator arg0) {
			// TODO Auto-generated method stub
			invalidate();
		}
	};

	public ChervonView(Context context){
		this(context,null);
	}
	
	public ChervonView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		
		Resources res = context.getResources();

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChervonView);
		mFeedbackCount = a.getInt(R.styleable.ChervonView_feedbackNumber, 4);
		mTopChervonDrawable = a.getDrawable(R.styleable.ChervonView_topDrawable);
		// Read chevron animation drawables
        final int chevrons[] = { R.styleable.ChervonView_leftDrawable,
                R.styleable.ChervonView_rightDrawable,
                R.styleable.ChervonView_topDrawable,
                R.styleable.ChervonView_bottomDrawable
        };
        for (int chevron : chevrons) {
            Drawable chevronDrawable = a.getDrawable(chevron);
            for (int i = 0; i < mFeedbackCount; i++) {
                mChevronDrawables.add(
                    chevronDrawable != null ? new TargetDrawable(res, chevronDrawable) : null);
            }
        }
		
	}

	public void hideChevrons() {
        for (TargetDrawable chevron : mChevronDrawables) {
            if (chevron != null) {
                chevron.setAlpha(0.0f);
            }
        }
    }
	
	/**
     * Animation used to attract user's attention to the target button.
     * Assumes mChevronDrawables is an a list with an even number of chevrons filled with
     * mFeedbackCount items in the order: left, right, top, bottom.
     */
    public void startChevronAnimation() {
    	final float mWaveCenterX = getWidth()/2;
    	final float mWaveCenterY = getHeight()-12;
        final float r = mTopChervonDrawable.getIntrinsicWidth() * 0.4f;
        final float chevronAnimationDistance = getHeight() * 0.1f;
        final float from[][] = {
                {mWaveCenterX - r, mWaveCenterY},  // left
                {mWaveCenterX + r, mWaveCenterY},  // right
                {mWaveCenterX, mWaveCenterY},  // top
                {mWaveCenterX, mWaveCenterY + r} }; // bottom
        final float to[][] = {
                {mWaveCenterX - chevronAnimationDistance, mWaveCenterY},  // left
                {mWaveCenterX + chevronAnimationDistance, mWaveCenterY},  // right
                {mWaveCenterX, mWaveCenterY - chevronAnimationDistance},  // top
                {mWaveCenterX, mWaveCenterY + chevronAnimationDistance} }; // bottom

        mChevronAnimations.clear();
        final float startScale = 1.0f;
        final float endScale = 1.4f;
        for (int direction = 0; direction < 4; direction++) {
            for (int count = 0; count < mFeedbackCount; count++) {
                int delay = count * CHEVRON_INCREMENTAL_DELAY;
                final TargetDrawable icon = mChevronDrawables.get(direction*mFeedbackCount + count);
                if (icon == null) {
                    continue;
                }
                mChevronAnimations.add(Tweener.to(icon, CHEVRON_ANIMATION_DURATION,
                        "ease", Ease.Quad.easeOut,
                        "delay", delay,
                        "x", new float[] { from[direction][0], to[direction][0] },
                        "y", new float[] { from[direction][1], to[direction][1] },
                        "alpha", new float[] {1.0f, 0.0f},
                        "scaleX", new float[] {startScale, endScale},
                        "scaleY", new float[] {startScale, endScale},
                        "onUpdate", mUpdateListener ));
            }
        }
    }

    public void stopChevronAnimation() {
        for (Tweener anim : mChevronAnimations) {
            anim.animator.end();
        }
        mChevronAnimations.clear();
    }
	
	private int resolveMeasured(int measureSpec, int desired) {
        int result = 0;
        int specSize = MeasureSpec.getSize(measureSpec);
        switch (MeasureSpec.getMode(measureSpec)) {
            case MeasureSpec.UNSPECIFIED:
                result = desired;
                break;
            case MeasureSpec.AT_MOST:
                result = Math.min(specSize, desired);
                break;
            case MeasureSpec.EXACTLY:
            default:
                result = specSize;
        }
        return result;
    }
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
//		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int minimumWidth = getSuggestedMinimumWidth();
        final int minimumHeight = getSuggestedMinimumHeight();
Log.d(TAG,"____minimumWidth="+minimumWidth+", mininumHeight"+minimumHeight);        
        int viewWidth = resolveMeasured(widthMeasureSpec, minimumWidth);
        int viewHeight = resolveMeasured(heightMeasureSpec, minimumHeight);
        
        setMeasuredDimension(viewWidth, viewHeight);
        
	}

	@Override
	protected int getSuggestedMinimumHeight() {
		// TODO Auto-generated method stub
		return (int) (mTopChervonDrawable.getIntrinsicHeight()*(1+0.2));
	}

	@Override
	protected int getSuggestedMinimumWidth() {
		// TODO Auto-generated method stub
		return (int) (mTopChervonDrawable.getIntrinsicWidth()*(1+0.2));
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
//		super.onDraw(canvas);
		for (TargetDrawable target : mChevronDrawables) {
            if (target != null) {
                target.draw(canvas);
            }
        }
	}
	

}


layout文件里的ChervonView的使用:

<com.android.internal.widget.htcmultiwaveview.ChervonView
			android:id="@+id/htcChevron"	        
			android:layout_width="250dip"
			android:layout_height="150dip"
			android:clickable="false"
			android:topDrawable="@drawable/htc_ic_lockscreen_chevron_up"
			android:feedbackCount="4"
			android:focusable="false"
			android:layout_gravity="bottom|center_horizontal"
			/>



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值