亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

android - 對button的width屬性做屬性動畫時出錯

瀏覽:115日期:2024-08-23 09:24:27

問題描述

給button寫了一個包裝類,設置setWidth()和getWidth()方法,大多時候動畫運行是正確的,但是當我連續運行幾次之后就出錯了,目的是把button的寬度從500px通過動畫變成800px

android - 對button的width屬性做屬性動畫時出錯

運行幾次后, 動畫執行完成后button的寬度未設置為800, 如下圖:

android - 對button的width屬性做屬性動畫時出錯

這是代碼

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: android:layout_width='match_parent' android:layout_height='match_parent' android:orientation='vertical' tools:context='com.example.circleview.MainActivity'> <Buttonandroid: android:layout_width='wrap_content'android:layout_height='50dp'android:text='Property Animation' /> <TextViewandroid: android:layout_width='wrap_content'android:layout_height='wrap_content'android:text='please click the button' /></LinearLayout>

問題解答

回答1:

問題就出在 performAnimate() 的 ObjectAnimator.ofInt(...) 調用, 由于 ObjectAnimator 本身實現的問題, 它會把 target 存為 WeakReference 類型. 關鍵代碼如下:

public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { ObjectAnimator anim = new ObjectAnimator(target, propertyName); anim.setIntValues(values); return anim;}private ObjectAnimator(Object target, String propertyName) { setTarget(target); setPropertyName(propertyName);}@Overridepublic void setTarget(@Nullable Object target) { final Object oldTarget = getTarget(); if (oldTarget != target) {if (isStarted()) { cancel();}mTarget = target == null ? null : new WeakReference<Object>(target);// New target should cause re-initialization prior to startingmInitialized = false; }}

由于這個原因, 如果不保持對象實例, 那么就很有可能會被gc回收掉. 因此, ViewWrapper 應該作為類成員變量, 以防被回收.

另外, 如果不停地按, 就會不停地產生多個動畫請求. 而上次以及上上次(上...上次)未執行完成的動畫會影響當次的動畫動作. 如果要達到預期的要求, 就應該把上次的動畫請求取消掉. 代碼如下:

private ObjectAnimator mObjectAnimator;private ViewWrapper viewWrapper;private void performAnimate() { if (mObjectAnimator != null) {mObjectAnimator.cancel();mObjectAnimator = null; } viewWrapper = new ViewWrapper(button); mObjectAnimator = ObjectAnimator.ofInt(viewWrapper, 'width', 500, 800).setDuration(1000); mObjectAnimator.start();}

相關文章:
主站蜘蛛池模板: 亚洲图片一区二区 | 福利在线观看视频 | 久久精品国产99国产精偷 | 亚洲网站在线观看 | 欧美黄视频网站 | 日韩经典一区 | 久久午夜鲁丝片午夜精品 | 国产视频久久久 | 亚洲第一区精品日韩在线播放 | 日本中文字幕有码 | 永久福利视频 | 国产精品超清大白屁股 | 成年黄色 | 久久久美女视频 | 香蕉视频美女 | 澳门一级特黄真人毛片 | 青青操在线免费观看 | 麻豆404| 在线观看中文字幕第一页 | 91九色porn偷拍在线 | 伊人久久精品亚洲精品一区 | 91精品啪在线看国产网站 | 成人毛片100部免费看 | 久久久久久亚洲精品 | 国产精品真实对白精彩久久 | 日韩美女网站在线看 | 夜夜操夜夜爱 | 高清黄色毛片 | 亚洲一区日韩二区欧美三区 | 麻豆91制片厂 | 9久9久女女热精品视频免费观看 | 欧美视频第二页 | 日本特黄特黄刺激大片免费 | 免费国产不卡午夜福在线观看 | 国产精品久久久久无码av | 新一级毛片国语版 | 日韩一区二区三区视频在线观看 | 国产成人影院一区二区 | 世界一级毛片 | 69视频最新在线观看 | 欧美日韩a级片 |