【问题标题】:Fragment Animation like Gmail Honeycomb AppGmail Honeycomb App 之类的片段动画
【发布时间】:2011-11-12 11:04:08
【问题描述】:

如何重新创建您在 Android 3.0+ 上的 Gmail 应用中看到的布局动画效果

我知道你可以使用 PropertyAnimators、ObjectAnimators 等,但是在我的场景中,我在屏幕上有几个可以互换的片段,所以它们都包含在自己的 FrameLayouts 中,并且所有 FrameLayouts 都在一个相对布局。

我不知道如何更改 FrameLayouts 的宽度,因为您必须通过 LayoutParams 对象对其进行编辑。

有什么想法吗?

【问题讨论】:

  • 它们实际上并没有改变宽度。实际上是片段的位置发生了变化。
  • 好吧,他们把它移到了左边,但是片段或容器正在缩小,因为它变小了,为邮件内容腾出空间。
  • 实际上,如果您仔细观察,它们似乎并没有缩小任何东西。它们似乎有两个容纳碎片的“容器”。第一个容器包含文件夹列表片段和电子邮件列表片段。第二个容器包含电子邮件列表片段和电子邮件内容片段。当在第一个“容器”中单击一封电子邮件时,然后加载第二个“容器”。一些智能淡入淡出和滑动动画给它一种片段正在改变大小等的错觉。好吧,这只是我的看法我会怎么做:)

标签: android android-layout android-fragments android-animation


【解决方案1】:

我对此的看法可以查看on GitHub here

它演示了一种用动画隐藏片段的方法,就像 Gmail 所做的那样。

动画并不完美,因为左侧片段的移动速度略快于右侧片段。

隐藏的方法在代码中定义了动画,如下所示:

/**
 * Besides showing/hiding the left fragment, this method specifies that a
 * layout animation should be used. It is defined as a sliding animation.
 * The right fragment will use the default animation, which is a sliding
 * animation also.
 * 
 * If the left fragment's animation is removed from this method, the default
 * animation will be used which is a fading animation.
 * 
 * Please note that this method will only have an effect in those screen
 * configurations where the list is hideable; by default, a width between
 * 600 and 1024 dip which corresponds to a portrait view on tablets. Change
 * the boolean value in layout_constants.xml to allow for it in other screen
 * sizes.
 * 
 * @param visible
 */
protected void setLeftFragmentVisible(boolean visible) {
    if (leftFragment != null && (leftFragment.isVisible() || visible)
            && getResources().getBoolean(R.bool.leftHideable)) {
        final float listWidth = getLeftFragment().getView().getWidth();
        ViewGroup container = (ViewGroup) findViewById(R.id.dual_layout);
        // Don't clip the children, we want to draw the entire fragment even
        // if it is partially off-screen.
        container.setClipChildren(false);
        final LayoutTransition trans = container.getLayoutTransition();
        /**
         * This specifies the delay before the leftFragment will appear.
         * Change if you want the right fragment to move before.
         */
        trans.setStartDelay(LayoutTransition.APPEARING, 0);
        /**
         * This is the delay before the right fragment will start to occupy
         * the space left by the left fragment
         */
        trans.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100);

        /**
         * Adding, specifies that the left fragment should animate by
         * sliding into view.
         */
        ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "x",
                -listWidth, 0f).setDuration(
                trans.getDuration(LayoutTransition.CHANGE_APPEARING));
        trans.setAnimator(LayoutTransition.APPEARING, animIn);

        /**
         * Removing, specifies that the left fragment should animate by
         * sliding out of view.
         */
        ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "x", 0f,
                -listWidth).setDuration(
                trans.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
        trans.setAnimator(LayoutTransition.DISAPPEARING, animOut);

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        if (getLeftFragment().isVisible()) {
            fragmentTransaction.hide(getLeftFragment());
        } else {
            fragmentTransaction.show(getLeftFragment());
        }
        // The hiding/showing will automatically initiate the animations
        // since
        // we have specified that we want layout animations in the layout
        // xml
        fragmentTransaction.commit();

        /*
         * Display home as up to be able to view the list
         */
        getActionBar().setDisplayHomeAsUpEnabled(!visible);
    }
}

要完成这项工作,您需要定义您希望布局过渡具有动画效果。布局的 xml 结构顶部的一行将执行此操作:

android:animateLayoutChanges="true"

如果你不想要自定义动画,你可以删除 FragmentManager fragmentManager = getFragmentManager() 之前的所有内容。

现在在我的示例中,我使用了片段,但同样的原则应该适用于任何视图。

编辑:您应该使用布局权重来允许自动调整大小,而不是手动更改视图的宽度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多