Material-Animations 学习二(共享控件的简单实用)---微博share客户端的头像移动效果

Activity间共享元素

Activity间共享元素的本质是有两个不同的View在不同的布局(Activity),然后通过某种方式把它们连起来,然后做动画。

Transition framework将会执行从一个View到另外一个View的过渡动画。

有一点需要注意的是:view不是从一个Activity 转移到另外一个Activity中,他们是完全独立的两个View 
这里写图片描述

a)允许Window Content Transition

如果想实现Activity间共享元素,那么需要在appstyles.xml文件中配置。

values/styles.xml

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="android:windowContentTransitions">true</item
    ...
</style>
  • 1
  • 2
  • 3
  • 4
  • 5

同时在这里可以为整个app配置缺省的enter,exitshared element transitions

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">
    ...
    <!-- specify enter and exit transitions -->
    <item name="android:windowEnterTransition">@transition/explode</item>
    <item name="android:windowExitTransition">@transition/explode</item>

    <!-- specify shared element transitions -->
    <item name="android:windowSharedElementEnterTransition">@transition/changebounds</item>
    <item name="android:windowSharedElementExitTransition">@transition/changebounds</item>
    ...
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(自我补充)重点:@transition/changebounds的实现:

在translation中定义xml文件

内容如下:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds android:interpolator="@android:interpolator/accelerate_decelerate"
        />
</transitionSet>

b)定义一个相同的过渡名字(transition name)

实现Activity间共享元素,需要给源View和目标View设置相同的 
android:transitionName,他们的其他的属性可以不同,但唯独android:transitionName必须相同。

layout/activity_a.xml

<ImageView
        android:id="@+id/small_blue_icon"
        style="@style/MaterialAnimations.Icon.Small"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
  • 1
  • 2
  • 3
  • 4
  • 5

layout/activity_b.xml

<ImageView
        android:id="@+id/big_blue_icon"
        style="@style/MaterialAnimations.Icon.Big"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
  • 1
  • 2
  • 3
  • 4
  • 5

c) 使用共享元素启动Activity

使用ActivityOptions.makeSceneTransitionAnimation()方法定义共享元素源View和过渡的名字transitionName

MainActivity.java

blueIconImageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent i = new Intent(MainActivity.this, SharedElementActivity.class);

        View sharedView = blueIconImageView;
        String transitionName = getString(R.string.blue_name);

        ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName);
        startActivity(i, transitionActivityOptions.toBundle());
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

经过三面几步,漂亮的过渡动画就完成了。 
这里写图片描述

如上面所示,Transition framework创建并执行动画,而这些动画使我们感到错觉,认为这个View是从一个Activity一边改变形状一边移动到另外一个Activity

Fragment间共享元素

Fragment间共享元素和Activity间共享元素非常相像,步骤a)和步骤b)一样,只是步骤c)改变。

a)允许Window Content Transition

values/styles.xml

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="android:windowContentTransitions">true</item>
    ...
</style>
  • 1
  • 2
  • 3
  • 4
  • 5

b)定义一个相同的过渡名字(transition name)

layout/fragment_a.xml

<ImageView
        android:id="@+id/small_blue_icon"
        style="@style/MaterialAnimations.Icon.Small"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
  • 1
  • 2
  • 3
  • 4
  • 5

layout/fragment_b.xml

<ImageView
        android:id="@+id/big_blue_icon"
        style="@style/MaterialAnimations.Icon.Big"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
  • 1
  • 2
  • 3
  • 4
  • 5

c) 使用共享元素启动Fragment

FragmentB fragmentB = FragmentB.newInstance(sample);

// Defines enter transition for all fragment views
Slide slideTransition = new Slide(Gravity.RIGHT);
slideTransition.setDuration(1000);
sharedElementFragment2.setEnterTransition(slideTransition);

// Defines enter transition only for shared element
ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);
fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

getFragmentManager().beginTransaction()
        .replace(R.id.content, fragmentB)
        .addSharedElement(blueView, getString(R.string.blue_name))
        .commit();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

最终的结果 
这里写图片描述

允许重叠过渡


(补充)activity1退出的时候有两种情况

1.退出时同时执行activity2的进入

2.在activity1完全退出之后再执行activity2的进入


你可以定义进入(enter transitions)和退出(exit transition)的过渡动画是否互相重叠。 

根据 Android官方文档

如果设置为Ture,enter transition将会立即执行 
如果设置为False,enter transition将等到exit transition完全执行完毕才开始执行

上面的设置对于FragmentActivity一样有效

FragmentB fragmentB = FragmentB.newInstance(sample);

// Defines enter transition for all fragment views
Slide slideTransition = new Slide(Gravity.RIGHT);
slideTransition.setDuration(1000);
sharedElementFragment2.setEnterTransition(slideTransition);

// Defines enter transition only for shared element
ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);
fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

// Prevent transitions for overlapping
fragmentB.setAllowEnterTransitionOverlap(overlap);
fragmentB.setAllowReturnTransitionOverlap(overlap);

getFragmentManager().beginTransaction()
        .replace(R.id.content, fragmentB)
        .addSharedElement(blueView, getString(R.string.blue_name))
        .commit();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

我们能很容易的发现两者的不同

允许覆盖不允许覆盖
Fragment_2 出现在Fragment_1顶部直到Fragment_1 消失,Fragment_2才出现
这里写图片描述这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值