[英]Animating the parent view without animating the child view
I would like to do something like this: https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4 我想做这样的事情: https : //storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4
I would like to squeeze a "ViewGroup" as you can see in the video. 如您在视频中所见,我想挤压一个“ ViewGroup”。 In the meantime, I want to fade out the content in the ViewGroup at its original position. 同时,我希望淡出ViewGroup中原始位置的内容。 ie not pushing the content to the right. 即不将内容推向右边。
Any idea how to implement this? 任何想法如何实现这一点?
Thanks! 谢谢!
You can do such animations with Transition API
. 您可以使用Transition API
制作此类动画。 Declare two ViewGroup
s: first one is horizontal with cut/copy buttons, second is vertical with search/share buttons. 声明两个ViewGroup
:第一个是水平的,具有剪切/复制按钮,第二个是垂直的,具有搜索/共享按钮。 Then switch these ViewGroup
s with TransitionManager
. 然后使用TransitionManager
切换这些ViewGroup
。 Then just provide Transition
which describes how views on first and second ViewGroup
s appears and disappers. 然后仅提供Transition
,该Transition
描述了第一个ViewGroup
和第二个ViewGroup
的视图如何显示和分配。
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.ChangeBounds;
import androidx.transition.Fade;
import androidx.transition.Scene;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
import androidx.transition.TransitionSet;
public class MainActivity extends AppCompatActivity {
private ViewGroup mSceneRoot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
mSceneRoot = findViewById(R.id.sceneRoot);
showPopup1();
}
private void showPopup1() {
ViewGroup popup1 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_1, mSceneRoot, false);
popup1.findViewById(R.id.btnGo).setOnClickListener(v -> {
showPopup2();
});
Scene scene = new Scene(mSceneRoot, popup1);
TransitionManager.go(scene, getTransition(false));
}
private void showPopup2() {
ViewGroup popup2 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_2, mSceneRoot, false);
popup2.findViewById(R.id.btnBack).setOnClickListener(v -> {
showPopup1();
});
Scene scene = new Scene(mSceneRoot, popup2);
TransitionManager.go(scene, getTransition(true));
}
}
activity_layout.xml activity_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sceneRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
android:orientation="vertical"
android:paddingBottom="150dp"
android:paddingRight="50dp"
android:clipToPadding="false"
android:clipChildren="false"/>
popup_1.xml popup_1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/popup1"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="@+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="go"
android:transitionName="btn_go"/>
</androidx.cardview.widget.CardView>
popup_2.xml popup_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/popup2"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="@+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="back"
android:transitionName="btn_back"/>
</androidx.cardview.widget.CardView>
Last thing here is getTransition
method. 这里的最后一件事是getTransition
方法。 You can just use AutoTransition , it can handle easy layout changes. 您可以只使用AutoTransition ,它可以处理简单的布局更改。
private Transition getTransition(boolean open) {
return new AutoTransition();
}
Result: 结果:
Also just for demostration I wrote more complex transition where button on first viewgroup appear/dissapear with Slide
animation. 同样为了演示,我编写了更复杂的过渡,其中第一个视图组上的按钮与Slide
动画一起出现/消失。
private Transition getTransition(boolean open) {
Slide btnGo = new Slide(Gravity.RIGHT);
btnGo.addTarget("btn_go");
ChangeBounds bgBounds = new ChangeBounds();
bgBounds.addTarget("bg");
Fade btnBack = new Fade();
btnBack.addTarget("btn_back");
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
if (open) {
set.addTransition(btnGo);
set.addTransition(bgBounds);
set.addTransition(btnBack);
} else {
set.addTransition(btnBack);
set.addTransition(bgBounds);
set.addTransition(btnGo);
}
return set;
}
Result: 结果:
Note that transitionName
for background should be same in both layouts. 请注意,两个布局中背景的transitionName
应该相同。 All transition classes here are from androix
package so code is backward compatible. 这里的所有过渡类都来自androix
包,因此代码向后兼容。 But if you need support pre Lollipop devices you should set transitionName
via ViewCompat.setTransitionName
method. 但是,如果您需要支持Lollipop之前的设备,则应通过ViewCompat.setTransitionName
方法设置transitionName
。
You can check my another answer with more difficult/custom transition. 您可以通过更困难的/自定义的过渡检查我的另一个答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.