it-swarm.com.ru

Меню и автоматическое скрытие FloatingActionButton библиотеки Android Design Support

Я использую библиотеку поддержки дизайна Android и хочу, чтобы элемент FloatingActionButton имел функцию AutoHide by Scrolling, 

мой макет:

<Android.support.design.widget.CoordinatorLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <ScrollView
        Android:id="@+id/scrollView"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">


        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/LargeText" />
    </ScrollView>

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:layout_anchorGravity="bottom|right|end"
        app:layout_anchor="@id/scrollView"
        Android:src="@drawable/abc_btn_rating_star_off_mtrl_alpha" />

</Android.support.design.widget.CoordinatorLayout>

FloatingActionButton всегда отображается при прокрутке текста, я хочу автоматически скрывать его при прокрутке текста.

И я хочу иметь меню FloatingActionButton, нажав на FloatingActionButton, вот так:

enter image description here

9
AliSh

FloatingActionButton, у которого есть AutoHide by Scrolling,

Вы должны использовать Android.support.v4.widget.NestedScrollView вместо ScrollView. Вы не можете использовать ScrollView. Вы должны использовать NestedScrollView или представление, которое реализует интерфейс NestedScrollingChild, например, RecyclerView.

Для достижения такого типа шаблона вы должны реализовать свой собственный Behavior. Существует хороший код, опубликованный Googler, который скрывает FAB, когда пользователь прокручивает страницу вниз, и показывает его, когда он прокручивает назад. Повторно использует ту же анимацию, которую FloatingActionButton.Behavior использует для скрытия/отображения FAB в ответ на выход/вход AppBarLayout.

ОБНОВЛЕНО 18/07/2015

С помощью 22.2.1 вы можете просто добавить код, размещенный ниже, используя предварительно созданные анимации .... Просто используйте такой класс: (исходный код здесь )

public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
    public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
        super();
    }

    @Override
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                                       final View directTargetChild, final View target, final int nestedScrollAxes) {
        // Ensure we react to vertical scrolling
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                               final View target, final int dxConsumed, final int dyConsumed,
                               final int dxUnconsumed, final int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
            // User scrolled down and the FAB is currently visible -> hide the FAB
            child.hide();
        } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
            // User scrolled up and the FAB is currently not visible -> show the FAB
            child.show();
        }
    }
}

Затем вы можете применить это поведение к вашему FAB, используя:

<Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
     app:layout_behavior="com.support.Android.designlibdemo.ScrollAwareFABBehavior" />

С Design 22.2.0: Вы должны использовать такой класс: (исходный код здесь )

public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
    private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
    private boolean mIsAnimatingOut = false;

    public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
        super();
    }

    @Override
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                                       final View directTargetChild, final View target, final int nestedScrollAxes) {
        // Ensure we react to vertical scrolling
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                               final View target, final int dxConsumed, final int dyConsumed,
                               final int dxUnconsumed, final int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) {
            // User scrolled down and the FAB is currently visible -> hide the FAB
            animateOut(child);
        } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
            // User scrolled up and the FAB is currently not visible -> show the FAB
            animateIn(child);
        }
    }

    // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
    private void animateOut(final FloatingActionButton button) {
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer()
                    .setListener(new ViewPropertyAnimatorListener() {
                        public void onAnimationStart(View view) {
                            ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
                        }

                        public void onAnimationCancel(View view) {
                            ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                        }

                        public void onAnimationEnd(View view) {
                            ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                            view.setVisibility(View.GONE);
                        }
                    }).start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out);
            anim.setInterpolator(INTERPOLATOR);
            anim.setDuration(200L);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
                }

                public void onAnimationEnd(Animation animation) {
                    ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                    button.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationRepeat(final Animation animation) {
                }
            });
            button.startAnimation(anim);
        }
    }

    // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
    private void animateIn(FloatingActionButton button) {
        button.setVisibility(View.VISIBLE);
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F)
                    .setInterpolator(INTERPOLATOR).withLayer().setListener(null)
                    .start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in);
            anim.setDuration(200L);
            anim.setInterpolator(INTERPOLATOR);
            button.startAnimation(anim);
        }
    }
}

Затем вы можете применить это поведение к вашему FAB, используя:

<Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
     app:layout_behavior="com.support.Android.designlibdemo.ScrollAwareFABBehavior" />

Конечно, вы можете изменить этот код, чтобы получить ваш любимый шаблон.

И я хочу иметь меню FloatingActionButton, нажав на FloatingActionButton, вот так:

В настоящее время оригинальный FAB не поддерживает этот шаблон. Вы должны реализовать собственный код для достижения этого.

31
Gabriele Mariotti

Вы можете достичь этого 

Вот мой код 

Шаг 1:

Сначала сделайте Getter из FloatingActionMenu, чтобы вы могли вызывать его из другого действия или из фрагмента, где используется ваше повторное представление

public FloatingActionMenu getFloatingActionMenu() {
        return fabMenu;
    }

Шаг 2:

Позвоните ниже линии из другого действия или из фрагмента 

   FloatingActionMenu fabMenu=((MainActivity)getActivity()).getFloatingActionMenu();

