Android自定义ImageView实现自动放大缩小动画
作者:guangyu_sun 发布时间:2021-11-07 12:24:48
标签:Android,ImageView,放大缩小
这篇讲的是如何生成一个自定义的ImageView,实现自动放大缩小动画。
为什么实现这个功能呢?因为我想在ViewPager实现图片放大缩小的动画,但是ViewPager几个页面的动画会一起动,而且放大全屏图片的话会相互覆盖,很诡异。于是上网搜demo,一无所获。迫于无奈。。。
废话不多说,直接贴代码。
1.配置文件直接添加
当直接在布局文件中添加图片的话,可以在自定义View代码中用getDrawable()获取图片资源,然后通过DrawBitmap绘制图片。通过不断绘制图片的位置,达到放大缩小的功能。
第一种情况实在XML布局文件中直接添加的:
public class CoolImageView extends ImageView {
private int mLeft = 0;
private int mTop = 0;
private Handler mHandler;
private Bitmap bitmap;
private Rect srcRect = new Rect();
private Rect dstRect = new Rect();
private int imgWidth;
private int imgHeight;
private boolean flag;
private boolean istart;
public CoolImageView(Context context) {
super(context);
}
public CoolImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setUp(context, attrs);
}
public CoolImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setUp(context, attrs);
}
private void setUp(Context context, AttributeSet attrs) {
mHandler = new MoveHandler();
mHandler.sendEmptyMessageDelayed(1, 220L);
istart = true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
//获取图片资源
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
bitmap = drawable.getBitmap();
dstRect.left = 0;
dstRect.top = 0;
dstRect.right = width;
dstRect.bottom = height;
if (bitmap != null) {
if (istart) {
// 获取图片的宽高
imgWidth = bitmap.getWidth();
imgHeight = bitmap.getHeight();
srcRect.left = 0 + mLeft;
srcRect.right = imgWidth - mLeft;
srcRect.top = 0 + mTop;
srcRect.bottom = imgHeight - mTop;
canvas.drawBitmap(bitmap, srcRect, dstRect, null);
} else {
canvas.drawBitmap(bitmap, null, dstRect, null);
}
}
}
private class MoveHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
if (imgHeight != 0) {
if (mTop == 0) {
mTop += 5;
mLeft += 5;
} else if (mTop == 120) {
mTop -= 5;
mLeft -= 5;
}
}
postInvalidate();
mHandler.sendEmptyMessageDelayed(1, 250);
break;
}
}
}
public void start() {
mTop = 0;
mLeft = 0;
istart = true;
mHandler.sendEmptyMessageDelayed(1, 220L);
}
public void stop() {
istart = false;
}
}
2 .通过Glide加载图片的方式
通过Glide加载图片的话,不能直接用getDrawable获取图片资源。Glide加载图片的方式也需要改变。废话不多说,直接上代码。
CoolimageView直接从Glide的缓存中加载图片。
Glide.with(GoodsPagerActivity.this)
.load(sList.get(position).img)
.override(width, height)
.centerCrop()
.into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
imageView.setImageDrawable(resource);
}
});
CoolImageView.java:
唯一不同的是获取图片的方式;
```java
public class CoolImageView extends ImageView {
private int mLeft = 0;
private int mTop = 0;
private Handler mHandler;
private Bitmap bitmap;
private Rect srcRect = new Rect();
private Rect dstRect = new Rect();
private int imgWidth;
private int imgHeight;
private boolean flag;
private boolean istart;
private int width;
private int height;
public CoolImageView(Context context) {
super(context);
}
public CoolImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setUp(context, attrs);
}
public CoolImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setUp(context, attrs);
}
private void setUp(Context context, AttributeSet attrs) {
mHandler = new MoveHandler();
mHandler.sendEmptyMessageDelayed(1, 220L);
istart = true;
}
@Override
public void setImageDrawable(@Nullable Drawable drawable) {
super.setImageDrawable(drawable);
if (mHandler != null) {
mHandler.sendEmptyMessageDelayed(1, 220L);
} else {
mHandler = new MoveHandler();
mHandler.sendEmptyMessageDelayed(1, 220L);
istart = true;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
width = getWidth();
height = getHeight();
GlideBitmapDrawable drawable = (GlideBitmapDrawable) getDrawable();
if (drawable != null) {
bitmap = drawable.getBitmap();
}
dstRect.left = 0;
dstRect.top = 0;
dstRect.right = width;
dstRect.bottom = height;
if (bitmap != null) {
if (istart) {
imgWidth = bitmap.getWidth();
imgHeight = bitmap.getHeight();
srcRect.left = 0 + mLeft;
srcRect.right = imgWidth - mLeft;
srcRect.top = 0 + mTop;
srcRect.bottom = imgHeight - mTop;
canvas.drawBitmap(bitmap, srcRect, dstRect, null);
} else {
canvas.drawBitmap(bitmap, null, dstRect, null);
}
}
}
private class MoveHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
if (imgHeight != 0) {
if (mTop == 0) {
flag = true;
} else if (mTop == 60) {
flag = false;
}
if (!flag) {
mTop -= 2;
mLeft -= 1;
} else {
mTop += 2;
mLeft += 1;
}
}
postInvalidate();
mHandler.sendEmptyMessageDelayed(1, 200);
break;
}
}
}
public void start() {
mTop = 0;
mLeft = 0;
istart = true;
mHandler.sendEmptyMessageDelayed(1, 220L);
}
public void stop() {
istart = false;
}
}
如果感觉动画不够流畅可以缩小线程等待时间。


猜你喜欢
- Builder模式使用链式结构创建复杂对象,将过程与结果分开,创建过程中可以自行组合。使用场景一个对象,不同组合,不同顺序生成不同的结果优点
- 区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大家都非常想了解这一切是如何工作的。这篇文章就是帮助你使用 Java
- 首先,说说final。final关键字可以修饰变量,方法,类。final变量:需求:1 需要一个永不改变的编译时常量2 一个运行时被初始化的
- 在上一讲中 OkHttp下载文件并带进度条 中,我们知道怎样去下载文件了。那上传文件呢一、编写服务器端在上一讲服务器下新建UploadFil
- 前提准备:1. 项目中至少需要引入的jar包,注意版本: a) core-renderer.jar&nb
- 一:简述如果我们想要生成一个随机数,通常会使用Random类。但是在并 * 况下Random生成随机数的性能并不是很理想,今天给大家介绍一下J
- 这里之所以说“浅谈”是因为我这里只是简单的介绍如何使用Visual C#进行图像的读入、保存以及对像素的访问。而不涉及太多的算法。一、读取图
- C#正则验证大全 Regex.IsMatch()正则表达式验证需要引入命名空间 using System.Text.RegularExpre
- 一般来说, 泛型的作用就类似一个占位符, 或者说是一个参数, 可以让我们把类型像参数一样进行传递, 尽可能地复用代码。我有个朋友, 在使用的
- 使用Palette API选择颜色 良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是
- 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。类型:创建类模式类图:工厂方法模式代码in
- 迅雷下载是目前使用非常普遍的一个下载软件,本文实例展示了C#实现调用迅雷下载的方法。具体方法如下:目前该实例代码只支持HTTP协议,具体功能
- Android短信高效备份这篇文章,承接上一篇。使用高效的方式备份短信——xml序列化器。存储短信,要以对象的方式存储。首先创建javabe
- import java.util.Arrays;public class HeapSort { publ
- mybatis-plus 3.0.1 枚举返回为null解决办法2020-11-02 14:28:48今天再次回到代码里无意间看到,原来和m
- 背景环境需要设置代理才能够访问外部网络,如果只是运行java程序来访问网络,我们可以通过java -jar test.jar -Dproxy
- 1.定义指向非法的内存地址指针叫作野指针(Wild Pointer),也叫悬挂指针(Dangling Pointer),意为无法正常使用的指
- 一、日志1、配置日志级别日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、D
- 简单工厂模式工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创
- 创建文件或文件夹您可通过编程方式在您的计算机上创建文件夹、子文件夹和子文件夹中的文件,并将数据写入文件。public class Creat