给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>
Masalahnya terletak pada panggilan
performAnimate()
ObjectAnimator.ofInt(...)
Disebabkan masalah pelaksanaanObjectAnimator
itu sendiri, ia akan menyimpan sasaran sebagai jenisWeakReference
adalah seperti berikut:Atas sebab ini, jika tika objek tidak dikekalkan, ia berkemungkinan dikitar semula oleh gc Oleh itu,
Selain itu, jika anda terus menekan, berbilang permintaan animasi akan terus dihasilkan Animasi yang belum selesai dari kali terakhir dan kali terakhir (terakhir...kali terakhir) akan menjejaskan tindakan animasi semasa memenuhi keperluan yang diharapkan, anda harus membatalkan permintaan animasi terakhir Kodnya adalah seperti berikut:ViewWrapper
harus digunakan sebagai pembolehubah ahli kelas untuk mengelakkannya daripada dikitar semula