浮动操作按钮在snackbar动画开始时会上下跳动

5
我希望你能够在删除笔记后,为我的Notes应用程序添加撤销功能。 我在android ItemTouchHelper的onSwiped方法中添加了一个snackbar来删除单个笔记。 我遇到的问题是Snackbar滑动动画会导致浮动操作按钮在动画开始时再次上下跳动。 我在Github论坛GitHub动画中找到了描述此问题的信息,但不幸的是该问题尚未解决。
我的activity_main:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:id="@+id/coordinatorLayout">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycle_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/note_item" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/button_add_note"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:elevation="4dp"
        android:layout_margin="32dp"
        android:src="@drawable/ic_add" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

onSwiped

public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorLayout);
                Note deletedNote = adapter.getNoteAt(viewHolder.getAdapterPosition());
                noteViewModel.delete(deletedNote);
                Snackbar snackbar = Snackbar.make(coordinatorLayout, "Note deleted", Snackbar.LENGTH_LONG)
                .setAction("UNDO", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                noteViewModel.insert(deletedNote);
                            }
                        });
                snackbar.show();
            }
        }).attachToRecyclerView(recyclerView);
2个回答

2
这似乎是Material-Components的一个bug,你可以通过使用旧版本库(1.1.0-alpha10)来解决它,或者放弃滑动动画,改用淡入淡出动画,如下所示。
<style name="MySnackbarStyle" parent="Widget.Design.Snackbar">
  <item name="animationMode">fade</item>
</style>

并将以下内容添加到您的活动主题中。
<item name="snackbarStyle">@style/MySnackbarStyle</item>

1
两个建议都有效,非常感谢您的时间和帮助。 - Grymon
淡入淡出效果也可以,但如果你喜欢幻灯片动画,请查看我的解决方案 :) - Panther

0
找到了一个简单的解决方案。花费了我很长时间。
它可以防止FAB在snackbar动画开始之前改变位置。
只需将一个新的SnackbarJumpFix类添加到您的项目中即可:
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import com.google.android.material.snackbar.Snackbar;

import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

public class SnackbarJumpFix extends CoordinatorLayout.Behavior<View> {

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

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

    @Override
    public void onDependentViewRemoved(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) {
        super.onDependentViewRemoved(parent, child, dependency);
        child.setTranslationY(0);
    }

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

然后在您的活动布局文件中,将此行添加到FAB

app:layout_behavior=".SnackbarJumpFix"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接