Tutorial Android – Criando um menu lateral deslizante

On 16 de setembro de 2014 by William Felippe

Criando menu lateral deslizante no Android

Hoje vamos falar de um componente que está muito na moda em grandes aplicações. Esse componente é o menu lateral deslizante. Você pode encontrá-lo em praticamente todos os aplicativos da Google e em muitos outros.

O assunto é um pouco mais avançado e para a criação de desse menu precisaremos ter conhecimento de alguns componentes do Android. Se você ainda é um novato, seria interessante que desse uma olhada em fragments, listview e animações usando XML.

Acreditando que os tutoriais acima referenciados foram estudados e entendidos, vamos ao que interessa. Criar um menu como esse:

Menu Lateral Deslizante

Passo a passo para o menu lateral deslizante

A primeira coisa a ser fazer é criar um listview com as opções que você deseja que apareçam no menu. No nosso caso, criaremos uma listview com um imageview, para nosso ícone, e dois textview, um para o texto que descreve o que é a opção e outro que mostrará a informação de quantos itens foram atualizados naquela aba.

Então crie um arquivo XML de layout chamado drawer_list_item com o seguinte código:

[sourcecode language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/list_selector"
android:paddingBottom="10dp"
android:paddingTop="10dp" >

<ImageView
android:id="@+id/icon"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:contentDescription="@string/desc_list_item_icon"
android:src="@drawable/ic_home" />

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@id/icon"
android:gravity="center_vertical"
android:paddingRight="40dp"
android:textColor="@color/list_item_title" />

<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:background="@drawable/counter_bg"
android:textColor="@color/counter_text_color" />

</RelativeLayout>
[/sourcecode]

Tendo criado o layout de um item da lista, agora vamos criar o código Java que representa o item e o adapter.

Criamos então duas classes, a NavDrawerItem e NavDrawerListAdapter, respectivamente com os códigos abaixo:

[sourcecode language=”java”]
public class NavDrawerItem {

private String title;
private int icon;
private String count = "0";
// boolean to set visiblity of the counter
private boolean isCounterVisible = false;

public NavDrawerItem(){}

public NavDrawerItem(String title, int icon){
this.title = title;
this.icon = icon;
}

public NavDrawerItem(String title, int icon, boolean isCounterVisible, String count){
this.title = title;
this.icon = icon;
this.isCounterVisible = isCounterVisible;
this.count = count;
}

public String getTitle(){
return this.title;
}

public int getIcon(){
return this.icon;
}

public String getCount(){
return this.count;
}

public boolean getCounterVisibility(){
return this.isCounterVisible;
}

public void setTitle(String title){
this.title = title;
}

public void setIcon(int icon){
this.icon = icon;
}

public void setCount(String count){
this.count = count;
}

public void setCounterVisibility(boolean isCounterVisible){
this.isCounterVisible = isCounterVisible;
}
}
[/sourcecode]

[sourcecode language=”java”]
public class NavDrawerListAdapter extends BaseAdapter
{
private Context context;
private ArrayList<NavDrawerItem> navDrawerItems;

public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems){
this.context = context;
this.navDrawerItems = navDrawerItems;
}

@Override
public int getCount() {
return navDrawerItems.size();
}

@Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item, null);
}

ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
TextView txtCount = (TextView) convertView.findViewById(R.id.counter);

imgIcon.setImageResource(navDrawerItems.get(position).getIcon());
txtTitle.setText(navDrawerItems.get(position).getTitle());

// displaying count
// check whether it set visible or not
if(navDrawerItems.get(position).getCounterVisibility()){
txtCount.setText(navDrawerItems.get(position).getCount());
}else{
// hide the counter view
txtCount.setVisibility(View.GONE);
}

return convertView;
}

}
[/sourcecode]

Vamos agora criar a classe principal que irá agrupar tudo isso e transformá-los em um menu.

Crie uma activity vazia, de preferência com nome de MainActivity e no XML responsável pelo layout insira o seguinte código:

[sourcecode language=”xml”]
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.uguideufopalfa.MainActivity" >

<!– Framelayout to display Fragments –>

<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<!– Listview to display slider menu –>

<ListView
android:id="@+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#f6f6f6"
android:choiceMode="singleChoice"
android:divider="#2d2b28"
android:dividerHeight="1dp" />
</android.support.v4.widget.DrawerLayout>
[/sourcecode]

Voltando à activity, vamos criar uma pequena classe privada, dentro da própria classe da Activity, com o seguinte código:

[sourcecode language=”java”]
private class SlideMenuClickListener implements ListView.OnItemClickListener
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// display view for selected nav drawer item
displayView(position);
}
}
[/sourcecode]

Essa classe serve para acionarmos os eventos de clique no menu.

Insira abaixo dessa classe o seguinte código, que será responsável por resolver e direcionar para qual fragmento a tela deverá ser redirecionada.

