Bottom Sheets

Según la documentación de Google sobre Material Design.

Una bottom sheet es una hoja de material que se desliza hacia arriba desde el límite inferor de la pantalla. Los bottom sheets son mostrados únicamente como resultado de una acción iniciada por el usuario, y puede ser deslizada hacia arriba para mostrar contenido adicional. Un bottom sheet puede tener una superificie modal temporal o una estructura persistente como elemento de una aplicación.

How to add?

I. Añade las últimas versiones de las librerías: appcompat y design en tu archivo build.gradle.

dependencies {  
    compile 'com.android.support:appcompat-v7:X.X.X' 
    compile 'com.android.support:design:X.X.X' 
    // X.X.X especifica la versión
}

II. Configura el atributo app:layout_behavior con el valor @string/bottom_sheet_behavior el cual permitirá a tu view o viewgroup aparecer como una bottom sheet.

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:orientation="vertical"
    android:padding="16dp"
    app:layout_behavior="@string/bottom_sheet_behavior">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Dandelion Chocolate"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        android:textColor="@android:color/black"/>
</LinearLayout>  

NOTA: Con el atributo behavior_peekHeight puedes configurar el ancho por defecto utilizado por el _bottom sheet en un estado pasivo._

III. Añade tu vista la cuál implementa el bottom sheet behavior como hijo directo de un CoordinatorLayout.

<?xml version="1.0" encoding="utf-8"?>  
<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"
    tools:context=".MainActivity" >

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarLayout"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >

        <android.support.v7.widget.Toolbar
            android:id="@+id/appbar"
            android:layout_height="?attr/actionBarSize"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>

    <!-- Contenido -->
    <include layout="@layout/content_main" />

    <!-- Bottom Sheet -->
    <include layout="@layout/bottom_sheets_main" />
</android.support.design.widget.CoordinatorLayout>  

NOTA: Puedes envolver _views y viewgroups bajo la etiqueta <include> para mantener limpios tus layouts._

IV. Obtén una referencia del BottomSheetBehavior con una referencia de la vista que implementa dicho behavior. Utiliza el método from de BottomSheetBehavior.

LinearLayout bottomSheetViewgroup  
    = (LinearLayout) findViewById(R.id.bottom_sheet);

BottomSheetBehavior bottomSheetBehavior =  
   BottomSheetBehavior.from(bottomSheetViewgroup);

VI. Para expandir tu bottom sheet utiliza el método setState con el valor BottomSheetBehavior.STATE_EXPANDED.

bottomSheetBehavior.setState(  
    BottomSheetBehavior.STATE_EXPANDED);

NOTA: Puedes manejar los diferentes estados con estos valores:

  • STATE_EXPANDED: Para expandir completamente el bottom sheet.
  • STATE_HIDE: PAra ocultar completamente el bottom sheet.
  • STATE_COLLAPSED: Para colapsar el bottom sheet hasta que encaje con el valor configurado en el atributo peekHeight.

Modal bottom sheets

Según la documentación de Google sobre Material Design.

Los modal bottom sheets son alternativas a menus o diálogos simples. Pueden presentar contenido enlazado profundamente desde otras aplicaciones.

I. Crea una clase que extienda de BottomSheetDialogFragment inflada con un layout el cuál será utilizado como contenido del modal bottom sheet.

public class ModalBottomSheet  
    extends BottomSheetDialogFragment {

    static BottomSheetDialogFragment newInstance() {
        return new BottomSheetDialogFragment();
    }

    @Override
    public View onCreateView(
       LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(
           R.layout.bottom_sheet_modal, container, false);

        return v;
    }
}

II. Crea una instancia del modal bottom sheet y muéstralo con el método show con un SupportFragmentManager y un String como parámetros.

ModalBottomSheet modalBottomSheet = new ModalBottomSheet();  
modalBottomSheet.show(getSupportFragmentManager(), "bottom sheet");  

Cómo fijar views?

I. Añade la vista que será fijada al bottom sheet como un hijo directo del CoordinatorLayout

<android.support.design.widget.FloatingActionButton  
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email"
    />

II. Referencia el id de la vista que tiene configurado el BottomSheetBehavior en el atributo layout_anchor.

<android.support.design.widget.FloatingActionButton  
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email"
    app:layout_anchor="@id/app_bar"
    />    

III. Configura el atributo layout_anchorGravity con la gravedad deseada.

<android.support.design.widget.FloatingActionButton  
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email"
    app:layout_anchor="@id/app_bar"
    app:layout_anchorGravity="bottom|end"
    />    

Especial mención a Salvador Gómez por su artículo: bottom sheets de su curso de android