前段时间产品那边让我做一个动画,要求是先以横线的方式横向展开,在纵向展示图片,最后展示几秒动画在原路返回,随后我在网上查找资料,发现这方面的记录很少,最后自己写了一个

后期还会慢慢改进;

转载请说明出处: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;
}
}

Android实现先横向横线展现在纵向拉开图片的更多相关文章

  1. Android TextView使用HTML处理字体样式、显示图片等

    一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及超级链接等属性呢?下面我们通过SpannableString的具体实例操 ...

  2. 转载:Android调用相册、拍照实现缩放、切割图片

    好几天没有写博客了,感觉都有点懈怠了.笔者参加了大学生第二届软件设计大赛,这几天 一直在弄大赛的事情,没有花些时间来整理博客.好在经过一些时日比赛的东西也弄得差不多了, 接下来就是将这段时间学习里面有 ...

  3. Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...

  4. [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现

    [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现 今天做Android项目的时候要用到图片选择,要实现拍照获取图片和从相册获取图片,并且要求在获取完之后可以裁剪,试了很多方法之 ...

  5. Android基础新手教程——1.6 .9(九妹)图片怎么玩

    Android基础新手教程--1.6 .9(九妹)图片怎么玩 标签(空格分隔): Android基础新手教程 1.本节引言: 可能有的一些疑问: 1.什么是.9图片? 答:图片后缀名前有.9的图片,如 ...

  6. [Android] 给图像加入相框、圆形圆角显示图片、图像合成知识

        前一篇文章讲述了Android触屏setOnTouchListener实现突破缩放.移动.绘制和加入水印,继续我的"随手拍"项目完毕给图片加入相框.圆形圆角显示图片和图像合 ...

  7. Android零基础入门第49节:AdapterViewFlipper图片轮播

    原文:Android零基础入门第49节:AdapterViewFlipper图片轮播 上一期学习了ExpandableListView的使用,你已经掌握了吗?本期开始学习AdapterViewFilp ...

  8. Android 自己定义ScrollView ListView 体验各种纵向滑动的需求

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38950509.本文出自[张鸿洋的博客] 1.概述 群里的一个哥们有个需求是这种: ...

  9. Android开发学习——画横线竖线

    画横线/竖线 竖线 <View android:layout_width="1dp" android:layout_height="match_parent&quo ...

随机推荐

  1. DNS相关配置文件

    我们晓得主机名对应到 IP 有两种方法,早期的方法是直接写在档案里面来对应, 后来比较新的方法则是透过 DNS 架构!那么这两种方法分别使用什么配置文件?可不可以同时存在? 若同时存在时,那个方法优先 ...

  2. (简单) POJ 1195 Mobile phones,二维树状数组。

    Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...

  3. 手机端 H5上传头像

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. 《javascript语言精粹》——第6章数组

    [1].数组字面量 var empty=[]; var num=[ 'zero','one','two','three','four','five','six','seven','eight','ni ...

  5. ucos信号量集源码分析

    在实际的应用之中,一个任务经常需要等待多个信号量的同时生效,或者说任务需要根据多个信号量的组合作用的结果来决定任务的运行方式,为了实现这种多信号量组合的功能,ucos实现了信号量集的特殊结构. 信号量 ...

  6. iOS动画特效

    关于图层的几个坐标系. 对于ios来说,坐标系的(0,0)点在左上角,就是越往下,Y值越大.越往右,X值越大. 一个图层的frame,它是position,bounds,anchorPoint和tra ...

  7. BZOJ 1653 [Usaco2006 Feb]Backward Digit Sums ——搜索

    [题目分析] 劳逸结合好了. 杨辉三角+暴搜. [代码] #include <cstdio> #include <cstring> #include <cmath> ...

  8. 算法系列001---dfs|多叉|解空间树理解

    1.研究范围 1)多叉树,图的遍历 2)回溯法的解空间树=多叉树的遍历 2.研究方法 我们现在研究的是多叉树的遍历,突然想到为什么不能直接用二叉树的遍历方法呢?我们抱着这个问题,先找到多叉树的结构不同 ...

  9. 刷新UITableView

    [from]http://www.superqq.com/blog/2015/08/18/ios-development-refresh-uitableview/ UITableView对于iOS开发 ...

  10. <!DOCTYPE> 声明 引发的错误

    <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. 在写模板的时候,因为最近开始给每个文件添加注释,无意中将注释写在文件的第一行.导致页面 ...