android - 对button的width属性做属性动画时出错
阿神
阿神 2017-04-18 09:05:12
0
1
472

给button写了一个包装类,设置setWidth()和getWidth()方法,大多时候动画运行是正确的,但是当我连续运行几次之后就出错了,目的是把button的宽度从500px通过动画变成800px

运行几次后, 动画执行完成后button的宽度未设置为800, 如下图:

这是代码

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private TextView textView;
    private Button button;
    private int clickTimes = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.click);
        textView = (TextView) findViewById(R.id.tv_showWidth);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                performAnimate();
                clickTimes ++;
                ViewTreeObserver observer = button.getViewTreeObserver();
                observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        textView.setText("The " + (clickTimes) + "th click" + "button's width:" + button.getWidth());
                    }
                });
            }
        });
    }

    private void performAnimate() {
        ViewWrapper viewWrapper = new ViewWrapper(button);
        ObjectAnimator.ofInt(viewWrapper, "width", 500, 800).setDuration(1000).start();
    }

    private static class ViewWrapper {
        private View mTarget;

        public ViewWrapper(View mTarget) {
            this.mTarget = mTarget;
        }

        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }

        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout(); //长度宽度改变需要调用此方法进行view的测量、布局和绘制
            Log.d(TAG, "setWidth: " + mTarget.getWidth());
        }
    }

}

layout 文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.circleview.MainActivity">

    <Button
        android:id="@+id/click"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:text="Property Animation" />

    <TextView
        android:id="@+id/tv_showWidth"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="please click the button" />

</LinearLayout>
阿神
阿神

闭关修行中......

全員に返信(1)
Ty80

問題は、performAnimate()ObjectAnimator.ofInt(...) 呼び出しにあります。ObjectAnimator 自体の実装の問題により、ターゲットは WeakReference タイプとして保存されます。キー コードは次のとおりです。 リーリー

このため、オブジェクト インスタンスが維持されていない場合、GC によってリサイクルされる可能性があります。そのため、

をクラス メンバー変数として使用して、ViewWrapper を防ぐ必要があります。

さらに、押し続けると、前回と前回(前回...前回)の未完了のアニメーションが、現在のアニメーション動作に影響を与え続けます。予想される要件を満たしている場合は、最後のアニメーション リクエストをキャンセルする必要があります。コードは次のとおりです:

リーリー

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート