Кнопка должна действовать как FAB, когда отображается SnackBar

Чего я хочу добиться, так это иметь Button контейнер в CoordinatorLayout

android.support.design.widget.CoordinatorLayout
android.widget.button

который реагирует на SnackBar как FloatingActionButton,
Тот использует FloatingActionButton,
Поведение, которое распространяется CoordinatorLayout.Behavior<FloatingActionButton>,

Должен ли я сам определять пользовательское поведение или есть какие-то общие компоненты, которые реагируют одинаково?

1 ответ

Решение

Вы можете определить свой собственный макет и пользовательский CoordinatorLayout.Behavior
Вы можете клонировать FloatingActionButton состав.

Что-то вроде:

    @CoordinatorLayout.DefaultBehavior(ButtonLayout.Behavior.class)
    public class ButtonLayout extends LinearLayout {


       public static class Behavior extends 
            android.support.design.widget.CoordinatorLayout.Behavior<ButtonLayout> {

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

            public boolean onDependentViewChanged(CoordinatorLayout parent, ButtonLayout child, View dependency) {
               if(dependency instanceof Snackbar.SnackbarLayout) {
                  this.updateFabTranslationForSnackbar(parent, child, dependency);
               } 
               return false;
            }

            private void updateFabTranslationForSnackbar(CoordinatorLayout parent, ButtonLayout fab, View snackbar) {
               //copy from FloatingActionButton.Behavior
            }

       }

    }

Вы должны создать свой собственный CoordinatorLayout.Behavior

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar

class SnackbarAwareBehaviour(context: Context, attrs: AttributeSet)
    : CoordinatorLayout.Behavior<View>(context, attrs) {

    override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
        return dependency is Snackbar.SnackbarLayout
    }

    override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
        child.translationY = Math.min(0f, dependency.translationY - dependency.height)
        return true
    }

    override fun onDependentViewRemoved(parent: CoordinatorLayout, child: View, dependency: View) {
        child.translationY = 0f
    }
}

и вы должны назначить это поведение любому прямому дочернему представлению CoordinatorLayout, используя один из следующих двух методов

1- Используя layout_behavior обычай CoordinatorLayout атрибут

<androidx.coordinatorlayout.widget.CoordinatorLayout
     ...>

    ...

    <!-- The view which has the Behaviour should be a direct child to the CoordinatorLayout -->
    <Button
       ...
       app:layout_behavior="my.package.SnackbarAwareBehaviour"
       />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

2 - Или вы также можете назначить поведение своему собственному пользовательскому представлению, реализовав интерфейс CoordinatorLayout.AttachedBehavior

class MyButton(context: Context, attrs: AttributeSet?)
    : Button(context, attrs), CoordinatorLayout.AttachedBehavior {
   ...
   override fun getBehavior(): CoordinatorLayout.Behavior<*> {
      return SnackbarAwareBehaviour(context, null)
   }
}