簡體   English   中英

如果在 CoordinatorLayout 中設置了 anchorView,則浮動操作按鈕不會隨 Snackbar 一起浮動

[英]Floating Action Button Not Floating With Snackbar If anchorView set within CoordinatorLayout

當我設置 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 上下浮動?

帶有 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 正常工作,但沒有底邊距。 對於 Zains 解決方案,存在底邊距。

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()

我不能寫簡單的評論對不起。 您可以嘗試在您的清單文件中添加您嘗試執行的活動android:windowSoftInputMode="adjustResize"

您需要創建一個自定義CoordinatorLayout.Behavior class 與FloatingActionButton作為此行為操作的視圖類型

以下自定義 java class 的學分返回到此回購 我剛剛將它轉換為 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屬性中使用此 class 以使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=".BottomNavigationFABBehavior2"
        app:srcCompat="@android:drawable/ic_input_add"
        app:useCompatPadding="true" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

當然你需要保持snackbar.anchorView = adContainer原樣

預習

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM