Navigation Drawer là một bảng điều hướng xuất hiện khi bạn vuốt trên màn hình từ cạnh trái sang cạnh phải hay từ cạnh phải sang trái. Ngoài ra Navigation Drawer còn có thể xuất hiện khi ban chạm vào 1 biểu tượng trên thanh Action bar. Chắc hẳn nếu bạn là người thường xuyên sử dụng Android thì bạn sẽ thấy Navigation Drawer có mặt trên rất nhiều ứng dụng ví dụ như Gmail, Facebook…
Và ở bài hướng dẫn này mình sẽ hướng dẫn các bạn cách để có thể làm việc được với Navigation Drawer trong Android.
Tạo mới Project
1. Trên Eclipse vào File -> New -> Android Application Project. Ở đây mình tạo main activity có tên là MainActivity.java và tên của package là truongbs.fet.hut.doubledrawerlayouttutorial.
2. Giao diên của layout main (activity_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<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" >
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/white"
android:dividerHeight="0dp" />
<ListView
android:id="@+id/right_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
Ở đây các bạn hãy chú ý tới thuộc tính android:layout_gravity=”start” và android:layout_gravity=”end” nếu bạn đặt là start thì Navigation Drawer sẽ được gọi từ trái qua phải còn nếu là end thì Navigation Drawer sẽ đươc gọi từ bên phải qua trái.
3. Tạo Actionbar
Tại mục res/menu bạn hãy tạo mới 1 file xml có tên là action_bar.xml.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="search"
yourapp:showAsAction="ifRoom"/>
<item
android:id="@+id/action_st"
android:icon="@drawable/ic_action_settings"
android:title="setting"
yourapp:showAsAction="ifRoom"/>
</menu>
4. Tải về bộ Icon cho Actionbar
Các bạn có thể tải về bộ icon để thiết kế Actionbar tại đây.
Add Support Library
Trong ví dụ này mình có sử dụng action bar trong android. Để acionbar có thể làm việc với các phiên bản android từ 2.2 trở lên bạn cần download lib support từ SDK manager (nếu chưa có). Mình sẽ làm một bài riêng giới thiệu về action bar trong tutorial tiếp theo.
Add support library: File -> Import -> Existing Project into Workspace. Sau đó clickNext. Ở màn hình tiếp theo chọn Browse và chọn tới thư mục “Thư mục chưa Android SDK” \sdk\extras\android\support\v7\appcompat và click OK.
Tiếp theo, các bạn click chuột phải vào Project và chọn Properties và chuyển sang mụcAndroid. click vào nút Add và chọn android-support-v7-appcompat.
Custom List View
1. Chúng ta cần 1 tập tin bố trí các item của listview để có thể tùy chỉnh việc hiển thị theo ý muốn. Các bạn hãy vào res -> layout và tạo 1 file có tên layout_item.xml như sau :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/itemIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp" />
<TextView
android:id="@+id/itemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="?android:attr/activatedBackgroundIndicator"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="#fff" />
</LinearLayout>
Theo như trên thì 1 item sẽ có 2 phần đó là icon và 1 phần Text chứa nội dụng hiển thị.
2. Tạo mới 1 class có tên là ItemNavigation.java có nội dung như sau:
package truongbs.fet.hut.doubledrawerlayouttutorial;
public class ItemNavigation {
public String itemName;
public int itemIcon;
public ItemNavigation (int itemIcon, String itemName){
this.itemIcon = itemIcon;
this.itemName = itemName;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemIcon() {
return itemIcon;
}
public void setItemIcon(int itemIcon) {
this.itemIcon = itemIcon;
}
}
3. Để tiếp tục việc tùy chỉnh listview trong Navigation Drawer thì ta cần tạo 1 lớp có tên là ItemAdapter.java.
package truongbs.fet.hut.doubledrawerlayouttutorial;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ItemAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context mContext;
private ArrayList arr;
public ItemAdapter(Context mContext, ArrayList arr) {
super();
this.mContext = mContext;
this.arr = arr;
mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
int count = 0;
if (arr != null) {
count = arr.size();
}
return count;
}
@Override
public Object getItem(int pos) {
// TODO Auto-generated method stub
return arr.get(pos);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
viewHolder holder;
if (convertView == null) {
holder = new viewHolder();
convertView = mInflater
.inflate(R.layout.layout_item, parent, false);
holder.itemIcon = (ImageView) convertView
.findViewById(R.id.itemIcon);
holder.itemName = (TextView) convertView
.findViewById(R.id.itemName);
convertView.setTag(holder);
} else {
holder = (viewHolder) convertView.getTag();
}
final ItemNavigation itemNavigation = arr.get(position);
if (itemNavigation != null) {
holder.itemIcon.setImageResource(itemNavigation.getItemIcon());
holder.itemName.setText(itemNavigation.getItemName());
}
// bat su kien khi click vao icon
holder.itemIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(mContext, "Ban da tap chon hinh anh",
Toast.LENGTH_LONG).show();
}
});
return convertView;
}
public class viewHolder {
public TextView itemName;
public ImageView itemIcon;
}
}
Thao tác với Navigation Drawer
Đến bước này thì bạn đã cơ bản hoàn thành việc tùy chỉnh cho list các item trong thanh Navigation Drawer. Bây giờ chúng ta sẽ chuyển sang làm việc với MainActivity.java để có thể thực hiện các thao tác với Navigation Drawer.
1. Thêm dữ liệu vào list.
// Them du lieu vao array
private void initArrayForListViewDrawer() {
// TODO Auto-generated method stub
arrLeft = new ArrayList();
arrRight = new ArrayList();
ItemNavigation ItemNavigation1 = new ItemNavigation(
R.drawable.ic_action_settings, "Settings");
arrLeft.add(ItemNavigation1);
ItemNavigation ItemNavigation2 = new ItemNavigation(
R.drawable.ic_action_new, "Add new");
arrLeft.add(ItemNavigation2);
ItemNavigation ItemNavigation3 = new ItemNavigation(
R.drawable.ic_action_favorite, "Favorite");
arrLeft.add(ItemNavigation3);
ItemNavigation ItemNavigation4 = new ItemNavigation(
R.drawable.ic_action_collection, "Foder");
arrLeft.add(ItemNavigation4);
ItemNavigation ItemNavigation5 = new ItemNavigation(
R.drawable.ic_action_about, "About");
arrLeft.add(ItemNavigation5);
ItemNavigation ItemNavigation11 = new ItemNavigation(
R.drawable.ic_action_settings, "Settings");
arrRight.add(ItemNavigation11);
}
2. Set Adapter.
// Set Adapter cho list ben trai
ItemAdapter adapterLeft = new ItemAdapter(this, arrLeft);
mleftList.setAdapter(adapterLeft);
// Set Adapter cho list ben phai
ItemAdapter adapterRight = new ItemAdapter(this, arrRight);
mrightList.setAdapter(adapterRight);
3. Bắt sự kiện khi click vào item của list trên Navigation Drawer. Ở đây mình chỉ bắt sự kiện khi người dùng click vào nút Settings của menu bên trái thì sẽ chuyển hướng sang Activity mới. Còn các sự kiện của các menu khác thì các ban có thể làm tương tự.
– Tạo mới 1 Activity có tên là SettingsActivity.java
package truongbs.fet.hut.doubledrawerlayouttutorial;
import android.app.Activity;
import android.os.Bundle;
public class SettingsActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.setting_layout);
}
}
– Tạo mới 1 layout có tên là setting_layout.
<?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="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvSettings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/tvSettings" >
</TextView>
</LinearLayout>
– File string.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">DoubleDrawerLayoutTutorial</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string name="tvSettings">Activiy Settings</string>
</resources>
– Bây giờ ta bắt sự kiện khi click vào menu của list trong Navigation Drawer.
// bat su kien click cua list ben trai
mleftList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
switch (pos) {
case 0:
// Chuyen sang activity settings
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(i);
Toast.makeText(MainActivity.this, "Ban da tap chon Settings",
Toast.LENGTH_LONG).show();
break;
default:
break;
}
Log.d("debug", "click left " + pos);
mleftList.setItemChecked(pos, true);
// Dong Drawer khi click xong
mDrawerLayout.closeDrawer(mleftList);
}
});
// bat su kien click cua list ben phai
mrightList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
Log.d("debug", "click right " + pos);
mleftList.setItemChecked(pos, true);
// Dong Drawer khi click xong
mDrawerLayout.closeDrawer(mrightList);
}
});
– Để chuyển Activity ta cần khai báo Activity mới này trong file AndroidManifest.xml.
<activity android:name="truongbs.fet.hut.doubledrawerlayouttutorial.SettingsActivity"></activity>
4. Code hoàn chỉnh của file MainActivity.java.
package truongbs.fet.hut.doubledrawerlayouttutorial;
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
@SuppressLint("NewApi")
public class MainActivity extends ActionBarActivity {
private DrawerLayout mDrawerLayout;
private ListView mleftList, mrightList;
private ActionBarDrawerToggle mDrawerToggle;
private ArrayList arrLeft, arrRight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Add du lieu vao array
initArrayForListViewDrawer();
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// Link den code
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mleftList = (ListView) findViewById(R.id.left_drawer);
mrightList = (ListView) findViewById(R.id.right_drawer);
// bat su kien click cua list ben trai
mleftList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
switch (pos) {
case 0:
// Chuyen sang activity settings
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(i);
Toast.makeText(MainActivity.this, "Ban da tap chon Settings",
Toast.LENGTH_LONG).show();
break;
default:
break;
}
Log.d("debug", "click left " + pos);
mleftList.setItemChecked(pos, true);
// Dong Drawer khi click xong
mDrawerLayout.closeDrawer(mleftList);
}
});
// bat su kien click cua list ben phai
mrightList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
Log.d("debug", "click right " + pos);
mleftList.setItemChecked(pos, true);
// Dong Drawer khi click xong
mDrawerLayout.closeDrawer(mrightList);
}
});
// Set Adapter cho list ben trai
ItemAdapter adapterLeft = new ItemAdapter(this, arrLeft);
mleftList.setAdapter(adapterLeft);
// Set Adapter cho list ben phai
ItemAdapter adapterRight = new ItemAdapter(this, arrRight);
mrightList.setAdapter(adapterRight);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
GravityCompat.START);
mDrawerToggle = new ActionBarDrawerToggle(this, // Activity chua Actionbar
mDrawerLayout, // DrawerLayout de lien ket den ActionBar
R.drawable.ic_drawer, // Hinh anh Drawer
R.string.drawer_open, // Chuoi mo ta hanh dong mo Drawer "open drawer"
R.string.drawer_close // Chuoi mo ta hanh dong dong Drawer "close drawer"
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle("Close DrawerLayout");
Log.d("debug", "onDrawerClosed");
invalidateOptionsMenu(); // tao lai menu sau khi options menu da duoc thay doi
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle("Open DrawerLayout");
Log.d("debug", "onDrawerOpened");
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
// Them du lieu vao array
private void initArrayForListViewDrawer() {
// TODO Auto-generated method stub
arrLeft = new ArrayList();
arrRight = new ArrayList();
ItemNavigation ItemNavigation1 = new ItemNavigation(
R.drawable.ic_action_settings, "Settings");
arrLeft.add(ItemNavigation1);
ItemNavigation ItemNavigation2 = new ItemNavigation(
R.drawable.ic_action_new, "Add new");
arrLeft.add(ItemNavigation2);
ItemNavigation ItemNavigation3 = new ItemNavigation(
R.drawable.ic_action_favorite, "Favorite");
arrLeft.add(ItemNavigation3);
ItemNavigation ItemNavigation4 = new ItemNavigation(
R.drawable.ic_action_collection, "Foder");
arrLeft.add(ItemNavigation4);
ItemNavigation ItemNavigation5 = new ItemNavigation(
R.drawable.ic_action_about, "About");
arrLeft.add(ItemNavigation5);
ItemNavigation ItemNavigation11 = new ItemNavigation(
R.drawable.ic_action_settings, "Settings");
arrRight.add(ItemNavigation11);
}
/**
* Khi su dung ActionBarDrawerToggle, ban phai goi toi 2 phuong thuc
* onPostCreate() va onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
Log.d("debug", "onPostCreate");
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
Log.d("debug", "onConfigurationChanged");
}
/*
* Khi goi invalidateOptionsMenu() thi chung ta phai override lai phuong
* thuc nay
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
Log.d("debug", "onPrepareOptionsMenu");
// Neu drawer ben trai dang mo thi an cac item cua actionbar
boolean drawerleftOpen = mDrawerLayout.isDrawerOpen(mleftList);
menu.findItem(R.id.action_search).setVisible(!drawerleftOpen);
menu.findItem(R.id.action_st).setVisible(!drawerleftOpen);
boolean drawerrightOpen = mDrawerLayout.isDrawerOpen(mrightList);
menu.findItem(R.id.action_search).setVisible(!drawerrightOpen);
getActionBar().setDisplayHomeAsUpEnabled(!drawerrightOpen);
getActionBar().setHomeButtonEnabled(!drawerrightOpen);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Gan cac icon vào Actionbar
getMenuInflater().inflate(R.menu.action_bar, menu);
return true;
}
// Bat su kien click tren actionbar
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
Log.d("debug", "click home");
boolean drawerleftOpen = mDrawerLayout.isDrawerOpen(mleftList);
if (!drawerleftOpen) {
mDrawerLayout.openDrawer(Gravity.START);
} else {
mDrawerLayout.closeDrawer(mleftList);
}
break;
case R.id.action_st:
Log.d("debug", "click setting");
boolean drawerrightOpen = mDrawerLayout.isDrawerOpen(mrightList);
if (!drawerrightOpen) {
mDrawerLayout.openDrawer(Gravity.END);
} else {
mDrawerLayout.closeDrawer(mrightList);
}
break;
case R.id.action_search:
Log.d("debug", "click Search");
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
Và Dưới đây là toàn bộ source code các bạn có thể tải về để nghiên cứu và chạy thử.
Tải về tại đây: NavigationDrawerLayoutTutorial