Android实现先横向横线展现在纵向拉开图片
前段时间产品那边让我做一个动画,要求是先以横线的方式横向展开,在纵向展示图片,最后展示几秒动画在原路返回,随后我在网上查找资料,发现这方面的记录很少,最后自己写了一个
后期还会慢慢改进;
转载请说明出处:http://www.cnblogs.com/hyylog/p/5659619.html
步骤:1、先利用控件的ondraw()方法,结合数字上升的动画,实现划线的步骤;
2、利用postInvalidate()方法,调用dispatchDraw()方法来展示图片的展现
具体代码如下:
public class ExpandView extends LinearLayout {
 private Bitmap mBitmap;
	private int linearDuration = 500;
	private int expandDuration = 800;
	private int dismissDuration = 1500;
	private Paint mpPaint;
	private Paint bitPaint;
	private int resultLinear = 40; // 划线动画执行距离完成启动下一个动画的距离 (为防止动画启动延迟产生的卡顿)
	private int resultBitMap = 30; // 画图动画距离启动下次动画的距离 (为防止动画启动延迟产生的卡顿)
	private int type = 1; // 1 为展开动画 2 为回缩动画
	private ValueAnimator valueAnimator = null;
	private ValueAnimator valueAnimator2 = null;
	private int radus = 8;
	private int velua = 0;
	private int veluaLinear = 0;
	private View view;
	private boolean isStart = false; // 保证动画只启动一次
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0:
				velua = 0;
				invalidate();
				break;
			case 1:
				start(2);
				break;
			default:
				break;
			}
		};
	};
	public ExpandView(Context context, AttributeSet attrs) {
		super(context, attrs);
		inite();
	}
	public void setView(View view) {
		this.view = view;
	}
	public ExpandView(Context context) {
		super(context);
		inite();
	}
	public void inite() {
		bitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mpPaint.setStrokeWidth(5);
		mpPaint.setColor(Color.BLACK);
	}
	public void setRadus(int radus) {
		this.radus = radus;
	}
	public void setDistance(int linear, int bit) {
		resultBitMap = bit;
		resultLinear = linear;
	}
	public void setDuration(int linearDuration, int expandDuration,
			int dismissDuration) {
		this.linearDuration = linearDuration;
		this.expandDuration = expandDuration;
		this.dismissDuration = dismissDuration;
	}
	public void setLinearPaintColor(int color) {
		mpPaint.setColor(color);
	}
	public void start(int type) {
		this.type = type;
		valueAnimator.cancel();
		valueAnimator2.cancel();
		handler.removeMessages(1);
		handler.sendEmptyMessage(0);
		isStart = true;
		if (type == 1) {
			valueAnimator.start();
		} else if (type == 2) {
			valueAnimator2.start();
		}
	}
	public void initedAnimation() {
		clearAnimations();
		mBitmap = getBitmap();
		Log.i("", "pppp====veluaLinear=>>"+(mBitmap.getWidth() - radus * 2));
		valueAnimator = ValueAnimator.ofInt(0, mBitmap.getWidth() - radus * 2);
		valueAnimator2 = ValueAnimator.ofInt(0, mBitmap.getHeight());
		valueAnimator.setDuration(linearDuration);
		valueAnimator2.setDuration(expandDuration);
		valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				veluaLinear = (Integer) animation.getAnimatedValue();
				if (veluaLinear > (mBitmap.getWidth() - resultLinear)&& type == 1) {
					if (isStart) {
						valueAnimator2.start();
						isStart = false;
					}
				}
				postInvalidate();
			}
		});
valueAnimator2.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				velua = (Integer) animation.getAnimatedValue();
				postInvalidate();
				veluaLinear = 0;
			}
		});
	}
	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		if (mBitmap != null) {
			Rect src;
			Rect des;
			if (type == 1) {
				canvas.drawLine(mBitmap.getWidth() - radus, 0,mBitmap.getWidth() - radus - veluaLinear, 0,mpPaint);
				src = new Rect(0, 0, mBitmap.getWidth(), velua);
				des = new Rect(0, 0, mBitmap.getWidth(), velua);
			} else {
				canvas.drawLine(mBitmap.getWidth() - radus, 0, radus+ veluaLinear, 0, mpPaint);
				src = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()- velua);
				des = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()- velua);
			}
			canvas.drawBitmap(mBitmap, src, des, bitPaint);
			if (velua == mBitmap.getHeight() && type == 1) {
				handler.removeMessages(1);
				handler.sendEmptyMessageDelayed(1, dismissDuration);
			}
			if (type == 2 && velua >= mBitmap.getHeight() - resultBitMap) {
				if (isStart) {
					valueAnimator.start();
					isStart = false;
				}
			}
		}
	}
	public void clearAnimations() {
		if (valueAnimator != null)
			valueAnimator.cancel();
		if (valueAnimator2 != null)
			valueAnimator.cancel();
		handler.removeMessages(1);
		veluaLinear=0;
		handler.sendEmptyMessage(0);
		if (mBitmap != null && !mBitmap.isRecycled()) {
			mBitmap.recycle();
		}
}
	private Bitmap getBitmap() {
		// 打开图像缓存
		view.setDrawingCacheEnabled(true);
		// 必须调用measure和layout方法才能成功保存可视组件的截图到png图像文件
		// 测量View大小
		view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		// 发送位置和尺寸到View及其所有的子View
		view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
		Bitmap bitmap = view.getDrawingCache();
		android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) getLayoutParams();
		params.width=bitmap.getWidth();
		params.height=bitmap.getHeight();
		setLayoutParams(params);
		return bitmap;
	}
}
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号