我打算在我的一个项目中实现类似的东西,但我不清楚以下概念,也没有这样的教程,而且你不能看到这个经常。以下是Click here to go to source
的外观
从我所理解的所有参考资料中,他们在这里使用了两种类型的过渡,一种是将按钮移动到一些现存的按钮,另一种是用于触发按钮。所以我做了一些挖掘并在
github
中遇到了这两个库我觉得用这两个我们可以实现以下动画这里是链接
Material Animations(移动按钮)和 Circular reveal(使按钮看起来像爆炸)
如果您找到以下更好的答案,请在此处发布
答案 0 :(得分:4)
我认为您正在寻找的是有意义的过渡。
在棒棒糖前设备中,可以使用ActivityOptionsCompat
帮助器来实现。
一些可能对您有用的有用链接:
答案 1 :(得分:4)
问题很老,但是仍然很有趣。我就是这样实现的:
首先,您需要创建两个ViewGroups
,它们在过渡api中称为“场景”。第一个场景包含过渡之前的视图,第二个场景包含过渡之后的视图。然后,您应该只用第二个场景替换第一个场景,并提供Transition
来描述第一个场景的视图如何进入第二个场景,第一个场景的视图如何消失以及第二个场景的视图如何出现。
在此示例中,无法使用fab按钮,因为这是唯一一个在“场景根”屏幕的白色区域之外进行动画处理的视图。这就是为什么场景全屏显示,其顶部空白等于蓝色“星期一”标题的高度。
此处所有的过渡都是默认的,除了黄色背景过渡。黄色 背景视图出现在第二个场景中,并带有圆形揭示动画。并以圆形显示崩溃动画消失。没有这样的默认动画,这就是为什么我编写自定义动画的原因:
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.support.transition.TransitionValues;
import android.support.transition.Visibility;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
public class CircularRevealTransition extends Visibility {
@Override
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
int startRadius = 0;
int endRadius = (int) Math.hypot(view.getWidth(), view.getHeight());
Animator reveal = ViewAnimationUtils.createCircularReveal(view, view.getWidth() / 2, view.getHeight() / 2, startRadius, endRadius);
//make view invisible until animation actually starts
view.setAlpha(0);
reveal.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
view.setAlpha(1);
}
});
return reveal;
}
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
int endRadius = 0;
int startRadius = (int) Math.hypot(view.getWidth(), view.getHeight());
Animator reveal = ViewAnimationUtils.createCircularReveal(view, view.getWidth() / 2, view.getHeight() / 2, startRadius, endRadius);
return reveal;
}
}
完整代码在这里:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.transition.ArcMotion;
import android.support.transition.ChangeBounds;
import android.support.transition.Fade;
import android.support.transition.Scene;
import android.support.transition.Slide;
import android.support.transition.Transition;
import android.support.transition.TransitionListenerAdapter;
import android.support.transition.TransitionManager;
import android.support.transition.TransitionSet;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends AppCompatActivity {
private ViewGroup mSceneRoot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setSupportActionBar(findViewById(R.id.toolbar));
mSceneRoot = findViewById(R.id.sceneRoot);
//show scene1 without animation
showScene1(false);
}
private void showScene1(boolean animated) {
ViewGroup root = (ViewGroup) getLayoutInflater().inflate(R.layout.scene1, null);
FloatingActionButton fab = root.findViewById(R.id.fab);
fab.setOnClickListener(v -> {
showScene2();
});
Scene scene = new Scene(mSceneRoot, root);
Transition transition = animated ? getScene1Transition() : null;
TransitionManager.go(scene, transition);
}
private void showScene2() {
ViewGroup root = (ViewGroup) getLayoutInflater().inflate(R.layout.scene2, null);
View btnBack = root.findViewById(R.id.btnCancel);
btnBack.setOnClickListener(v -> {
showScene1(true);
});
Scene scene = new Scene(mSceneRoot, root);
Transition transition = getScene2Transition();
TransitionManager.go(scene, transition);
}
private Transition getScene2Transition() {
TransitionSet set = new TransitionSet();
//fab changes position
ChangeBounds changeTransform = new ChangeBounds();
changeTransform.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(@NonNull Transition transition) {
//hide fab button on the end of animation
mSceneRoot.findViewById(R.id.fab).setVisibility(View.INVISIBLE);
}
});
changeTransform.addTarget(R.id.fab);
changeTransform.setDuration(300);
//fab arc path
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMaximumAngle(45);
arcMotion.setMinimumHorizontalAngle(90);
arcMotion.setMinimumVerticalAngle(0);
changeTransform.setPathMotion(arcMotion);
set.addTransition(changeTransform);
//bg circular reveal animation starts
CircularRevealTransition crt = new CircularRevealTransition();
crt.addTarget(R.id.yellowBG);
crt.setStartDelay(200);
crt.setDuration(600);
set.addTransition(crt);
//buttons appear
Fade fade = new Fade();
fade.addTarget(R.id.btnBegin);
fade.addTarget(R.id.btnCancel);
fade.addTarget(R.id.text);
fade.setStartDelay(600);
set.addTransition(fade);
//left buttons column slide to left
Slide slide = new Slide(Gravity.LEFT);
slide.addTarget(R.id.slideLeftContainer);
set.addTransition(slide);
//right buttons column slide to right
Slide slide2 = new Slide(Gravity.RIGHT);
slide2.addTarget(R.id.slideRightContainer);
set.addTransition(slide2);
return set;
}
private Transition getScene1Transition() {
TransitionSet set = new TransitionSet();
//buttons from scene2 fade out
Fade fade = new Fade();
fade.addTarget(R.id.btnBegin);
fade.addTarget(R.id.btnCancel);
fade.addTarget(R.id.text);
set.addTransition(fade);
//Circular Reveal collapse animation starts
CircularRevealTransition crt = new CircularRevealTransition();
crt.addTarget(R.id.yellowBG);
crt.setDuration(600);
set.addTransition(crt);
//then fab button changes position
ChangeBounds changeTransform = new ChangeBounds();
changeTransform.addTarget(R.id.fab);
changeTransform.setDuration(300);
changeTransform.setStartDelay(500);
//arc path
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMaximumAngle(45);
arcMotion.setMinimumHorizontalAngle(90);
arcMotion.setMinimumVerticalAngle(0);
changeTransform.setPathMotion(arcMotion);
set.addTransition(changeTransform);
//left buttons column slide in from left
Slide slide = new Slide(Gravity.LEFT);
slide.addTarget(R.id.slideLeftContainer);
slide.setStartDelay(500);
set.addTransition(slide);
//right buttons column slide in from right
Slide slide2 = new Slide(Gravity.RIGHT);
slide2.addTarget(R.id.slideRightContainer);
slide2.setStartDelay(500);
set.addTransition(slide2);
return set;
}
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:titleTextColor="#fff" />
<FrameLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:background="#00BCD4"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<TextView
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_gravity="bottom"
android:background="#9000"
android:gravity="center_vertical"
android:paddingLeft="8dp"
android:text="MONDAY"
android:textColor="#fff" />
</FrameLayout>
<FrameLayout
android:id="@+id/sceneRoot"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
</android.support.constraint.ConstraintLayout>
scene1.xml
:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/slideLeftContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/header_height"
android:orientation="vertical">
<include layout="@layout/button" />
<include layout="@layout/button" />
<include layout="@layout/button" />
</LinearLayout>
<LinearLayout
android:id="@+id/slideRightContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_marginTop="@dimen/header_height"
android:orientation="vertical">
<include layout="@layout/button" />
<include layout="@layout/button" />
<include layout="@layout/button" />
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="@dimen/fab_margin_top"
android:layout_marginRight="@dimen/fab_margin"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#FFEE4D"
app:srcCompat="@drawable/ic_add_black_24dp" />
</FrameLayout>
scene2.xml
:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="@dimen/header_height">
<View
android:id="@+id/yellowBG"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFEE4D" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="#FFEE4D"
app:srcCompat="@drawable/ic_add_black_24dp" />
<Button
android:id="@+id/btnBegin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left"
android:layout_margin="@dimen/fab_margin"
android:padding="16dp"
android:text="BEGIN"
android:textSize="22sp" />
<TextView
android:id="@+id/text"
android:layout_width="@dimen/header_height"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt"
android:textSize="22sp" />
<Button
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/fab_margin"
android:backgroundTint="#FF5151"
android:padding="16dp"
android:text="CANCEL"
android:textSize="22sp" />
</FrameLayout>
button.xml
:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:padding="24dp"
android:text="6:30"
android:textSize="24sp" />
values.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestTransition</string>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<dimen name="fab_margin">16dp</dimen>
<dimen name="header_height">200dp</dimen>
<dimen name="fab_margin_top">132dp</dimen>
</resources>