【譯】Animate Objects, not Views

原文地址:https://android.jlelse.eu/animate-objects-not-views-250fe7880196

無可否認,我們都喜歡炫酷的動畫效果婉商。沒有用戶會喜歡生硬配乓、沒有過渡和動畫的app黑滴。但同時沒有開發(fā)者愿意花費大量的時間和ValueAnimator打交道趴泌,特別是當你需要創(chuàng)建很多ValueAnimators才能達到自己相要的效果。

因此為什么不使用DataBinding來完成這些復雜的事抒抬?

眾所周知复局,BaseObservable可以包含標有@Bindable注釋的字段冲簿。

就像這樣:

public class ExpandStateItem extends BaseObservable {

    @Bindable
    private float padding;
    @Bindable
    private boolean expanded;
    @Bindable
    private boolean fast;
}

如果您調用notifyPropertyChanged(BR.field_name),任何使用此字段的視圖將被通知到亿昏,然后進行更新民假。所以唯一剩下我們需要做的事情就是把正確的東西綁定到正確的值。

在我的例子中有3個可以綁定的屬性龙优。 讓我們一一看看他們羊异。

第一個值是padding,我們需要像這樣綁定它

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@{state.padding}"
    android:paddingTop="@{state.padding}">
....
</LinearLayout>

state是在布局文件中聲明的類型為ExpandStateItem的變量

Android DataBinding庫甚至知道如何設置padding屬性彤断,因此您不需要自己創(chuàng)建@BindingAdapter野舶。

現(xiàn)在如果您為ExpandStateItem對象的padding設置某個值,您會看到它對應的所有視圖實際上會改變它的padding值宰衙。

如果您創(chuàng)建一些動畫并在動畫的CallBack中更改此值平道,則所有視圖將相應地進行動畫。

這里是一個例子供炼。 state是一個在RecyclerView中綁定到RecyclerView.ViewHolders的數(shù)組一屋。

private ValueAnimator paddingAnimator = ValueAnimator.ofFloat(MAX_MARGIN, MIN_MARGIN);
paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        for (ExpandStateItem item :
                states) {
            item.setPading((float) animation.getAnimatedValue());
        }
    }
});

下一個變量是expanded窘疮。如果您注意到文章頂部的GIF圖像,它有一些可伸縮的卡片冀墨,它們隨著expanded屬性的改變而擴展/折疊闸衫。 它是這樣綁定?的:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:visibility="gone"
    app:expand="@{state.expanded}"
    app:fastExpand="@{state.fast}">
...
</LinearLayout>

另外你可能注意到了app:fastExpand,稍后我會告訴你诽嘉。

對于app:expand屬性蔚出,我們需要編寫我們自己的@BindingAdapter。

@BindingAdapter({"expand", "fastExpand"})
public static void expandView(View view, boolean expand, boolean fast) {
    if (expand) {
        ViewAnimationUtils.expand(view, null, fast);
    } else if (view.getHeight() != 0) {
        ViewAnimationUtils.collapse(view, null, fast);
    }
}

現(xiàn)在虫腋,如果我向你展示ViewAnimationUtils類骄酗,我敢打賭你會弄清楚為什么我們需要fastExpand屬性。

package com.wldev.expandablecardviewlist.extra;

