为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

猛跑小猪 2020-02-03 14:45:59
我正在寻找一个完整的工作样本,该样本将被称为“ 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中的动画使我想拔头发,而那些看到我的人都知道这是徒劳的。
查看完整描述

3 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

在github上上传了我的建议 (尽管强烈建议将视图硬件加速用于这种动画,但它适用于所有android版本。对于非硬件加速的设备,位图缓存实现应该更合适)


带有动画的演示视频在此处(导致屏幕投放速度缓慢的帧率。实际性能非常快)


用法:


layout = new ThreeLayout(this, 3);

layout.setAnimationDuration(1000);

setContentView(layout);

layout.getLeftView();   //<---inflate FragmentA here

layout.getMiddleView(); //<---inflate FragmentB here

layout.getRightView();  //<---inflate FragmentC here


//Left Animation set

layout.startLeftAnimation();


//Right Animation set

layout.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_____]


查看完整回答
反对 回复 2020-02-03
  • 3 回答
  • 0 关注
  • 662 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信