给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>
PHP中文网2017-04-18 09:07:12
문제는 performAnimate()
의 ObjectAnimator.ofInt(...)
호출에 있습니다. ObjectAnimator
자체의 구현 문제로 인해 대상을 WeakReference
유형으로 저장하게 됩니다.
이 때문에 객체 인스턴스가 유지되지 않으면 gc에 의해 재활용될 가능성이 높습니다. 따라서 ViewWrapper
을 클래스 멤버 변수로 사용하여 재활용을 방지해야 합니다.
으아악