猿问

Gmail三段式动画方案的完整工作示例?

我正在寻找一个完整的工作样本,该样本将被称为“ Gmail三段动画”方案。具体来说,我们想从两个片段开始,像这样:


两个碎片


在发生某些UI事件(例如,点击片段B中的某些内容)时,我们想要:


片段A从屏幕左侧滑出

片段B滑动到屏幕的左边缘并缩小以占据片段A空出的位置

片段C从屏幕右侧滑入并占据片段B空出的位置

并且,在按下“返回”按钮时,我们希望该组操作被逆转。


现在,我已经看到了很多部分实现。我将在下面回顾其中的四个。除了不完整之外,它们都有问题。


@Reto迈尔促成这种普遍的回答相同的基本问题,表明你会使用setCustomAnimations()一个FragmentTransaction。对于两个片段的场景(例如,您最初只看到片段A,并希望使用动画效果将其替换为新的片段B),我完全同意。然而:


由于您只能指定一个“入”和一个“出”动画,因此我看不到如何处理三片段场景所需的所有不同动画

在<objectAnimator>他的代码示例使用像素的硬连线的位置,这似乎给出不同的屏幕尺寸是不切实际的,但setCustomAnimations()需要动画资源,排除在Java中定义这些事情的可能性

我不知道比例缩放的对象动画制作器如何与诸如android:layout_weight按LinearLayout百分比分配空间的对象动画配合

我一开始就对片段C的处理方式不知所措(将GONE?android:layout_weight的0?预先设置为0的比例动画了吗?还有其他吗?)

@Roman Nurik指出,您可以为任何属性设置动画,包括您自己定义的属性。这可以帮助解决固定位置的问题,而以发明自己的自定义布局管理器子类为代价。这对某些人有所帮助,但是我仍然对Reto的其余解决方案感到困惑。


该pastebin条目的作者显示了一些诱人的伪代码,基本上是说所有三个片段最初都将驻留在容器中,而片段C首先通过hide()事务操作隐藏。然后我们在UI事件发生时使用show()C和hide()A。但是,我看不到如何处理B更改大小这一事实。它还依赖于一个事实,即您显然可以将多个片段添加到同一容器中,并且我不确定从长远来看这是否是可靠的行为(更不用说它应该破坏了findFragmentById(),尽管我可以忍受)。


这篇博文的作者指出,Gmail根本没有使用setCustomAnimations(),而是直接使用对象动画器(“您只需更改根视图的左边界+更改右视图的宽度”)。但是,这仍然是两段式解决方案AFAICT,实现再次显示了以像素为单位的硬接线尺寸。


我将继续解决这个问题,所以有一天我可能会自己回答,但我真的希望有人能为这个动画场景制定出三片段解决方案,并可以发布代码(或链接)。Android中的动画使我想拔头发,而那些看到我的人都知道这是徒劳的。


猛跑小猪
浏览 696回答 3
3回答

三国纷争

在github上上传了我的建议 (尽管强烈建议将视图硬件加速用于这种动画,但它适用于所有android版本。对于非硬件加速的设备,位图缓存实现应该更合适)带有动画的演示视频在此处(导致屏幕投放速度缓慢的帧率。实际性能非常快)用法:layout = new ThreeLayout(this, 3);layout.setAnimationDuration(1000);setContentView(layout);layout.getLeftView();&nbsp; &nbsp;//<---inflate FragmentA herelayout.getMiddleView(); //<---inflate FragmentB herelayout.getRightView();&nbsp; //<---inflate FragmentC here//Left Animation setlayout.startLeftAnimation();//Right Animation setlayout.startRightAnimation();//You can even set interpolators说明:创建了一个新的自定义RelativeLayout(ThreeLayout)和2个自定义动画(MyScalAnimation,MyTranslateAnimation)ThreeLayout假设其他可见视图具有,则以参数的形式获取左窗格的权重weight=1。因此,new ThreeLayout(context,3)创建一个具有3个子级的新视图,左侧窗格的总屏幕数为1/3。另一个视图占据了所有可用空间。它在运行时计算宽度,更安全的实现是在draw()中第一次计算尺寸。而不是post()缩放和平移动画实际上是调整视图的大小和移动视图,而不是伪[缩放,移动]。注意,fillAfter(true)任何地方都不会使用它。View2是view1的right_of和View3是view2的right_of设置了这些规则后,RelativeLayout会处理其他所有事情。动画改变了margins(移动中)和[width,height]比例要访问每个孩子(以便您可以用Fragment对其进行充气,可以调用public FrameLayout getLeftLayout() {}public FrameLayout getMiddleLayout() {}public FrameLayout getRightLayout() {}下面展示了2个动画阶段1--- IN屏幕----------!----- OUT ----[View1] [_____ View2 _____] [_____ View3_____]第二阶段--OUT-!-------- IN屏幕------[View1] [View2] [_____ View3_____]
随时随地看视频慕课网APP

相关分类

Android
我要回答