http://www.bkjia.com/Androidjc/929473.html;

问题追踪:ImageView执行缩放动画ScaleAnimation之后,图像显示不全的问题。,

问题:我有一个ScrollView,嵌套了一个垂直向的LinearLayout,然后这个LinearLayout中有多个ImageView控件,分别显示自己的图像。

接着我新建了一个放大的ScaleAnimation动画,然后设置给LinearLayout或ScrollView。现在我通过监听ScrollView来滚动LinearLayout,使得放大后的ImageView可以全部看得见。

但是当我fling滑动之后,重新设置ImageView的Bitmap,此时的Bitmap虽然是跟着放大了的效果,但是被裁减了,显示不全。

解决方案:一开始,我去ScrollView和LinearLayout的onDraw方法和draw方法中查看,没有发现有什么异常,(by the way,我发现LinearLayout竟然真的能像ListView一样可以设置Divider,我之前没有发现过哟!),然后我去ImageView的onDraw方法中查看,发现有一个mDrawable,这个就是背景Drawable,还有一个mDrawMatrix,如果mDrawMatrix==null,则直接绘制mDrawable,接着我去看了一下这个mDrawMatrix是怎么赋值的。

    @Override
protected boolean setFrame(int l, int t, int r, int b) {
boolean changed = super.setFrame(l, t, r, b);
mHaveFrame = true;
configureBounds();
return changed;
} private void configureBounds() {
if (mDrawable == null || !mHaveFrame) {
return;
} int dwidth = mDrawableWidth;
int dheight = mDrawableHeight; int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
int vheight = getHeight() - mPaddingTop - mPaddingBottom; boolean fits = (dwidth < 0 || vwidth == dwidth) &&
(dheight < 0 || vheight == dheight); if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
/* If the drawable has no intrinsic size, or we're told to
scaletofit, then we just fill our entire view.
*/
mDrawable.setBounds(0, 0, vwidth, vheight);
mDrawMatrix = null;
} else {
// We need to do the scaling ourself, so have the drawable
// use its native size.
mDrawable.setBounds(0, 0, dwidth, dheight); if (ScaleType.MATRIX == mScaleType) {
// Use the specified matrix as-is.
if (mMatrix.isIdentity()) {
mDrawMatrix = null;
} else {
mDrawMatrix = mMatrix;
}
} else if (fits) {
// The bitmap fits exactly, no transform needed.
mDrawMatrix = null;
} else if (ScaleType.CENTER == mScaleType) {
// Center bitmap in view, no scaling.
mDrawMatrix = mMatrix;
mDrawMatrix.setTranslate((int) ((vwidth - dwidth) * 0.5f + 0.5f),
(int) ((vheight - dheight) * 0.5f + 0.5f));
} else if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix = mMatrix; float scale;
float dx = 0, dy = 0; if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
} mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
} else if (ScaleType.CENTER_INSIDE == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx;
float dy; if (dwidth <= vwidth && dheight <= vheight) {
scale = 1.0f;
} else {
scale = Math.min((float) vwidth / (float) dwidth,
(float) vheight / (float) dheight);
} dx = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);
dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f); mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(dx, dy);
} else {
// Generate the required transform.
mTempSrc.set(0, 0, dwidth, dheight);
mTempDst.set(0, 0, vwidth, vheight); mDrawMatrix = mMatrix;
mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));
}
}
}

很显然,这个mDrawMatrix会根据mScaleType的值来操作,因为我的程序内mScaleType是ScaleType.FIT_XY,所以执行了这段:

if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
  mDrawable.setBounds(0, 0, vwidth, vheight);
  mDrawMatrix = null;
}

这个mDrawable被设置成控件本身的宽高了。

然后我试图查找下当控件被执行动画之后,这个bounds会不会也被设置了,我找到了一个方法:

    /**
* Return the visible drawing bounds of your view. Fills in the output
* rectangle with the values from getScrollX(), getScrollY(),
* getWidth(), and getHeight(). These bounds do not account for any
* transformation properties currently set on the view, such as
* {@link #setScaleX(float)} or {@link #setRotation(float)}.
*
* @param outRect The (scrolled) drawing bounds of the view.
*/
public void getDrawingRect(Rect outRect) {
outRect.left = mScrollX;
outRect.top = mScrollY;
outRect.right = mScrollX + (mRight - mLeft);
outRect.bottom = mScrollY + (mBottom - mTop);
}

这个方法返回你的视图的绘制区域的边距信息,其中有一句话(These bounds do not account for any * transformation properties currently set on the view, such as * {@link #setScaleX(float)} or {@link #setRotation(float)}.) ,意思应该是这个bounds是不会被动画所影响的。好吧。。。感觉没有头绪了啊。。。

接着我去Google了一下:android ImageView after ScaleAnimation draw not complete

在倒数几条搜索结果中,

我找到了:ImageView scale animation cropping(link:https://code.google.com/p/android/issues/detail?id=20333),内容如下:

Reported by halfs...@gmail.com, Sep 26, 2011

I have a project that requires a fairly simple animation.
There is a ImageView created this way:
<ImageView android:src="@drawable/letter3" android:clipChildren="false" android:clipToPadding="false" android:cropToPadding="false" android:id="@+id/startmessage" android:adjustViewBounds="true" android:layout_width="wrap_content" android:scaleType="fitCenter" android:layout_centerVertical="true" android:layout_centerHorizontal="true"></ImageView> As I understand it wrap_content should keep the size of the view big enough to contain the image within.
Then in code I set an image and start an animation that fades out and scales up the image: final ImageView v = (ImageView)findViewById(R.id.startmessage);
fadeout.setAnimationListener(null);
v.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.letter3));
v.startAnimation(fadeout); Here is the animation code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true">
<alpha android:fromAlpha = "1.0"
android:toAlpha = "0.0"
android:duration="1000"
/>
</set> The problem is that when the scaling animation begins the drawing rect does not seem to change so the image is cropped when it becomes larger. The problem occurs only on android 2.3.3 I believe, on device and on emulator as well. I played around with all the scaleType settings for the imageview but it didn't fix the problem. Sep 26, 2011
#1 halfs...@gmail.com Correction - this is how the animation is defined: <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true">
<alpha android:fromAlpha = "1.0"
android:toAlpha = "0.0"
android:duration="1000"
/>
<scale android:fromXScale="1.0"
android:toXScale="6.0"
android:fromYScale="1.0"
android:toYScale="6.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
/>
</set> Sep 26, 2011
Project Member #2 romain...@android.com The ImageView will be cropped by its parent. You need to disable children clipping on the parent and make the parent big enough. Status: Declined
Sep 27, 2011
#3 halfs...@gmail.com The parent is fullscreen and it also is set to not crop the children, also this behavior is observer only on 2.3.3, on 2.2 and lower everything is working fine. <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:clipChildren="false" android:clipToPadding="false" android:id="@+id/startlayout" android:visibility="invisible">
<ImageView android:layout_height="wrap_content" android:src="@drawable/letter3" android:layout_width="wrap_content" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:scaleType="fitCenter" android:id="@+id/startmessage"></ImageView>
</RelativeLayout>

意思是你的父容器的clipChildren属性默认为true,导致了这个裁剪现象的发生。现在你只需要将ScrollView和LinearLayout的clipChildren属性设置为true即可。

就目前来看,我的三星i9250是没问题,另外我用Genymotion模拟器模拟4.3的Nexus4也没问题,其他版本的未知。

动画--问题追踪:ImageView执行缩放动画ScaleAnimation之后,图像显示不全的问题。的更多相关文章

  1. Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform)

    在Silverlight的动画框架中,ScaleTransform类提供了在二维空间中的坐标内进行缩放操作,通过ScaleTransform可以在水平或垂直方向的缩放和拉伸对象,以实现一个简单的缩放动 ...

  2. AndroidTv Home界面实现原理(二)——Leanback 库的主页卡位缩放动画源码解析

    先看个效果图: 上一篇中,我们留了问题,在 Tv Home 界面这种很常见聚焦卡位放大动画效果,我们这一篇就来看看 Leanback 库是怎么实现的. 如果要我们自己实现的话,思路应该不难,就是写个放 ...

  3. android缩放动画的两种实现方法

    在android开发.我们会常常使用到缩放动画,普通情况下缩放动画有两种实现方式.一种是直接通过java代码去实现,第二种是通过配置文件实现动画,以下是两种动画的基本是用法: Java代码实现: // ...

  4. AndroidUI 视图动画-缩放动画效果 (ScaleAnimation)

    放动画效果,可以使用ScaleAnimation: <Button android:id="@+id/btnScale2" android:layout_width=&quo ...

  5. Android缩放动画

    Android缩放动画 核心方法 public void startAnimation(Animation animation) 执行动画,参数可以是各种动画的对象,Animation的多态,也可以是 ...

  6. UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法

    基本的动画构成共有四种:透明动画/旋转动画/移动动画/缩放动画. 配置动画的方式有两种,一种是直接使用代码来配置动画效果,另一种是使用xml文档配置动画效果 相比而言,用xml文档写出来的动画效果,写 ...

  7. iOS开发笔记10:圆点缩放动画、强制更新、远程推送加语音提醒及UIView截屏

    1.使用CAReplicatorLayer制作等待动画 CALayer+CABasicAnimation可以制作很多简单的动画效果,之前的博客中介绍的“两个动画”,一个是利用一张渐变色图片+CABas ...

  8. iOS:Gif动画功能(显示gif动画、获取gif动画时长、获取gif动画执行次数)

    一.简单介绍 gif动画是iOS开发中很常用的一个功能,有的是为了显示加载视频的过程,更多的是为了显示一个结果状态(动画更直观). 那么如何执行gif动画,方法有很多.(这里只写一下方法三,前两种之前 ...

  9. POP缩放动画

    POP缩放动画 效果 源码 https://github.com/YouXianMing/Animations // // SpringScaleViewController.m // Animati ...

随机推荐

  1. DirectShow开发快速入门之慨述

    摘要:本篇文档概括性的介绍了DirectShow的主要组成部分,以及一些Directshow的基本概念.熟悉这些基本的知识对于Directshow的应用开发或者过滤器的开发者都会有所帮助. Direc ...

  2. linux awk的使用

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  3. eclipse控台不见

  4. PP读取生产订单状态

    转自http://blog.csdn.net/heng0757/article/details/6656089 传递订单号码,可以返回该订单的状态 REPORT  ZCMH2.TABLES : JES ...

  5. SQL_Server_2008修改sa密码的方法

    转载自:http://blog.csdn.net/templar1000/article/details/20211191 1. 先用Window身份验证方式登陆进去,选择数据库实例,右键选择属性—— ...

  6. 今天我看了一个H5游戏EUI的例子,我都快分不清我到底是在用什么语言编译了代码了,作为刚刚学习H5游戏开发的菜鸟只能默默的收集知识

    今天看了一个EUI的demo,也是接触H5游戏开发的第五天了,我想看看我能不能做点什么出来,哎,自己写果然还是有问题的.在看EUI哪一个demo的时候就遇见了一些摇摆不定的问题,我觉得提出来 1.to ...

  7. linux文件系统节点详解

    linux文件系统有两层结构,逻辑结构和物理结构.也就是inode和block. 每个文件都有一个inode, 记录文件属性:权限,时间还有最重要的block号码. block是实际存放文件内容的地方 ...

  8. CE 内存申请

    char ch_ReadByte='H'; char *ptr_OneLineData; unsigned ); if ((ptr_OneLineData = (char *)malloc(bufsi ...

  9. centos安装sublime

    在官网下载,tarball    下载链接        http://www.sublimetext.com/3 提示信息:  Ubuntu 64 bit - also available as a ...

  10. Zookeeper 的学习与运用

    引子 云计算越来越流行的今天,单一机器处理能力已经不能满足我们的需求,不得不采用大量的服务集群.服务集群对外提供服务的过程中,有很多的配置需要随时更新,服务间需要协调工作,这些信息如何推送到各个节点? ...