Шаг 3:

Теперь проверьте, прокручивается ли перезапуск или не зависит от позиции "dy" Здесь я использовал анимацию fabMenu 

Animation FabMenu_fadOut = AnimationUtils.loadAnimation(getActivity(),
            R.anim.fade_out);
Animation  FabMenu_fadIn = AnimationUtils.loadAnimation(getActivity(),
            R.anim.abc_grow_fade_in);

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0 && floatingActionButton.isShown()) {
                    //fabMenu.startAnimation(FabMenu_fadIn);
                    fabMenu.setVisibility(View.GONE);
                }
                if (dy < 0 && !floatingActionButton.isShown()) {
                   // fabMenu.startAnimation(FabMenu_fadOut);
                    fabMenu.setVisibility(View.VISIBLE);
                }
            }
        });

Примечание. Если вы хотите скрыть FloatingActionButton при прокрутке, используйте тот же код, что и в FloatingActionMenu.

Спасибо.

1
Ulearn

Вы можете реализовать плавающее меню действий, используя это .

Что касается анимации для плавающего меню действий, вы можете создать класс с именем ScrollAwareFloatingActionMenuBehaviour:

public class ScrollAwareFloatingActionMenuBehaviour extends CoordinatorLayout.Behavior<FloatingActionsMenu> {
    private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
    private boolean mIsAnimatingOut = false;
    private boolean mIsAnimatingIn = false;

    public ScrollAwareFloatingActionMenuBehaviour(Context context, AttributeSet attrs) {
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) {
        float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
        child.setTranslationY(translationY);
        return true;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
                                       FloatingActionsMenu child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
                super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target,
                        nestedScrollAxes);
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionsMenu child,
                               View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,
                dyUnconsumed);

        if (dyConsumed > 10 && !this.mIsAnimatingOut && !this.mIsAnimatingIn && child.getVisibility() == View.VISIBLE) {
            // User scrolled down and the FAB is currently visible -> hide the FAB
            animateOut(child);
        } else if (dyConsumed < -10 && !this.mIsAnimatingOut && !this.mIsAnimatingIn && child.getVisibility() != View.VISIBLE) {
            // User scrolled up and the FAB is currently not visible -> show the FAB
            animateIn(child);
        }
    }

    // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
    private void animateOut(final FloatingActionsMenu button) {
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).translationYBy(200F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer()
                    .setListener(new ViewPropertyAnimatorListener() {
                        public void onAnimationStart(View view) {
                            ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = true;
                        }

                        public void onAnimationCancel(View view) {
                            ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false;
                        }

                        public void onAnimationEnd(View view) {
                            ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false;
                            view.setVisibility(View.GONE);
                        }
                    }).start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.design_fab_out);
            anim.setInterpolator(INTERPOLATOR);
            anim.setDuration(200L);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = true;
                }

                public void onAnimationEnd(Animation animation) {
                    ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false;
                    button.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationRepeat(final Animation animation) {
                }
            });
            button.startAnimation(anim);
        }
    }

    // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
    private void animateIn(FloatingActionsMenu button) {
        button.setVisibility(View.VISIBLE);
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).translationYBy(-200F).alpha(1.0F)
                    .setInterpolator(INTERPOLATOR).withLayer().setListener(new ViewPropertyAnimatorListener() {
                @Override
                public void onAnimationStart(View view) {
                    ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = true;

                }

                @Override
                public void onAnimationEnd(View view) {
                    ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = false;

                }

                @Override
                public void onAnimationCancel(View view) {
                    ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = false;

                }
            })
                    .start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), Android.support.design.R.anim.design_fab_in);
            anim.setDuration(200L);
            anim.setInterpolator(INTERPOLATOR);
            button.startAnimation(anim);
        }
    }
}

Обратите внимание, что R.anim.fab_in и R.anim.fab_out заменены на R.anim.design_fab_in и R.anim.design_fab_out соответственно.

Используйте это в xml:

<com.getbase.floatingactionbutton.FloatingActionsMenu
        xmlns:fab="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/fab_menu"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="end|bottom"
        Android:layout_margin="@dimen/fab_margin"
        fab:fab_addButtonColorNormal="@color/colorAccent"
        fab:fab_addButtonColorPressed="@color/colorAccentLight"
        fab:fab_addButtonPlusIconColor="@Android:color/white"
        app:layout_behavior="com.example.widgets.behaviour.ScrollAwareFloatingActionMenuBehaviour"
        fab:fab_labelStyle="@style/menu_labels_style"
        fab:fab_labelsPosition="left">

        <com.getbase.floatingactionbutton.FloatingActionButton
            Android:id="@+id/fab_share"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            fab:fab_colorNormal="@color/fab_normal_blue"
            fab:fab_colorPressed="@color/fab_normal_blue_pressed"
            fab:fab_icon="@drawable/ic_social_share"
            fab:fab_title="@string/fab_menu_group_chat" />

</com.getbase.floatingactionbutton.FloatingActionsMenu>
0
Noel Chew