Фрагмент анимации, такой как приложение Gmail Honeycomb - PullRequest
3 голосов
/ 07 сентября 2011

Как воссоздать макет анимации, который вы видите в приложении Gmail на Android 3.0 +

Я знаю, что вы можете использовать PropertyAnimators, ObjectAnimators и т. Д., Но в моем сценарии у меня есть несколько фрагментов на экране, которые можно поменять местами, поэтому они все содержатся в своих собственных FrameLayouts, и все FrameLayouts находятся RelativeLayout.

Я не могу понять, как изменить ширину FrameLayouts, так как вы должны редактировать это через объект LayoutParams.

Есть идеи?

1 Ответ

0 голосов
/ 20 марта 2012

Мой взгляд на это можно посмотреть на GitHub здесь

Он демонстрирует один из способов скрыть фрагмент с анимацией, как это делает 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 fragManager = getFragmentManager ().

Теперь в моем примере я использую фрагменты, но тот же принцип должен применяться к любому представлению.

Редактировать: Вместо того, чтобы изменять ширину ваших видов вручную, вы должны вместо этого использовать веса макета, чтобы разрешить автоматическое изменение размера.

...