Подтвердить что ты не робот

FloatingActionButton расширяется в новую деятельность

На странице принципов дизайна материалов для андроидов один из примеров показывает, что FAB расширяется в новый полноэкранный режим. (В разделе "Полный экран" )

http://www.google.com/design/spec/components/buttons-floating-action-button.html#buttons-floating-action-button-transitions

Я попытался реализовать тот же эффект в своем приложении, но с небольшим успехом.
Мне удалось создать FAB, который расширяется в виде, используя этот код в качестве ссылки: https://gist.github.com/chris95x8/882b5c5d0aa2096236ba.

Это сработало, но мне было интересно, могу ли я применить тот же эффект к переходу на активность. Я пробовал искать его и играть с ним сам, но не мог найти ничего, что могло бы сработать.

Я знаю, что я могу сделать FAB расширением Fragment, а не целым новым действием, но я не уверен, что это делается, и насколько это оптимально или нет.

И поэтому мой вопрос заключается в том, есть ли способ реализовать расширяющийся эффект раскрытия как переход активности, или он должен просто открыть новый фрагмент?

4b9b3361

Ответ 1

Я разрабатываю приложение, которое расширяет FloatingActionButton в новый Activity. Я не уверен, что если вам нравится моя реализация, но сначала посмотрите фотографии:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите здесь описание изображения

Итак, первое изображение показывает MainActivity, а в последнем показывает SecondActivity, который "расширен" из FAB.

Теперь я хочу упомянуть, что Я фактически не расширяю FAB в новый Activity, но я могу позволить пользователю почувствовать, что новая страница расширена из этого FAB, и я думаю это достаточно для разработчиков и пользователей.

Здесь реализация:

Приготовление:

  • A FloatingActionButton, конечно,
  • Посетите https://github.com/kyze8439690/RevealLayout и импортируйте эту библиотеку в свой проект. Он используется для воспроизведения анимации показа. У него есть пользовательский BakedBezierInterpolator для управления анимацией раскрытия и создания его в материальном стиле.

Шаги:

  • создайте файл activity_main.xml следующим образом:

    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <!--Your main content here-->
    
        <RevealLayout
            android:id="@+id/reveal_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="invisible">
    
            <View
                android:id="@+id/reveal_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:visibility="invisible"/>
    
        </RevealLayout>
    
    </FrameLayout>
    
  • find Просмотров:

    mRevealLayout = (RevealLayout) findViewById(R.id.reveal_layout);
    mRevealView = findViewById(R.id.reveal_view);
    
  • расширяется, когда пользователь нажимает кнопку FAB:

    mFab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mFab.setClickable(false); // Avoid naughty guys clicking FAB again and again...
            int[] location = new int[2];
            mFab.getLocationOnScreen(location);
            location[0] += mFab.getWidth() / 2;
            location[1] += mFab.getHeight() / 2;
    
            final Intent intent = new Intent(MainActivity.this, SecondActivity.class);
    
            mRevealView.setVisibility(View.VISIBLE);
            mRevealLayout.setVisibility(View.VISIBLE);
    
            mRevealLayout.show(location[0], location[1]); // Expand from center of FAB. Actually, it just plays reveal animation.
            mFab.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startActivity(intent);
                    /**
                     * Without using R.anim.hold, the screen will flash because of transition
                     * of Activities.
                     */
                    overridePendingTransition(0, R.anim.hold);
                }
            }, 600); // 600 is default duration of reveal animation in RevealLayout
            mFab.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mFab.setClickable(true);
                    mRevealLayout.setVisibility(View.INVISIBLE);
                    mViewToReveal.setVisibility(View.INVISIBLE);
                }
            }, 960); // Or some numbers larger than 600.
        }
    });
    

    И вот hold.xml в res/anim:

    <set
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shareInterpolator="false">
    
        <translate
            android:duration="960" <!-- Enough-large time is OK -->
            android:fromXDelta="0%"
            android:fromYDelta="0%"
            android:toXDelta="0%"
            android:toYDelta="0%"/>
    
    </set>
    

Что все.

<сильные > Улучшения:

  • RevealLayout имеет ошибку (играет прямоугольную форму вместо круговой анимации раскрытия) для устройств под API 17 (Android 4.2), вы можете добавить эти строки в свой конструктор:

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }
    
  • Если ваш SecondActivity содержит сложное содержимое, простой View, используемый как open_view в layout.xml, недостаточно/совершенен. Вы можете включить второй макет внутри RevealLayout show_layout. Кажется расточительным и трудно контролировать, если второй макет не будет отображаться одинаковым в каждый раз. Но для меня это будет. Таким образом, вы можете сделать другие улучшения, если хотите.

  • Если вы хотите реализовать полностью ту же анимацию, показанную в Руководстве по проектированию материалов, вы можете установить layout_height из RevealLayout в определенное число вместо match_parent. После расширения анимации (или через некоторое время после анимации, которая должна сделать весь процесс анимации плавно), вы можете оживить перевод. Важным моментом является просто обманывать пользователей визуально, контролируя продолжительность анимации.

Наконец, это мой собственный опыт/попытка, и я новичок в разработке приложений для Android. Если есть ошибки/дальнейшие улучшения, оставляйте комментарии/отредактируйте мой ответ. Спасибо.

