android 如果在CoordinatorLayout中设置了anchorView,则浮动操作按钮不随快餐栏浮动

oogrdqng  于 2022-12-28  发布在  Android
关注(0)|答案(1)|浏览(159)

当我设置snackbar.anchorView = adContainer时,我的FAB没有浮动。

val snackbar = Snackbar.make(main_content, "Item Deleted", Snackbar.LENGTH_INDEFINITE)
        snackbar.anchorView = adContainer
        snackbar.setAction("Dismiss"){

        }
        snackbar.show()

如果我不设置锚视图,它可以正常浮动。
问题-如果我将snackbar锚视图设置为adContainer,如何让FAB上下浮动?
snackbar with anchorview set
snackbar without anchorview
我的XML文件-

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/rootConstraintLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Show Snackbar"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/adContainer"
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:layout_marginStart="1dp"
            android:layout_marginTop="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginBottom="1dp"
            android:background="#F44336"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_marginBottom="96dp"
        android:layout_marginEnd="32dp"
        android:clickable="true"
        app:layout_anchorGravity="end|bottom"
        app:srcCompat="@android:drawable/ic_input_add"
        android:focusable="true" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

感谢@Zain的回答。使用下面的代码,我已经设法让FAB工作,除了没有底部余量。使用Zain解决方案,有底部余量。

val snackbar = Snackbar.make(main_content, "Item Deleted", Snackbar.LENGTH_INDEFINITE)
            snackbar.setAction("Dismiss"){

            }
            val snackbarView = snackbar.view
            val params = snackbarView.layoutParams as CoordinatorLayout.LayoutParams
            params.anchorId = R.id.adContainer
            params.bottomMargin = 16// this line didn't work
            params.gravity = Gravity.TOP
            params.anchorGravity = Gravity.TOP
            snackbarView.layoutParams = params
            snackbar.show()
bmp9r5qi

bmp9r5qi1#

您需要创建一个自定义CoordinatorLayout.Behavior类,并将FloatingActionButton作为此行为操作的视图类型
下面的自定义java类的学分回到this Repo。我只是把它转换成Kotlin。
您可以使用Kotlin或Java版本。

Kotlin:

class BottomNavigationFABBehavior constructor(context: Context, attrs: AttributeSet?) :
    CoordinatorLayout.Behavior<FloatingActionButton>(context, attrs) {

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

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

    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        child: FloatingActionButton,
        dependency: View
    ): Boolean {
        return updateButton(child, dependency)
    }

    private fun updateButton(child: View, dependency: View): Boolean {
        return if (dependency is SnackbarLayout) {
            val oldTranslation = child.translationY
            val height = dependency.getHeight().toFloat()
            val newTranslation = dependency.getTranslationY() - height
            child.translationY = newTranslation
            oldTranslation != newTranslation
        } else {
            false
        }
    }
}

** java **

public final class BottomNavigationFABBehavior
        extends CoordinatorLayout.Behavior<FloatingActionButton> {

  public BottomNavigationFABBehavior(@Nullable Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  }

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

  public void onDependentViewRemoved(
          @NonNull CoordinatorLayout parent,
          @NonNull FloatingActionButton child,
          @NonNull View dependency) {
    child.setTranslationY(0.0f);
  }

  public boolean onDependentViewChanged(
          @NonNull CoordinatorLayout parent,
          @NonNull FloatingActionButton child,
          @NonNull View dependency) {
    return this.updateButton(child, dependency);
  }

  private boolean updateButton(View child, View dependency) {
    if (dependency instanceof Snackbar.SnackbarLayout) {
      float oldTranslation = child.getTranslationY();
      float height = (float) dependency.getHeight();
      float newTranslation = dependency.getTranslationY() - height;
      child.setTranslationY(newTranslation);
      return oldTranslation != newTranslation;
    } else {
      return false;
    }
  }
}

然后在fab app:layout_behavior属性中使用该类,使CoordinatorLayout函数具有所需的行为
完整布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/rootConstraintLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Show Snackbar"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/adContainer"
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:layout_marginStart="1dp"
            android:layout_marginTop="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginBottom="1dp"
            android:background="#F44336"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        app:fabSize="normal"
        app:layout_anchor="@id/adContainer"
        app:layout_anchorGravity="end|top"
        app:layout_behavior=".BottomNavigationFABBehavior"
        app:srcCompat="@android:drawable/ic_input_add"
        app:useCompatPadding="true" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

当然,您需要保持snackbar.anchorView = adContainer的原样

预览

相关问题