android 图片闪电效果图,Android超简单实现炫酷的图片展示效果

目录

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

目录

效果展示

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

实现原理

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

这里的实现原理很简单,就是添加多个矩形路径,并不断的延长各个矩形路径的宽度(通过onDraw方法的递归实现),然后在矩形路径中绘制Bitmap即可。

实现步骤

1. 构建用于展示的Bitmap

这里我们选择在onSizeChanged方法中初始化Bitmap,因为当控件大小改变时方便我们重新计算所需展示Bitmap的大小。

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false);//根据控件大小创建一个与控件宽高相同的Bitmap对象

postInvalidate();//创建完Bitmap后对控件进行刷新

super.onSizeChanged(w, h, oldw, oldh);

}

2. 构建矩形裁剪区域并添加到Path中

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

由上图可以看出我们需要添加的矩形路径分为左半边部分和右半边部分,我们以左半部分第一个矩形和右半部分第一个矩形为例:

左边矩形的构建参数:left = 0,top = 0,right = clipwidth,bottom = SINGLERECT_HEIGHT。

右边矩形的构建参数:left = View_Width - clipwidth,top = SINGLERECT_HEIGHT,right = View_Width,bottom = 2 * SINGLERECT_HEIGHT。

根据如上构建参数的规律我们总结出如下公式(其中i代表由上到下第几个矩形):

左边矩形构建公式:RectF rectleft = new RectF(0,i * SINGLEREGION_HEIGHT,cilpWidth,(i + 1) * SINGLEREGION_HEIGHT)

右边矩形构建公式:RectF rectright = new RectF(View_Width - cilpWidth,i * SINGLEREGION_HEIGHT,getWidth(),(i + 1) * SINGLEREGION_HEIGHT)

根据如上公式我们在代码中添加路径:

//根据控件的高度来添加矩形路径

for(int i=0;i*SINGLEREGION_HEIGHT

if(i%2==0){

mPath.addRect(new RectF(0,i*SINGLEREGION_HEIGHT,cilpWidth,(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);

}else {

mPath.addRect(new RectF(getWidth()-cilpWidth,i*SINGLEREGION_HEIGHT,getWidth(),(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);

}

}

3. 在对应的路径中绘制出Bitmap

这里使用Canvas的clipPath方法将画布裁切成路径的形状,然后在裁切后的画布上绘制图片。

canvas.clipPath(mPath);//根据路径裁切画布

canvas.drawBitmap(mBitmap,0,0,mPaint);//在裁切后的画布上绘制图片

4. 利用递归实现动画效果

if(cilpWidth>getWidth()){

//当矩形的宽度等于控件宽度时停止重绘

return;

}

cilpWidth+=5;//每次绘制完需要增加clipWidth的宽度

invalidate();//重绘(运用递归)

5. 当图片完全显示时替换图片

图片完全显示也是cilpWidth>控件宽度的时候。

if(cilpWidth>getWidth()){

//当图片完全展示时替换图片

mBitmap=Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false);

canvas.drawBitmap(mBitmap,0,0,mPaint);

return;

}

完整代码展示

public class View_ClipAnim extends View {

private Paint mPaint;

private Path mPath;

private final float SINGLEREGION_HEIGHT=30;//每个长条的高度

private Bitmap mBitmap;

float cilpWidth=0;//矩形宽度

public View_ClipAnim(Context context) {

this(context,null);

}

public View_ClipAnim(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public View_ClipAnim(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

/**

* 初始化画笔等

*/

private void init() {

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPath = new Path();

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false);

cilpWidth=0;

postInvalidate();

super.onSizeChanged(w, h, oldw, oldh);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

mPath.reset();//每次绘制之前先将Path重置

for(int i=0;i*SINGLEREGION_HEIGHT

if(i%2==0){

mPath.addRect(new RectF(0,i*SINGLEREGION_HEIGHT,cilpWidth,(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);

}else {

mPath.addRect(new RectF(getWidth()-cilpWidth,i*SINGLEREGION_HEIGHT,getWidth(),(i+1)*SINGLEREGION_HEIGHT), Path.Direction.CCW);

}

}

canvas.clipPath(mPath);//根据路径裁切画布

canvas.drawBitmap(mBitmap,0,0,mPaint);//在裁切后的画布上绘制图片

if(cilpWidth>getWidth()){

//当图片完全展示时替换图片

mBitmap=Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false);

canvas.drawBitmap(mBitmap,0,0,mPaint);

return;

}

cilpWidth+=5;//每次绘制完需要增加clipWidth的宽度

invalidate();//重绘(运用递归)

}

}

扩展

扫描式图片展示

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

效果图

1a86d70c322d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

这里主要是使用弧形路径来展示图片的,通过不断增加弧形角度来扩大显示区域(这里的弧形半径是通过勾股定理得出的)。

public class View_ClipCircleAnim extends View {

private Paint mPaint;

private float mRadius;//圆形的半径

private Path mPath;

private Bitmap mBitmap;

private int mAngle=0;//圆形角度

public View_ClipCircleAnim(Context context) {

this(context,null);

}

public View_ClipCircleAnim(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public View_ClipCircleAnim(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init() {

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPath = new Path();

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

float a = w/2;

float b = h/2;

mRadius = (float) Math.sqrt(a*a+b*b);//根据勾股定理算出圆形的半径

mBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.timg), w, h, false);

super.onSizeChanged(w, h, oldw, oldh);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(getWidth()/2,getHeight()/2);//将(0,0)点移动到画布中心

if(mAngle>=360){

canvas.drawBitmap(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.baozou), getWidth(), getHeight(), false),-getWidth()/2,-getHeight()/2,mPaint);

return;

}

mPath.reset();//清空路径

mPath.moveTo(0,0);

mPath.arcTo(new RectF(-mRadius,-mRadius,mRadius,mRadius),0,mAngle,false);//添加闭合的弧形

canvas.clipPath(mPath);//裁剪画布为路径的形状

canvas.drawBitmap(mBitmap,-getWidth()/2,-getHeight()/2,mPaint);

mAngle++;

postInvalidate();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值