android - 底部工作表的动 Canvas 局更改

标签 android android-animation android-transitions

在我的应用程序中,我使用了一个底部工作表(来自支持库),效果很好。现在我想在向上拖动工作表时为布局更改设置动画。为此,我创建了 BottomSheetCallback 的子类(这通常是 Fragment 的内部类,因此并非此类中使用的所有对象都在此处初始化):

public class MyBehavior extends BottomSheetBehavior.BottomSheetCallback {

    Transition transition;
    float lastOffset = 0;
    Scene scene;

    public PlayerBehavior() {
        TransitionInflater inflater = TransitionInflater.from(getContext());
        transition = inflater.inflateTransition(R.transition.player);
        //transition.setDuration(300);

        scene = fullLayout;

        transition.setInterpolator(new Interpolator() {
            @Override
            public float getInterpolation(float v) {
                return lastOffset;
            }
        });
    }

    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if(newState == BottomSheetBehavior.STATE_DRAGGING) {
            TransitionManager.go(scene, transition);
        }
    }

    @Override
    public void onSlide(View bottomSheet, final float slideOffset) {
        scene = (slideOffset > lastOffset) ? smallLayout : fullLayout;
        lastOffset = slideOffset;
    }
}

如您所见,我还从不同的布局文件创建了两个 Scene 和一个自定义 Transition 以使用 TransitionManager 在场景之间进行动画处理。我的问题是 Transition 应该基于 slideOffset 参数(范围为 0-1),但 TransitionManager 使用 后台动画类,在Android中通常是基于时间的。

我尝试创建自定义 Intapolator,但这不能正常工作。那么如何创建一个基于外部变量而不是时间的 Transition 呢?

最佳答案

根据您的描述,我认为您正在尝试实现类似谷歌地图底页行为的东西。当 bottomsheet 向上拖动时,布局会发生变化。

如果这是您想要实现的目标,那么您不需要强制执行自定义动画,因为 bottomsheetdialog 本身在合并到父 Coordinator 布局 中时具有这些动画行为强>。

这是我如何实现相同行为的示例代码。它还使 FloatingActionButton 在底部表单被拖动到全屏大小时不可见:

  1. 创建一个要在主布局中使用的底部对话框

    public class CustomBottomDialog extends BottomSheetDialogFragment {
    
    String mSomeName;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // if some arguments are passed from the calling activity 
        mSomeName = getArguments().getString("some_name");
    
    
    }
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View bottomSheet = inflater.inflate(R.layout.bottomsheet_layout, container, false);
         // initialise your bottomsheet_layout items here 
        TextView tvName = bottomSheet.findViewById(R.id.display_name);
        tvName.setText(mSomeName); 
        tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               // do something here
                ((MainActivity)getActivity()).doSomething();
            }
        });
    
        return bottomSheet;
    }
    }
    
  2. bottomsheet_layout:

    <android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.design.widget.FloatingActionButton
    android:id="@+id/nav"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/navigation_tilt_grey"
    app:backgroundTint="@color/colorAccent"
    app:elevation="3dp"
    app:fabSize="normal"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    app:layout_anchor="@+id/live_dash"
    app:layout_anchorGravity="top|right" />
    
    <!--BottomSheet-->
    
    <android.support.v4.widget.NestedScrollView
    android:id="@+id/live_dash"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F3F3F3"
    android:clipToPadding="true"
    app:layout_behavior="android.support.design.widget.BottomSheetBe 
    havior"
    tools:layout_editor_absoluteY="150dp">
    
    <!--Include your items here, the height of all items combined
    will take the main screen layout size with animation-->
    
    </android.support.v4.widget.NestedScrollView>
    
    </android.support.design.widget.CoordinatorLayout>
    
  3. 从您的 Activity 中调用此 BottomSheet:

    public void notifyBottomSheet(String somename){
    
    BottomSheetDialogFragment customDialogFragment = new CustomBottomDialog();
    Bundle args = new Bundle();
    args.putString("some_name", somename);
    customDialogFragment.setArguments(args);
    customDialogFragment.show(getSupportFragmentManager(), customDialogFragment.getTag());
    customDialogFragment.setCancelable(false); // if you don't wish to hide
    }
    

    希望这能解决您想要实现的目标。

关于android - 底部工作表的动 Canvas 局更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45658198/

相关文章:

android - 无法从 Android Studio 生成签名的 apk

android - 在拖动 View 时执行动画

Android ActivityOptions.makeSceneTransitionAnimation 似乎不存在

android - 导航组件的共享 View 转换不起作用

java - 将循环结果放入数组后如何使用 ArrayList 和 For 循环?

键盘打开时的android浏览器计时器

java - 在 Android 中创建文件夹

ANDROID:抽屉导航菜单项共享元素转换

android - MotionLayout - OnSwipe 不适用于可点击的子项

android - 在具有共享元素的 fragment 上输入转换以共享元素为目标