Android How to implement Bottom Sheet from Material Design docs

佐手、 提交于 2019-11-26 23:24:55
reVerse

Edit

The BottomSheet is now part of the android-support-library. See John Shelleys' answer.


Unfortunately there's currently no "official" way on how to do this (at least none that I'm aware of).
Luckily there's a library called "BottomSheet" (click) which mimics the look and feel of the BottomSheet and supports Android 2.1 and up.

In case of the Drive app, here's how the code would look like with this library:

    new BottomSheet.Builder(this, R.style.BottomSheet_Dialog)
            .title("New")
            .grid() // <-- important part
            .sheet(R.menu.menu_bottom_sheet)
            .listener(new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO
        }
    }).show();

menu_bottom_sheet (basically a standard /res/menu/*.xml resource)

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/folder"
        android:title="Folder"
        android:icon="@drawable/ic_action_folder" />
    <item
        android:id="@+id/upload"
        android:title="Upload"
        android:icon="@drawable/ic_action_file_upload" />
    <item
        android:id="@+id/scan"
        android:title="Scan"
        android:icon="@drawable/ic_action_camera_alt" />
</menu>

Output looks like this:

Which, I think, comes pretty close to the original. If you're not happy with the colors you can customize it - see this (click).

John Shelley

Answering my own question so developers know that the new support library provides this finally! All hail the all powerful Google!

An example from the Android Developer's Blog:

// The View with the BottomSheetBehavior
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);  
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);  
behavior.setBottomSheetCallback(new BottomSheetCallback() {  
   @Override  
   public void onStateChanged(@NonNull View bottomSheet, int newState) {  
     // React to state change  
   }  

  @Override  
  public void onSlide(@NonNull View bottomSheet, float slideOffset) {  
     // React to dragging events  
  }  
});

@reVerse's answer above is still a valid option but its nice to know that there is a standard that Google supports too.

You can now use Official BottomSheetBehavior API from android support library 23.2.

Below is sample code snippet

bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheet));

case R.id.expandBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
 break;
case R.id.collapseBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
 break;
case R.id.hideBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
 break;
case R.id.showBottomSheetDialogButton:
 new MyBottomSheetDialogFragment().show(getSupportFragmentManager(), "sample");

Please refer to Android BottomSheet youtube tutorial to get understanding on it.

mcorrado

Following the blog post: http://android-developers.blogspot.com/2016/02/android-support-library-232.html

My xml ended up looking like this:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/coordinator_layout"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="horizontal"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
        <ImageView
            android:src="@android:drawable/ic_input_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

And in my onCreateView of my fragment:

    coordinatorLayout = (CoordinatorLayout)v.findViewById(R.id.coordinator_layout);
    View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
    BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
    behavior.setPeekHeight(100);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            // React to state change
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            // React to dragging events
        }
    });

The default of setPeekHeight is 0, so if you don't set it, you won't be able to see your view.

I would go with a straight corners as it is in the guidelines. As for the implementation - maybe it is best to use the idea from this project: https://github.com/umano/AndroidSlidingUpPanel

I think that you could use it as it is or take the idea for the implementation. Another great article on how to implement similar sliding panel can be found here: http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend/

Here are some of the other options :

  • There is one available from Flipboard, however the embedding activity needs to be modified for the bottomsheet to work.
  • tutti-ch's bottomsheet : This has been extracted from Android Repo's ResolverActivity and the launching activity need not be modified.

Google recently released Android Support Library 23.2 which officially brings Bottom sheets to the Android Design Support Library.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!