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. Win10/UWP开发—使用Cortana语音指令与App的前台交互

    Win10开发中最具有系统特色的功能点绝对少不了集成Cortana语音指令,其实Cortana语音指令在以前的wp8/8.1时就已经存在了,发展到了Win10,Cortana最明显的进步就是开始支持调 ...

  2. SILVERLIGHT 应急卫生模拟演练项目之GRID布局

    上篇文章 我介绍了LOADING界面 loading加载完成后 会进入主界面 效果图如下 这里我要给大家说一下我在布局方面的应用  说起布局 做过SL开发的一定都知道 Grid,StackPanel和 ...

  3. HTTPURLConnection 发送Post数据

    在使用HTTPURLConnection发送POST数据时,通常使用如下方式: byte[] body = new byte[512]; // 需要发送的body数据 URL url = new UR ...

  4. Linux系统上通知网关更新arp

    经常会有在线更换Linux服务器IP的操作,该操作带来的一个问题是: 我们已经执行了修改IP的操作,但由于网络上(网关)的ARP缓存暂未更新,导致在某一段时间内,该服务器会有网络不通的情况存在. 因此 ...

  5. matlab列优先与高维矩阵重构 及 CNN 逐层可视化 on Matlab

    由于matlab在列化a(:)以及reshape(a)等操作中是列优先的,所以要重构出新的高维度矩阵,通常要把reshape和permute结合起来使用. 先到 http://caffe.berkel ...

  6. 使用 FP-growth 算法高效挖掘海量数据中的频繁项集

    前言 对于如何发现一个数据集中的频繁项集,前文讲解的经典 Apriori 算法能够做到. 然而,对于每个潜在的频繁项,它都要检索一遍数据集,这是比较低效的.在实际的大数据应用中,这么做就更不好了. 本 ...

  7. LintCode MinStack

    Implement a stack with min() function, which will return the smallest number in the stack. It should ...

  8. .offset().top是什么意思?

    offset获取匹配元素在当前视口的相对偏移: 返回的对象包含两个整形属性:top,left.此方法只对 可见元素有效. $("#div").offset() 获得位移对象:(此时 ...

  9. 用JS实现的类似QQ密码的输入特效

    <input ID="_PSD"></input> <script> function passwordText(ID,pd,mark){ ma ...

  10. netezza 数据库 取 季初 季末 时间

    -- 取季初那一天 select date_trunc( 'quarter',cast('20150820' as date)) -- 取季末那一天 select add_months(date_tr ...