Skip to content

Most visited

Recently visited

navigation

Creación de un panel lateral de navegación

El panel lateral de navegación es un panel en el que se muestran las principales opciones de navegación de la app en el borde izquierdo de la pantalla. La mayor parte del tiempo está oculto, pero aparece cuando el usuario desliza un dedo desde el borde izquierdo de la pantalla o, mientras está en el nivel superior de la app, el usuario toca el ícono de la app en la barra de acciones.

En esta lección se describe la manera de implementar un panel lateral de navegación usando las DrawerLayout API disponibles en la Biblioteca de compatibilidad.

Diseño del panel lateral de navegación

Antes de decidir usar un panel lateral de navegación en tu app, debes comprender los casos de uso y los principios de diseño definidos en la guía de diseño de Panel lateral de navegación.

Crear un diseño de panel lateral

Para agregar un panel lateral de navegación, declara tu interfaz de usuario con un objeto DrawerLayout como vista raíz de tu diseño. Dentro del DrawerLayout, agrega una vista que tenga el contenido principal de la pantalla (tu diseño principal cuando el panel lateral está oculto) y otra vista con el contenido del panel lateral de navegación.

Por ejemplo, en el siguiente diseño se usa DrawerLayout con dos vistas secundarias: un FrameLayout con el contenido principal (que hace aparecer un Fragment en tiempo de ejecución) y un ListView para el panel lateral de navegación.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Este diseño muestra algunas características de diseño importantes:

Inicializar la lista de panel lateral

En tu actividad, una de las primeras cosas que debes hacer es inicializar la lista de elementos del panel lateral de navegación. La manera en que lo hagas depende del contenido de tu app, pero un panel lateral de navegación a menudo consiste en una ListView; por lo tanto, la lista debe completarse con un Adapter (como ArrayAdapter o SimpleCursorAdapter).

A continuación, por ejemplo, se muestra la manera en que puedes inicializar la lista de navegación con una matriz de string:

public class MainActivity extends Activity {
    private String[] mPlanetTitles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPlanetTitles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        // Set the adapter for the list view
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mPlanetTitles));
        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        ...
    }
}

Este código también llama a setOnItemClickListener() para recibir eventos de clic en la lista del panel lateral de navegación. En la siguiente sección se muestra la manera de implementar esta interfaz y cambiar la vista de contenido cuando el usuario selecciona un elemento.

Controlar eventos de clic de navegación

Cuando el usuario selecciona un elemento de la lista del panel lateral, el sistema llama a onItemClick() en el OnItemClickListener que se otorga a setOnItemClickListener().

Las medidas que apliques al método onItemClick() dependen de la manera en que implementes la estructura de tu app. En el siguiente ejemplo, con la selección de cada elemento de la lista se inserta un Fragment distinto en la vista de contenido principal (el elemento FrameLayout identificado por el ID R.id.content_frame):

private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Create a new fragment and specify the planet to show based on position
    Fragment fragment = new PlanetFragment();
    Bundle args = new Bundle();
    args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
    fragment.setArguments(args);

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
                   .replace(R.id.content_frame, fragment)
                   .commit();

    // Highlight the selected item, update the title, and close the drawer
    mDrawerList.setItemChecked(position, true);
    setTitle(mPlanetTitles[position]);
    mDrawerLayout.closeDrawer(mDrawerList);
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

Recibir eventos abiertos y cerrados

Para detectar eventos abiertos y cerrados del panel lateral, llama a setDrawerListener() en tu DrawerLayout y pasa esa implementación a DrawerLayout.DrawerListener. Esta interfaz brinda callbacks para eventos del panel lateral como onDrawerOpened() y onDrawerClosed().

Sin embargo, en lugar de implementar el DrawerLayout.DrawerListener, si tu actividad incluye la barra de acciones, puedes extender la clase ActionBarDrawerToggle. El ActionBarDrawerToggle implementa DrawerLayout.DrawerListener para que puedas anular esos callbacks, pero también facilita el comportamiento de interacción correspondiente entre el ícono de barra de acciones y el panel lateral de navegación (se trata posteriormente en la siguiente sección).

Según lo analizado en la guía de diseño del Panel lateral de navegación, debes modificar el contenido de la barra de acciones cuando el panel lateral sea visible; por ejemplo, cambiar el título y eliminar los elementos de acción contextuales respecto del contenido principal. En el siguiente código se muestra la manera en que puedes hacerlo anulando los métodos de callback DrawerLayout.DrawerListener con una instancia de la clase ActionBarDrawerToggle:

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...

        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
}

En la sección siguiente, se describen los argumentos de constructor de ActionBarDrawerToggle y los demás pasos necesarios para configurarlo a fin de controlar la interacción con el ícono de la barra de acciones.

Abrir y cerrar el panel lateral con el ícono de la app

Los usuarios pueden abrir y cerrar el panel lateral de navegación con un gesto de deslizamiento desde o hacia el borde izquierdo de la pantalla, pero si usas la barra de acciones debes permitir que los usuarios la abran y cierren tocando el ícono de la app. El ícono de la app también debe indicar la presencia del panel lateral de navegación con un ícono especial. Puedes implementar este comportamiento usando el ActionBarDrawerToggle que se muestra en la sección anterior.

Para hacer que el ActionBarDrawerToggle funcione, crea una instancia de este con su constructor, que requiere los siguientes argumentos:

Entonces, ya sea si has creado o no una subclase de ActionBarDrawerToggle como receptor de panel lateral, debes llamar a tu ActionBarDrawerToggle en algunos puntos durante el ciclo de vida de tu actividad:

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    ...

    public void onCreate(Bundle savedInstanceState) {
        ...

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.string.drawer_open,  /* "open drawer" description */
                R.string.drawer_close  /* "close drawer" description */
                ) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    ...
}

Para hallar un ejemplo completo de un panel lateral de navegación, descarga la muestra disponible en la parte superior de la página.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)