知乎等应用的开场动画是:全屏显示一副图像,并以图像的中间为原点,实现放大(也就是zoomin)的动画,让等待的过程不再单调乏味。
最近不是很忙,因此想了下如何实现这种效果,方案是:采用调整imageview的matrix的方式来实现此效果。
这个例子中我只是简单的将原理实现,没有对效果进行任何的优化。如果想达到比较完美的效果,需要添加动画,如使用valueAnimator,在updatelistener中不断的更新matrix或者float[]即可。
为了演示方便,我将其实现过程拆分为两部:
1.调整图片,使图片位于屏幕的正中间。由于android手机屏幕尺寸多种多样,而图片的大小也不甚相同,为了灵活的使用此效果,需要将任意尺寸比例的图片显示在任意尺寸比例的手机屏幕的正中间,同时不使图片扭曲变形
2.采用点击button模拟zoomin的效果,当然可以优化成使用valueanimator的方式,由于这不是本篇文章的重点,因此不进行优化了
 
 实现的效果:[屏幕截图有点问题,所以显得有点卡]
原理在代码中进行说明:
主界面:
package com.carbs.testandroidimage;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView; public class MainActivity extends Activity implements View.OnClickListener { private ImageView iv;
private Button bt1_refine;
private Button bt2_zoomin; private int iv_height = 0;
private int iv_width = 0;
private int dr_height = 0;
private int dr_width = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main); iv = (ImageView) this.findViewById(R.id.iv);
bt1_refine = (Button) this.findViewById(R.id.bt1);
bt2_zoomin = (Button) this.findViewById(R.id.bt2); bt1_refine.setOnClickListener(this);
bt2_zoomin.setOnClickListener(this); iv.post( new Runnable() { @Override
public void run() {
//获取imageview的宽和高、获取drawable的宽和高
Drawable d = iv.getDrawable();
//drawable的宽高,存储到全局变量中
dr_width = d.getIntrinsicWidth();
dr_height = d.getIntrinsicHeight();
//imageview的宽高,存储到全局变量中
iv_height = iv .getMeasuredHeight();
iv_width = iv.getMeasuredWidth();
Log. d("a", "onClick() --> dr_width is " + dr_width + " | dr_height is " + dr_height + " | iv_height is " + iv_height + " | iv_width is " + iv_width);
}
});
} @Override
public void onClick(View v) { switch (v.getId()) { case R.id.bt1 : if((iv_height * dr_width > dr_height * iv_width)){
//如果iv更细高,也就是我们需要调整其中图片的高度,使其高度和imageview的高度一致,这样算出scale后,使drawable的宽高同时放大scale倍。由于matrix模式下,调整scale后imageview显示图片依然是从左上角开始显示的,因此需要调整imageview的左右平移,使显示的drawable正好位于正中间。另一种情况(如果iv更宽扁)同理
//计算出高度需要放大多少倍
float scale1 = ((float)iv_height )/((float)dr_height);
//计算出左右平移多少
float offset1 = (dr_width *scale1 - (float)iv_width )/2;
Log. d("1223", "offset1 is " + offset1); Matrix matrix1 = new Matrix();
matrix1.postScale(scale1, scale1);
matrix1.postTranslate(-offset1, 0);
iv.setImageMatrix(matrix1); } else{
//如果iv更宽扁,同理
float scale2 = ((float)iv_width )/((float)dr_width); float offset2 = (dr_height *scale2 - (float)iv_height )/2;
Log. d("1223", "offset2 is " + offset2);
//产生新的大小但Bitmap对象
Matrix matrix2 = new Matrix();
matrix2.postScale(scale2, scale2);
matrix2.postTranslate(0, -offset2);
iv.setImageMatrix(matrix2);
} break; case R.id.bt2 : Matrix ma = iv.getImageMatrix(); float[] dValues = new float[9]; ma.getValues(dValues); dValues[0] = dValues[0] + 0.1f;
dValues[4] = dValues[4] + 0.1f; float offsetheight = (dr_height *dValues[0] - (float)iv_height )/2;
dValues[5] = - offsetheight;
float offsetwidth = (dr_width *dValues[0] - (float)iv_width )/2;
dValues[2] = - offsetwidth; Matrix m = new Matrix();
m.setValues(dValues); iv.setImageMatrix(m);
break;
}
} public String printMyMatrix(Matrix m){
String s = "";
float[] valueFloat = new float[9];
m.getValues(valueFloat); for(int i = 0; i < 9; i++){
s = s + " [ " + valueFloat[i] + " ] " ;
} return s;
} }
Matrix的使用说明:
android.graphics.Matrix;包下的Matrix类主要用于imageview的图形变换,主要包括平移、缩放、旋转等,具体的使用方法可以参考如下这片博客:http://blog.csdn.net/hahajluzxb/article/details/8165258
Matrix可以由一个包含9个float类型的float数组构成,下标为[0]和[4]控制x轴和y轴的伸缩,大于1为放大,小于1为缩小。下标为[2]和[5]分别控制宽和高的平移,正数为图片向左平移,负数为图片向右平移。
点击button进行zoomin效果的原理就是不断的设置imageview的matrix,使其按照float[]数组的值进行变换,在放大的情况下同时进行平移,从而达到了zoomin的效果
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:gravity= "center_horizontal"
android:orientation= "vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop= "@dimen/activity_vertical_margin" > <ImageView
android:id="@+id/iv"
android:layout_width="1200px"
android:layout_height="700px"
android:background="@drawable/background_stroke"
android:scaleType="matrix"
android:src="@drawable/dog" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" > <Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button 1" /> <Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button 2" /> </LinearLayout > </LinearLayout>
 