Ответ 2

Я сделал индивидуальную деятельность на основе этого вопроса Циркулярный переход на новую активность, который обрабатывает CircularRevealAnimation и его обратный эффект, когда завершается работа:

public class RevealActivity extends AppCompatActivity {

private View revealView;

public static final String REVEAL_X="REVEAL_X";
public static final String REVEAL_Y="REVEAL_Y";

public void showRevealEffect(Bundle savedInstanceState, final View rootView) {

    revealView=rootView;

    if (savedInstanceState == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        rootView.setVisibility(View.INVISIBLE);

        ViewTreeObserver viewTreeObserver = rootView.getViewTreeObserver();

        if(viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {

                    circularRevealActivity(rootView);

                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        rootView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }

                }
            });
        }

    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void circularRevealActivity(View rootView) {

    int cx = getIntent().getIntExtra(REVEAL_X, 0);
    int cy = getIntent().getIntExtra(REVEAL_Y, 0);

    float finalRadius = Math.max(rootView.getWidth(), rootView.getHeight());

    // create the animator for this view (the start radius is zero)
    Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootView, cx, cy, 0, finalRadius);
    circularReveal.setDuration(400);

    // make the view visible and start the animation
    rootView.setVisibility(View.VISIBLE);
    circularReveal.start();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case android.R.id.home: onBackPressed();break;
return super.onOptionsItemSelected(item);

}    

}

@Override
public void onBackPressed() {
    destroyActivity(revealView);
}

private void destroyActivity(View rootView) {
    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP)
        destroyCircularRevealActivity(rootView);
    else
        finish();
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void destroyCircularRevealActivity(final View rootView) {
    int cx = getIntent().getIntExtra(REVEAL_X, 0);
    int cy = getIntent().getIntExtra(REVEAL_Y, 0);

    float finalRadius = Math.max(rootView.getWidth(), rootView.getHeight());

    // create the animator for this view (the start radius is zero)
    Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootView, cx, cy, finalRadius, 0);
    circularReveal.setDuration(400);

    circularReveal.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {

        }

        @Override
        public void onAnimationEnd(Animator animator) {
            rootView.setVisibility(View.INVISIBLE);
            finishAfterTransition();
        }

        @Override
        public void onAnimationCancel(Animator animator) {

        }

        @Override
        public void onAnimationRepeat(Animator animator) {

        }
    });

    // make the view visible and start the animation
    rootView.setVisibility(View.VISIBLE);
    circularReveal.start();
}
}

Вы можете расширить это с помощью своей собственной деятельности и вызвать в своем onCreate метод 'showRevealEffect' следующим образом:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_activity_layout);

    //your code

    View root= findViewById(R.id.your_root_id);
    showRevealEffect(savedInstanceState, root);

}

Вы также должны использовать прозрачную тему, подобную этой:

<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="colorControlNormal">@android:color/white</item>
</style>

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

int[] location = new int[2];

    fab.getLocationOnScreen(location);

    Intent intent = new Intent(this, YourRevealActivity.class);

    intent.putExtra(SearchActivity.REVEAL_X, location[0]);
    intent.putExtra(SearchActivity.REVEAL_Y, location[1]);

    startActivity(intent);

Ответ 3

Кто-то исследовал реализацию перехода между действиями из пледа. Ее пример был опубликован через https://github.com/hujiaweibujidao/FabDialogMorph.

Короче говоря, она проходит два вида деятельности:

  1. FAB как общий элемент.
  2. Макет в целевой деятельности имеет тот же android:transitionName что и FAB.
  3. Чтобы сгладить анимацию, MorphDrawable (расширенный от Drawable) и MorphTransition (расширенный от ChangeBounds) реализованы и применены.

Ответ 4

вы можете использовать этот lib [https://github.com/sergiocasero/RevealFAB][1]

[1]: https://github.com/sergiocasero/RevealFAB Сторонняя его простая и простая в использовании

Добавить в макет

<RelativeLayout...>

    <android.support.design.widget.CoordinatorLayout...>
        <!-- YOUR CONTENT -->
    </android.support.design.widget.CoordinatorLayout>

    <com.sergiocasero.revealfab.RevealFAB
        android:id="@+id/reveal_fab"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:fab_color="@color/colorAccent"
        app:fab_icon="@drawable/ic_add_white_24dp"
        app:reveal_color="@color/colorAccent" />
</RelativeLayout>

Важно: этот компонент находится над вашим контентом. Вы можете использовать Coordinator, LinearLayout... или другой Relative layout, если хотите:)

Как вы можете видеть, у вас есть 3 пользовательских атрибута для настройки цветов и значков

Настройка информации о намерении:

revealFAB = (RevealFAB) findViewById(R.id.reveal_fab);
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
revealFAB.setIntent(intent);

revealFAB.setOnClickListener(new RevealFAB.OnClickListener() {
    @Override
    public void onClick(RevealFAB button, View v) {
        button.startActivityWithAnimation();
    }
});

Не забудьте вызвать метод onResume()!

@Override
protected void onResume() {
    super.onResume();
    revealFAB.onResume();
}