成人视屏在线观看-国产99精品-国产精品1区2区-欧美一级在线观看-国产一区二区日韩-色九九九

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

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

瀏覽:153日期: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在线视频网站 | 日韩免费看片 | 一级欧美一级日韩片 | 精品一区二区三区在线视频 | 国产三级精品三级国产 | 成人免费视频一区 | 免费一级欧美片片线观看 | 亚洲精品午夜久久久伊人 | 国产一在线精品一区在线观看 | 亚洲精品一区二区三区国产 | 波多野结衣被强在线视频 | 最新国产精品亚洲 | 国产真人毛片一级视频 | 7777在线视频 | 欧美一级毛片免费播放器 | 亚洲视频免费在线 | 国产精品综合久成人 | 台湾三级香港三级在线理论 | 青青操在线视频 | 欧美成人另类69 | 狠狠久久综合 | 男女牲高爱潮免费视频男女 | 亚洲精品一区二区三区第四页 | 波多野结衣一区在线观看 | 精品免费久久久久欧美亚一区 | 亚洲综合伦理一区 | 中文字幕在线永久 | 特黄特a级特别特级特毛片 特黄特黄 | 欧美粗又大gay69视频 | 国产农村乱| 亚洲日产2021三区 | 男女午夜爽爽 | 韩国一级毛片在线观看 | 亚洲 午夜在线一区 | 国产精品久久在线观看 | 白嫩美女直冒白浆 | 国产精品yjizz视频网一二区 | 日韩欧美精品在线观看 | 香蕉久久精品国产 | 亚洲高清无在码在线无弹窗 |