[sourcecode language=”java”]
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position)
{
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new MenuFragment();
break;
case 2:
fragment = new NewsFragment();
break;
case 3:
fragment = new EventsFragment();
break;
case 4:
fragment = new PlacesFragment();
break;
case 5:
fragment = new AdsFragment();
break;

default:
break;
}

if (fragment != null)
{
FragmentManager fragmentManager = getFragmentManager();

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
{
fragmentManager.beginTransaction()
.setCustomAnimations(R.anim.fadein, R.anim.fadeout, R.anim.fadein, R.anim.fadeout)
.replace(R.id.frame_container, fragment).commit();
}
else
{
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
}

// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
else
{
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
[/sourcecode]

Para finalizar a activity, inserimos o seguinte código:

[sourcecode language=”java”]
public class MainActivity extends Activity
{
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;

// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;

private static boolean alreadyOpen = false;

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

// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

// nav drawer icons from resources
navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

navDrawerItems = new ArrayList<NavDrawerItem>();

// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
// Find People
navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
// Photos
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
// Pages
navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
// What’s hot, We will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));

// Recycle the typed array
navMenuIcons.recycle();

mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

// setting the nav drawer list adapter
adapter = new NavDrawerListAdapter(getApplicationContext(), navDrawerItems);
mDrawerList.setAdapter(adapter);

if (savedInstanceState == null)
{
// on first time display view for first nav item
displayView(0);
}
}

@Override
protected void onResume()
{
super.onResume();

Log.i("Already Open", "" + alreadyOpen);

if(!alreadyOpen)
{
mDrawerLayout.openDrawer(mDrawerList);
Handler h = new Handler();
h.postDelayed(new Runnable()
{
@Override
public void run()
{
mDrawerLayout.closeDrawer(mDrawerList);
}
}, 2000);

alreadyOpen = true;
}
}
[/sourcecode]

Vocês podem perceber que meu menu contêm seis opções, sendo assim preciso de seis fragmentos.

O construtor de NavDrawerItem aceita dois tipos diferentes de entrada. Em uma são passados somente o texto que será inserido no menu e o ícone do mesmo. A segunda opção, um pouco maior, recebe o texto, o ícone, a opção de acionar ou não o contador (true ou false) e o valor que será passado ao contador. Lembrando que esse contador é o lugar onde é mostrado quantos itens foram atualizados naquela seção.

No método onResume, criei um código que abrirá o menu na primeira vez que o usuário entrar na aplicação, para que o mesmo possa saber que a funcionalidade existe.

Provavelmente alguns erros ainda aparecerão citando a falta de alguns arquivos XML. Os arquivos que faltam são os arquivos para animação do menu. Também faltará algumas strings a serem inseridas no arquivo strings.xml.

Vamos fazer isso agora.

Crie dois arquivos XML com os nome fadein.xml e fadeout.xml e os insira na pasta anim que está dentro da pasta res. Caso a pasta anim não exista, crie a mesma.

No arquivo fadein, insira esse código:

[sourcecode language=”java”]
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="alpha"
android:valueFrom="0.0"
android:valueTo="1" />
[/sourcecode]

Para o arquivo fadeout vai esse código:

[sourcecode language=”java”]
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0.0" />
[/sourcecode]

Para finalizar vamos ao nosso arquivo strings.xml e vamos inserir o seguinte:

[sourcecode language=”xml”]
<string-array name="nav_drawer_items">
<item>Home</item>
<item>Cardápio</item>
<item>Notícias</item>
<item>Eventos</item>
<item>Locais</item>
<item>Anúncios</item>
</string-array>

<array name="nav_drawer_icons">
<item>@drawable/ic_home</item>
<item>@drawable/ic_menu</item>
<item>@drawable/ic_news</item>
<item>@drawable/ic_events</item>
<item>@drawable/ic_places</item>
<item>@drawable/ic_ads</item>
</array>
[/sourcecode]

No string-array ficará o nome dos itens que você vai colocar no menu. Já no array ficará o caminho para os ícones do menu.

Temos agora o nosso menu deslizante funcionando perfeitamente.

Não é uma tarefa das mais fáceis para quem não conhece nada ainda de programação para Android, mas para quem já tem um conhecimento básico, vai conseguir tirar de letra tudo isso.

Lembrando que todas as suas telas agora serão fragments e o menu será sua activity. Então, como falei no ínicio, um conhecimentos sobre fragments também é importante para dar continuidade ao seu projeto.

Qualquer dúvida, deixe nos comentários.

(Atualização: Para quem está pedindo o código ou quer saber mais, fiz um novo post sobre o menu lateral. Está tudo aqui: http://www2.decom.ufop.br/imobilis/crie-um-menu-lateral-com-navigationview/)

Summary
Review Date
Reviewed Item
Como fazer um menu lateral deslizante no Android
Author Rating
51star1star1star1star1star

96 Responses to “Tutorial Android – Criando um menu lateral deslizante”

Trackbacks & Pings

Deixe um comentário

O seu endereço de e-mail não será publicado.