Material Design - ShareElements

jake-ingle

拖了很久,不過(guò)終于有時(shí)間把這個(gè)點(diǎn)給磨完了。網(wǎng)上關(guān)于共享元素的效果很多,不過(guò)大致原理相同,先看看效果圖:

GIF.gif

共享元素的優(yōu)點(diǎn)這里就不講了,很多東西學(xué)了不一定有用,但是好看的東西大家都喜歡。

注意:共享元素需要 api 21 以上才支持

Activity 中的共享元素


第一步

首先,我們需要在style.xml中加入下面的代碼:

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="android:windowContentTransitions">true</item>
    ...
</style>

當(dāng)然用 java 代碼在用到共享元素的頁(yè)面設(shè)置也可以。

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
第二步

接下來(lái),我們需要確認(rèn)兩個(gè)頁(yè)面中共享的元素。Android 提供了android:transitionName:屬性作為兩個(gè) View 共享的標(biāo)志。頁(yè)面中的共享元素可以不同id,在不同的層級(jí),但是一定要有android:transitionName:,這是標(biāo)志兩個(gè)View為共享元素的唯一標(biāo)志。

item_layout.xml:
<LinearLayout>
    <LinearLayout>
        <ImageView
            android:id="@+id/item_img"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/img_1"
            android:transitionName="SharedImage"
            />
        <TextView/>
    </LinearLayout>
</LinearLayout>

activity_target.xml
<LinearLayout>
    <LinearLayout>
        <TextView/>
    </LinearLayout>
    <LinearLayout>
        <TextView/>
        <ImageView
            android:id="@+id/target_shareImg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:transitionName="SharedImage"
            android:layout_marginLeft="24dp"
            android:layout_marginRight="24dp"
            android:src="@drawable/img_1"
            />
    </LinearLayout>
</LinearLayout>
第三步

跳轉(zhuǎn)指定頁(yè)面:

Intent intent = new Intent(MainActivity.this, TargetActivity.class);
//可添加一個(gè)或多個(gè)共享元素
Pair<View, String>[] pairs = new Pair[]{
        Pair.create(view.findViewById(R.id.item_img), "SharedImage")};
        Pair.create(view.findViewById(R.id.item_name), "SharedName")
ActivityOptionsCompat options = ActivityOptionsCompat
        .makeSceneTransitionAnimation(MainActivity.this, pairs);
startActivity(intent,options.toBundle());
第四步

結(jié)束頁(yè)面:

@Override
protected void onDestroy() {
    supportFinishAfterTransition();
    super.onDestroy();
}
效果

現(xiàn)在,你獲得的應(yīng)該是這樣的動(dòng)畫:


GIF.gif

可以看到,共享元素的效果是有了,但是除了共享元素,其他的視圖卻很死板地直接顯示出來(lái)了。共享元素要想有更好的感官體驗(yàn),應(yīng)該讓內(nèi)容后于共享元素顯示。因此,我們需要監(jiān)聽(tīng)共享元素的動(dòng)畫。

優(yōu)化

共享元素的 Transition使用的是內(nèi)部的默認(rèn)值,我們無(wú)法對(duì)這個(gè)對(duì)象進(jìn)行監(jiān)聽(tīng)。為此,我們自定義共享元素的動(dòng)畫來(lái)實(shí)現(xiàn)需要的效果。

從效果上看,默認(rèn)的Transition使用的應(yīng)該是ChangeBounds 。因此,我們直接使用ChangeBounds作為我們的切換動(dòng)畫。

ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(500);

changeBounds.addListener(new Transition.TransitionListener() {
    @Override
    public void onTransitionStart(Transition transition) {

    }

    @Override
    public void onTransitionEnd(Transition transition) {
        transition.removeListener(this);
        //開(kāi)始其他視圖的淡入動(dòng)畫
    }

    @Override
    public void onTransitionCancel(Transition transition) {

    }

    @Override
    public void onTransitionPause(Transition transition) {

    }

    @Override
    public void onTransitionResume(Transition transition) {

    }
});
getWindow().setSharedElementReturnTransition(changeBounds);
getWindow().setSharedElementEnterTransition(changeBounds);

其他視圖的動(dòng)畫,我這里就做一個(gè)簡(jiǎn)單的淡入的例子,先在 xml 文件中把視圖 alpha 值設(shè)置為 0,然后在共享元素動(dòng)畫結(jié)束后加入這樣的代碼:

TextView textview = (TextView) findViewById(R.id.target_content);
textview.animate().setDuration(1000).alpha(1f);

我們就可以得到這樣的效果:


GIF.gif

Fragment 中的共享元素


Fragment 中的 Transition 一樣,它們的屬性也都在 FragmentTransaction 中:

SharedElementFragment sharedElementFragment = SharedElementFragment.newInstance();

Slide slideTransition = new Slide(Gravity.RIGHT);
slideTransition.setDuration(500);

ChangeBounds changeBoundsTransition = new ChangeBounds();
changeBoundsTransition.setDuration(500);

sharedElementFragment.setEnterTransition(slideTransition);//進(jìn)入動(dòng)畫
sharedElementFragment.setSharedElementEnterTransition(changeBoundsTransition);//共享元素動(dòng)畫

getFragmentManager().beginTransaction()
        .replace(R.id.fragment_content, sharedElementFragment)
        .addToBackStack(null)
        .addSharedElement(sharedView, sharedName)
        .commit();

以上。

感謝:

Shared Element Activity Transition

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評(píng)論 25 708
  • 原文鏈接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影閱讀 33,172評(píng)論 6 472
  • 泥人 伴奏:天梯 歌類:填詞 說(shuō)明:非商用,伴奏無(wú)授權(quán),靈感來(lái)于短篇小說(shuō)《那個(gè)不為人知的故事》。 -制作組- 演唱...
    采山信仰閱讀 1,442評(píng)論 5 3
  • 前陣子有不少人反饋:呆總,我平時(shí)看了不少圖,但是做項(xiàng)目的時(shí)候沒(méi)辦法用上,怎么辦呀? 這類問(wèn)題我一般只會(huì)用一句話回答...
    UI設(shè)計(jì)學(xué)習(xí)閣閱讀 1,721評(píng)論 0 4
  • 地鐵里散發(fā)混合口腔氣味 泛著油光的臉龐 和粘在頭皮上的頭發(fā) 擁有著彼此 疲倦頂著呆滯的眼神 和低頭聚焦的屏幕 擁有...
    JoeyLQ閱讀 347評(píng)論 4 1

友情鏈接更多精彩內(nèi)容