开发者

Android 2.3: Grow/Shrink animation bug?

For my application, I'm trying to add a [grow/shrink + alpha change] animation to each ImageView in my layout. I managed to get the animations working and have each of the animations persist after they're done by setting fillAfter=开发者_如何转开发"true" for both of my XML files (grow.xml and shrink.xml). However, there seems to be some weird animation bug that causes unselected images to grow and then 'snap' back to normal size when I set fillAfter="true for shrink.xml! Let me explain how the application works and then give a scenario so it becomes more clear:

Initially, all the images have their alpha levels set to 50%. When I click on a particular image, it will grow to 120% and its alpha level will become 100% ('light up' effect). When I click on another image, the previously selected image will shrink back to 100% and its alpha level will return to 50% and the currently selected image will grow as described previously.

In my layout, I have three, equal sized images placed in a row. I click the first image, then click the second one then click the first one again. Ok, no problems there. Now, I click on the third image and I get the weird snapping problem for the first image. Any idea how to fix this?

I've tried:

  1. image.setAlpha(...) to avoid having to set the alpha level in shrink.xml then calling fillAfter="true", but unfortunately that's an API 11 call
  2. setting the fillAfter attribute of only my alpha tags to true in shrink.xml
  3. calling image.startAnimation(fadeOut) right after a shrink animation but that looks horrible.
  4. Overriding onAnimationEnd(), but this call never gets reached(??)

shrink.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fillAfter="true"> <scale android:fromXScale="1.2" android:toXScale="1.0" android:fromYScale="1.2" android:toYScale="1.0" android:duration="300" android:pivotX="50%" android:pivotY="50%"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.5" android:duration="300"/> </set>

grow.xml

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fillAfter="true"> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="1.0" android:toXScale="1.20" android:fromYScale="1.0" android:toYScale="1.20" android:duration="300" android:pivotX="50%" android:pivotY="50%" /> <alpha android:fromAlpha="0.5" android:toAlpha="1.0" android:duration="300"/> </set>

fade_out.xml:

<?xml version="1.0" encoding="UTF-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:startOffset="300" android:fromAlpha="1.0" android:toAlpha="0.5" android:fillAfter="true"> </alpha>

main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <ImageView android:id="@+id/image1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="20dip" android:paddingRight="20dip" android:src="@drawable/image1"/> <ImageView android:id="@+id/image2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="20dip" android:paddingRight="20dip" android:src="@drawable/image2"/> <ImageView android:id="@+id/image3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="20dip" android:paddingRight="20dip" android:src="@drawable/image3"/> </LinearLayout>

Test.java:

    public class Test extends Activity {
    private View mSelected;
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Animation fadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
    final Animation grow = AnimationUtils.loadAnimation(this, R.anim.grow);
    final Animation shrink = AnimationUtils.loadAnimation(this, R.anim.shrink);

    OnClickListener listener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (mSelected == v) 
                return;

            if (mSelected != null) 
                mSelected.startAnimation(shrink);

            mSelected = v;
            mSelected.startAnimation(grow);             
        }
    };

    ImageView image1 = (ImageView)findViewById(R.id.image1);
    image1.startAnimation(fadeOut);
    image1.setOnClickListener(listener); 

    ImageView image2 = (ImageView)findViewById(R.id.image2);
    image2.startAnimation(fadeOut);
    image2.setOnClickListener(listener);

    ImageView image3 = (ImageView)findViewById(R.id.image3);
    image3.startAnimation(fadeOut);
    image3.setOnClickListener(listener);
}}


The problem is that your shrink Animation is still assigned to the other Views. When you're calling mSelected.startAnimation() you are starting the Animation object, which is attached to the other Views, so they animate as well. You can create a new instance of the Animation by changing mSelected.startAnimation(shrink); to

mSelected.startAnimation(AnimationUtils.loadAnimation(Test.this, R.anim.shrink));

Which is the easy (though inefficient) way to solve the problem, or you can manage the Animation cycle yourself by unassigning Animations from Views (mSelected.setAnimation(null)).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