ViewGroups 的一个 Animate Layout 属性是如何实现的?
我有以下布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout android:id="@+id/viewgroup_left"
android:layout_height="match_parent"
android:layout_weight="2"
android:layout_width="0dp">
... children ...
</FrameLayout>
<LinearLayout android:id="@+id/viewgroup_right"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dp"
android:orientation="vertical">
... children ...
</LinearLayout>
</LinearLayout>
我最终得到这样的结果:
+------------------------+------------+
| | |
| | |
| Left | Right |
| | |
| | |
+------------------------+------------+
当切换某个开关时,我想为“Left”设置动画,以便其宽度扩展以填充整个屏幕。同时,我想对 Right 的宽度进行动画处理,使其缩小到零。稍后,当再次切换切换时,我需要将事物恢复到上述状态。
我尝试编写自己的动画来调用 View.getWidth()
但当我动画回到该值时(通过设置 View.getLayoutParams().width
),它是比开始时更宽。我怀疑我只是做错了。我还阅读了有关蜂窝动画内容的所有文档,但我不想翻译或缩放...我想对布局宽度属性进行动画处理。我找不到这方面的例子。
这样做的正确方法是什么?
I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout android:id="@+id/viewgroup_left"
android:layout_height="match_parent"
android:layout_weight="2"
android:layout_width="0dp">
... children ...
</FrameLayout>
<LinearLayout android:id="@+id/viewgroup_right"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dp"
android:orientation="vertical">
... children ...
</LinearLayout>
</LinearLayout>
I end up with something like this:
+------------------------+------------+
| | |
| | |
| Left | Right |
| | |
| | |
+------------------------+------------+
When a certain toggle is toggled, I want to animate Left so that its width expands to fill the entire screen. At the same time, I would like to animate the width of Right so that it shrinks to zero. Later, when the toggle is toggled again, I need to restore things to the above state.
I've tried writing my own Animation that calls View.getWidth()
but when I animate back to that value (by setting View.getLayoutParams().width
) it is wider than when it began. I suspect I'm just doing it wrong. I have also read all the documentation on the Honeycomb animation stuff, but I don't want to translate or scale... I want to animate the layout width property. I can't find an example of this.
What is the correct way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于还没人帮助你,而且我的第一个答案是如此混乱,所以这次我会尽力给你正确的答案;-)
实际上我喜欢这个想法,我认为这是一个很棒的视觉效果,可能对很多人有用人们。我会实现右视图的溢出(我认为缩小看起来很奇怪,因为文本扩展到底部)。
但无论如何,这里的代码运行得很好(您甚至可以在动画播放时进行切换)。
快速解释:
您可以使用布尔值来调用
toggle
作为您的方向,这将启动处理程序动画调用循环。这将根据方向和过去的时间增加或减少两个视图的权重(以实现平滑的计算和动画)。只要动画调用循环尚未到达开始或结束位置,它就会调用自身。布局:
活动:
Since noone helped you yet and my first answer was such a mess I'll try to give you the right answer this time ;-)
Actually I like the idea and I think this is a great visual effect which might be useful for a bunch of people. I would implement an overflow of the right view (I think the shrink looks strange since the text is expanding to the bottom).
But anyway, here's the code which works perfectly fine (you can even toggle while it's animating).
Quick explanation:
You call
toggle
with a boolean for your direction and this will start a handler animation call loop. This will increase or decrease the weights of both views based on the direction and the past time (for a smooth calculation and animation). The animation call loop will invoke itself as long it hasn't reached the start or end position.The layout:
The activity:
只是将我的 2 美分添加到 Knickedi 的出色答案中 - 以防万一有人需要它:
如果您使用权重进行动画制作,您最终会遇到包含视图和视图组的裁剪/非裁剪问题。如果您使用具有权重的视图组作为片段容器,则尤其如此。为了克服这个问题,您可能还需要对有问题的子视图和视图组/片段容器的边距进行动画处理。
而且,要一起完成所有这些事情,最好选择 ObjectAnimator 和 AnimatorSet(如果可以使用它们),以及一些实用程序类,例如
Just adding my 2 cents here to Knickedi's excellent answer - just in case someone needs it:
If you animate using weights you will end up with issues with clipping/non-clipping on contained views and viewgroups. This is especially true if you use viewgroups with weight as fragment containers. To overcome it, you might as well need to animate margins of the problematic child views and viewgroups / fragment containers.
And, to do all these things together, its always better to go for ObjectAnimator and AnimatorSet (if you can use them), along with some utility classes like MarginProxy
@knickedi 发布的解决方案的另一种方法是使用 ObjectAnimator 而不是 Runnable。这个想法是使用ObjectAnimator来调整左视图和右视图的权重。但是,需要自定义视图,以便可以将权重公开为 ObjectAnimator 进行动画处理的属性。
首先,定义一个自定义视图(以 LinearLayout 为例):
然后,更新布局 XML 以使用此自定义线性布局。
然后,当您需要切换动画时,请使用 ObjectAnimator:
上面的代码假设两个视图都是线性布局,并且一开始的权重都是一半。动画会将右侧视图扩展到最大(因此左侧视图被隐藏)。请注意,ObjectAnimator 使用自定义线性布局的“MyWeight”属性进行动画处理。 AnimatorSet 用于将左右 ObjectAnimators 连接在一起,因此动画看起来很流畅。
这种方法减少了编写可运行代码及其内部权重计算的需要,但需要定义自定义的类。
A different way to the solution posted by @knickedi is to use ObjectAnimator instead of Runnable. The idea is to use ObjectAnimator to adjust the weight of both left and right views. The views, however, need to be customised so that the weight can be exposed as a property for the ObjectAnimator to animate.
So first, define a customised view (using a LinearLayout as an example):
Then, update the layout XML to use this custom linear layout.
Then, when you need to toggle the animation, use ObjectAnimator:
The above code assumes both views are linear layout and are half in weight to start with. The animation will expand the right view to full weight (so the left one is hidden). Note that ObjectAnimator is animated using the "MyWeight" property of the customised linear layout. The AnimatorSet is used to tie both left and right ObjectAnimators together, so the animation looks smooth.
This approach reduces the need to write runnable code and the weight calculation inside it, but it needs a customised class to be defined.