Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate layout change of bottom sheet

In my application I use a bottom sheet (from the support library) which works great. Now I would like to animate a layout change while the sheet is dragged up. For this I have created a subclass of BottomSheetCallback (this is normaly an inner class of a Fragment so not all objects used in this calss are initialized here):

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;     } } 

As you can see I also created two Scene from different layout files and a custom Transition to animate between the scenes with the TransitionManager. My problem is that the Transition should be based on the slideOffset parameter (in range of 0-1) but the TransitionManager uses the Animation class in the background which is normally time based in Android.

I tried to create the custom Intapolator but this does not work properly. So how can I create a Transition which is based on an external variable and not on time?

like image 717
Cilenco Avatar asked Aug 13 '17 07:08

Cilenco


People also ask

How do I change an animation layout?

All you need to do is set an attribute in the layout to tell the Android system to animate these layout changes, and system-default animations are carried out for you. Tip: If you want to supply custom layout animations, create a LayoutTransition object and supply it to the layout with the setLayoutTransition() method.

What is bottom sheet in Android?

Bottom Sheet dialogs seem to be replacing regular Android dialogs and menus. The Bottom Sheet is a component that slides up from the bottom of the screen to showcase additional content in your application. A Bottom Sheet dialog is like a message box triggered by the user's actions.


1 Answers

Based on your description, I think you are trying to achieve something like google maps bottom sheet behaviour. The layout changes as the bottomsheet is dragged up.

If that is what you are trying to achieve then you don't need to enforce custom animations, as the bottomsheetdialog itself has those animation behaviour when incorporated inside a parent Coordinator Layout.

Here is a sample code of how I'm implementing the same behaviour. It also makes the FloatingActionButton invisible when the bottomsheet is dragged up to full screen size :

  1. Create a bottomsheetdialog that you want to use inside your main layout

    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. Calling this BottomSheet from your activity:

    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 } 

    Hope this solves what you are trying to achieve.

like image 168
Prashant Kumar Avatar answered Sep 20 '22 16:09

Prashant Kumar