import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class ViewAnimationUtils {

    public static void expand(final View v, final AnimationEndCallback callback, boolean fast) {
        v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        final int targtetHeight = v.getMeasuredHeight();

        v.getLayoutParams().height = 0;
        v.setVisibility(View.VISIBLE);
        Animation a = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                v.getLayoutParams().height = interpolatedTime == 1
                        ? ViewGroup.LayoutParams.WRAP_CONTENT
                        : (int) (targtetHeight * interpolatedTime);
                v.requestLayout();
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        int duration = 0;

        if (!fast) {
            duration = (int) (targtetHeight / v.getContext().getResources().getDisplayMetrics().density);
        }

        a.setDuration(duration);
        a.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (callback != null)
                    callback.onAnimationEnded();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        v.startAnimation(a);
    }

    public static void collapse(final View v, final AnimationEndCallback callback, boolean fast) {
        final int initialHeight = v.getMeasuredHeight();

        Animation a = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                if (interpolatedTime == 1) {
                    v.setVisibility(View.GONE);
                } else {
                    v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
                    v.requestLayout();
                }
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        int duration = 0;
        if (!fast) {
            duration = (int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density);
        }

        a.setDuration(duration);

        a.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (callback != null)
                    callback.onAnimationEnded();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        v.startAnimation(a);
    }

    interface AnimationEndCallback {
        void onAnimationEnded();
    }
}

通過將fastExpand指定為true悦冀,將不會有動畫時長趋翻。

但是為什么我們需要移除動畫時長?事實上盒蟆,如果你想在可回收的列表上使用它嘿歌,完全不必這樣做。當view將被回收并再次使用(RecyclerView里是onBindViewHolder)茁影,所有動畫將再次出現(xiàn)在此特定視圖中,因此需要指定我們只想展開的視圖丧凤,并且不展示進度募闲。

例子就這樣,如何與視圖進行交互(動畫)愿待,而不會觸及視圖(實際上你會浩螺,但是間接地)。 你可以用它做的事情只會受到你想象力的限制仍侥。Viewmargins, paddings, width, height要出,TextViewlines count, color, taste (no), thousands of them.。

我的示例的源代碼在GitHub上here农渊。

Thanks for attention and happy coding :)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末患蹂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子砸紊,更是在濱河造成了極大的恐慌传于,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醉顽,死亡現(xiàn)場離奇詭異沼溜,居然都是意外死亡,警方通過查閱死者的電腦和手機游添,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門系草,熙熙樓的掌柜王于貴愁眉苦臉地迎上來通熄,“玉大人,你說我怎么就攤上這事找都〈奖妫” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵檐嚣,是天一觀的道長助泽。 經(jīng)常有香客問我,道長嚎京,這世上最難降的妖魔是什么嗡贺? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮鞍帝,結果婚禮上诫睬,老公的妹妹穿的比我還像新娘。我一直安慰自己帕涌,他們只是感情好摄凡,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚓曼,像睡著了一般亲澡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纫版,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天床绪,我揣著相機與錄音,去河邊找鬼其弊。 笑死癞己,一個胖子當著我的面吹牛,可吹牛的內容都是我干的梭伐。 我是一名探鬼主播痹雅,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糊识!你這毒婦竟也來了绩社?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赂苗,失蹤者是張志新(化名)和其女友劉穎铃将,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哑梳,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡劲阎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸠真。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悯仙。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡龄毡,死狀恐怖,靈堂內的尸體忽然破棺而出锡垄,到底是詐尸還是另有隱情沦零,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布货岭,位于F島的核電站路操,受9級特大地震影響,放射性物質發(fā)生泄漏千贯。R本人自食惡果不足惜屯仗,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搔谴。 院中可真熱鬧魁袜,春花似錦、人聲如沸敦第。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芜果。三九已至鞠呈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間右钾,已是汗流浹背蚁吝。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霹粥,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓疼鸟,卻偏偏與公主長得像后控,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子空镜,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,290評論 25 707
  • 簡介: 提供一個讓有限的窗口變成一個大數(shù)據(jù)集的靈活視圖浩淘。 術語表: Adapter:RecyclerView的子類...
    酷泡泡閱讀 5,174評論 0 16
  • DataBinding 庫是 Google 公司 Android Framework UI 工具團隊開發(fā)出來的一款...
    bravian閱讀 5,425評論 2 16
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)吴攒,斷路器张抄,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • 文/ 微風和煦的世界 場景一:拿別人家的孩子來比自己家的 L先生總是喜歡拿自己的侄女和家里的另一個親戚的小孩來比較...
    煦媽讀書閱讀 339評論 2 1