Android动画在移动过程中会留下线条

时间:2011-09-12 18:33:59

标签: android animation

我使用AbsoluteLayout在3x4网格中设置了12个ImageButton。当用户点击图像按钮时,它会增长以填满屏幕,保持,然后缩小到原始位置。

动画有效,但按钮收缩时有时会留下线条。 (我在下面附上了图片)。

有没有更好的方法来实现这个动画?我该怎么做才能防止我得到的绘图错误?

修改: 收缩动画完成后,线条也会消失,它们仅在动画期间出现。

这是我的 UDATED 动画代码

private void animateCard(final CardButton c){
    this.isAnimating = true;
    CardPickerActivity.this.soundManager.playSound(c.name);
    Util.logD("Card:" + c.name + " clicked!");

    final int growDuration = 750;
    final int holdDuration = 500;
    final int shrinkDuration = 500;

    c.bringToFront();
    AnimationSet asGrow = new AnimationSet(true);
    float newScale = 2.0f;
    float newX = (CardPickerActivity.this.wDesk/2.0f - CardPickerActivity.this.cardSize/2.0f*newScale - c.getLeft())/newScale;
    float newY = (CardPickerActivity.this.hDesk/2.0f - CardPickerActivity.this.cardSize/2.0f*newScale - c.getTop() )/newScale;
    TranslateAnimation taG = new TranslateAnimation(0.0f, newX , 0.0f, newY);
    ScaleAnimation saG = new ScaleAnimation(    1.0f, newScale, 1.0f, newScale);

    taG.setRepeatCount(1);
    saG.setRepeatCount(1);
    taG.setRepeatMode(Animation.REVERSE);
    saG.setRepeatMode(Animation.REVERSE);

    asGrow.addAnimation(taG);
    asGrow.addAnimation(saG);
    asGrow.setDuration(growDuration);


    c.startAnimation(asGrow);

}

这是活动的XML布局,忽略layout_x和layout_y我稍后根据设备的屏幕设置它们:

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/cardLayout" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.myProject.CardButton
        android:id="@+id/btn1" android:text="1" android:layout_x="0px"
        android:layout_y="0px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn2" android:text="2" android:layout_x="10px"
        android:layout_y="10px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn3" android:text="3" android:layout_x="20px"
        android:layout_y="20px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn4" android:text="4" android:layout_x="30px"
        android:layout_y="30px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn5" android:text="5" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn6" android:text="6" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn7" android:text="7" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn8" android:text="8" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn9" android:text="9" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn10" android:text="10" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn11" android:text="11" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <com.myProject.CardButton
        android:id="@+id/btn12" android:text="12" android:layout_x="40px"
        android:layout_y="40px" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</AbsoluteLayout>

这是CardButton类,它本质上是一个带有更多成员变量的ImageButton

public class CardButton extends ImageButton {
    public CardButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public CardButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CardButton(Context context) {
        super(context);
    }

    public String name;
    public Bitmap image;

    public int soundRes;
    public int imageRes;

    public String customImagePath;
    public String customSoundPath;
}

Here is what the grid looks like before touch

Here is what the grid looks like when a button has finished growing

Here is what the grid looks like when the button has finished skrinking. Notice the white vertical lines

3 个答案:

答案 0 :(得分:2)

所以我解决了这个问题,但并没有让我满意。

首先在我的代码中的一个地方我没有显示我打电话:

cardButton.setBackgroundColor(Color.WHITE);

如果我注释掉这一行,问题就会消失。然而,这产生了看起来像股票Android按钮的CardButtons。这不是我想要它们的样子,所以我尝试了其他一些方式设置白色按钮“style”。所有这些都产生了这个bug。

为了更好地了解正在发生的事情,并在Android或我的代码中找出可能存在的错误,我创建了一个测试项目,该项目仅包含一个带有3x4网格的活动而没有其他内容。此测试项目包含单个活动和单个XML文件。从基本网格开始,我无法重现该错误,然后我开始向测试应用添加越来越多的功能,并最终重新创建了原始活动但没有错误。

我想我的新实现可能比原版更好,所以我将新的测试活动合并到我的原始项目中。但是,当我从原始项目运行测试活动时,错误再次出现。

我现在有两个活动在不同的Android项目中使用相同的代码。一个是项目中唯一的活动,另一个是具有许多活动的大型项目的一部分。较大项目中的版本显示错误,而独立项目中的版本则没有。我不确定如何解释这一点,我非常感谢您对此提出任何反馈/意见。

所以,直到我能弄清楚为什么我在更大的应用程序的上下文中得到绘图错误,我将使用股票android按钮背景。

更新:我突然想到一个白色的9Patch背景。这解决了这个问题。

答案 1 :(得分:1)

这可能会导致问题。有时动画onAnimationEnd会在实际动画完成之前触发一下。

您可以创建自定义视图或布局,并覆盖其“animationEnd”方法并添加界面,以便设置侦听器。

这是一个例子

CustomLayout类

public class CustomLayout extends LinearLayout {
    private LayoutAnimationListener mListner;

    public CustomLayout(Context context) {
        super(context);
    }

    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onAnimationEnd() {
        super.onAnimationEnd();
        if(mListner != null){
            mListner.onAnimationEnd(CustomLayout.this);
        }
    }

    @Override
    protected void onAnimationStart() {
        super.onAnimationStart();
        if(mListner != null){
            mListner.onAnimationStart(CustomLayout.this);
        }
    }

    public static interface LayoutAnimationListener {
        //Notifies the start of the animation.
        void onAnimationStart(CustomLayout cLayout);
        //Notifies the end of the animation.
        void onAnimationEnd(CustomLayout cLayout);
    }

    public void setLayoutAnimationListener(LayoutAnimationListener listener){
        mListner = listener;
    }
}

因此,在您的活动中,您可以将其用作普通的线性布局,而不是向动画中添加动画侦听器,您可以将其添加到布局中,如

com.blessan.CustomLayout layout   = 
            (com.blessan.CustomLayout)findViewById(R.id.counts_layout);
    LayoutAnimationListener layoutAnimListener = new LayoutAnimationListener() {           
        @Override
        public void onAnimationStart(CustomLayout cLayout) {

        }

        @Override
        public void onAnimationEnd(CustomLayout cLayout) {

        }

    };
    layout.setLayoutAnimationListener(layoutAnimListener);

这可能适合你。试一试。

答案 2 :(得分:1)

改进/可能的解决方案:

我的代码有所改进,希望它能解决你的刷新问题。也觉得这是你正在尝试的正确方法。

growShrink.addAnimation(ta);
growShrink.addAnimation(sa);
holdAnim.setStartOffset(growDuration); // hold will start when grow stops.
growShrink.addAnimation(holdAnim);

growShrink.setRepeatCount(1);
growShrink.setRepeatMode(Animation.REVERSE);
growShrink.setInterpolator(new LinearInterpolator());

这将反过来播放不断增长的动画。无需动画结束侦听器即可启动保持和缩小动画。


替代解决方案:

将所有增长,保持和缩小的动画添加到一个AnimtaionSet中。适当地设置保持和缩小动画的起始偏移。

// growAnim will start at 0.
holdAnim.setStartOffset(growDuration); 
shrinkAnim.setStartOffset(growDuration+holdDuration);