实现仿知乎的开场动画,图片zoomin的效果,实现原理,没加动效的更多相关文章

  1. [原创]实现android知乎、一览等的开场动画图片放大效果

    代码下载地址: https://github.com/Carbs0126/AutoZoomInImageView 知乎等app的开场动画为:一张图片被显示到屏幕的正中央,并充满整个屏幕,过一小段时间后 ...

  2. iOS动画进阶 - 实现炫酷的上拉刷新动效

    移动端訪问不佳,请訪问我的个人博客 近期撸了一个上拉刷新的小轮子.仅仅要遵循一个协议就能自己定义自己动效的上拉刷新和载入,我自己也写了几个动效进去,以下是一个比較好的动效的实现过程 先上效果图和git ...

  3. 微信小程序开发日记——高仿知乎日报(上)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  4. 微信小程序开发日记——高仿知乎日报(下)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  5. 微信小程序开发日记——高仿知乎日报(中)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该教 ...

  6. 仿知乎app登录界面(Material Design设计框架拿来就用的TexnInputLayout)

    在我脑子里还没有Material Design这种概念,就我个人而言,PC端应用扁平化设计必须成为首选,手当其冲的两款即时通讯旺旺和QQ早就完成UI扁平化的更新,然而客户端扁平化的设计本身就存在天生的 ...

  7. Android 仿知乎创意广告

    代码地址如下:http://www.demodashi.com/demo/14904.html 一.概述 貌似前段时间刷知乎看到的一种非常有特色的广告展现方式,即在列表页,某一个Item显示背后部分广 ...

  8. 用仿ActionScript的语法来编写html5——第八篇,图片处理+粒子效果

    用仿ActionScript的语法来编写html5系列开发到现在,应该可以做出一些东西了,下面先来研究下图片的各种效果预览各种效果看下图效果和代码看这里,看不到效果的请下载支持html5的浏览器 ht ...

  9. HTML5动画图片播放器 高端大气

    我们见过很多图片播放插件(焦点图),很多都基于jQuery.今天介绍的HTML5图片播放器很特别,它不仅在图片间切换有过渡动画效果,而且在切换时图片中的元素也将出现动画效果,比如图中的文字移动.打散. ...

随机推荐

  1. 【转贴】-- 基于QT的跨平台应用开发

    原帖地址:http://www.cnblogs.com/R0b1n/p/4106613.html 1 Qt简介 Qt是1991年奇趣科技开发的一个跨平台的C++图形用户界面应用程序框架.它提供给应用程 ...

  2. Android系统的常用权限

    1.ACCES_NETWORK_STATE                       允许应用程序获取网络状态信息的权限 2.ACCESS_WIFI_STATE                   ...

  3. poj 1325 Machine Schedule

    Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u   Java class name ...

  4. haskell中的monad

    monad本意是单子.在haskell中,第一个接触的基本都是IO action,通过把IO动作包装起来我们能很方便的与现实世界进行数据交换.但其实monad的用途不止如此,monad还能讲一系列操作 ...

  5. newLISP 10.5.3 发布,类 Lisp 的脚本语言

    newLISP 10.5.3 修复了一些 bug ,为 KMEANS 集群分析器增加了一些函数. newLISP是一个类似Lisp语言的.用于一般用途的脚本语言.它具有 LISP 语言所有的魔力,但更 ...

  6. WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 系列博文 <WinDbg 命令三部曲:(一)WinDbg 命令手册> <WinDb ...

  7. SQLSERVER--定期清理维护作业的历史记录

    刚删除一个数据库时,在清理数据库备份历史记录时,执行超过近10分钟还未完成,随时查了下,吓死宝宝啦,逻辑读操作竟然高达8000万次以上! 通过UI进行删除数据库时,会默认勾选上“删除数据库备份和还原历 ...

  8. HBase中MVCC的实现机制及应用情况

    MVCC(Multi-Version Concurrent Control),即多版本并发控制协议,广泛使用于数据库系统.本文将介绍HBase中对于MVCC的实现及应用情况. MVCC基本原理 在介绍 ...

  9. C#移除HTML标记

    移除一段文字中的HTML标记,以消除其中包含的样式和段落等,最常用的办法可能就是正则表达式了.但是请注意,正则表达式并不能处理所有的HTML文档,所以有时采用一个迭代的方式会更好,如for循环.看下面 ...

  10. 基于iscroll.js实现下拉刷新和上拉加载特效

    现在已经不是纯Android独霸天下的时代了,H5嵌入Android的Hybrid混合开发是大势所趋.今天给大家带来的就是移动端中常见的"上拉刷新,下拉加载"特效,这个特效将会基于 ...