首先创建一个工程,修改其主布局代码:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawlayout"
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" >
</FrameLayout>
<!-- 左边的侧滑菜单 -->
<ListView
android:id="@+id/lv_leftmenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ffc" >
</ListView>
<!-- 右边的侧滑菜单 -->
<ListView
android:id="@+id/lv_rightmenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#0f0" >
</ListView>
</android.support.v4.widget.DrawerLayout>
注意:左右抽屉菜单的宽度最好不要超过300do,因为我们要显示抽屉菜单的同时,最好也留一部分区域显示主界面
然后还有就是layout_gravity属性,start就是左菜单,需要从左往右滑才能出来菜单,end的话就是从右往左出来右菜单
内容区域布局代码:
<?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/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="TextView" />
</LinearLayout>
主activity的代码:
package com.example.testdrawerlayoutleft;
import java.util.ArrayList;
import java.util.List;
import android.R.anim;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
public class Main extends Activity {
private DrawerLayout drawerLayout;
private FrameLayout frameLayout;
private ListView lv_leftmenu;
private List<String> strlist;
private ArrayAdapter<String> adapter;
private ActionBarDrawerToggle mActionBarDrawerToggle;
private String before_title;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
before_title = (String) getTitle();
initView();
}
/**
* 初始化控件
*/
private void initView() {
// TODO Auto-generated method stub
drawerLayout = (DrawerLayout) findViewById(R.id.drawlayout);
frameLayout = (FrameLayout) findViewById(R.id.content_frame);
lv_leftmenu = (ListView) findViewById(R.id.lv_leftmenu);
strlist = getdata();
adapter = new ArrayAdapter<String>(Main.this,
android.R.layout.simple_list_item_1, strlist);
lv_leftmenu.setAdapter(adapter);// 设置adapter
lv_leftmenu.setOnItemClickListener(new MyListItemClick());// 设置itemclick
// 创建一个ActionBarDrawerToggle对象,该对象为了可以相应抽屉打开关闭的事件
// 第一个参数是我们的activity对象
// 第二个参数是drawerLayout的布局
// 第三个是左上角将要显示的图片icon
// 第四个是抽屉打开时候的文字说明
// 第五个是抽屉关闭时候的文字说明
mActionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.drawable.ic_drawer, R.string.drawer_open,
R.string.drawer_close) {
@Override
public void onDrawerOpened(View drawerView) {
// TODO Auto-generated method stub
super.onDrawerOpened(drawerView);
getActionBar().setTitle("请选择");
// 当我们改变了actiobar的title之后,我们需要更新下actionbar,用来达到actionbar上其他控件显示和隐藏的目的
// invalidateOptionsMenu();
// 在这里我们也可以通过menu item的id找到这个view,然后对他直接设置是显示还是隐藏就行了
findViewById(R.id.menu_search).setVisibility(View.GONE);
}
@Override
public void onDrawerClosed(View drawerView) {
// TODO Auto-generated method stub
super.onDrawerClosed(drawerView);
getActionBar().setTitle(before_title);
// invalidateOptionsMenu();//执行这个方法之后系统会自动调用onPrepareOptionsMenu方法,所以在onpre方法中,我们也可以设置view的显示和隐藏
findViewById(R.id.menu_search).setVisibility(View.VISIBLE);
}
};
// 为我们的抽屉设置一个抽屉监听
drawerLayout.setDrawerListener(mActionBarDrawerToggle);
// 启用我们actionbar上的图标的功能
getActionBar().setDisplayHomeAsUpEnabled(true);// 这个是显示左上角的返回图标
getActionBar().setHomeButtonEnabled(true);
}
/**
* @return listview所需要的一个集合数据
*/
public List<String> getdata() {
List<String> list = new ArrayList<String>();
for (int i = 1; i < 10; i++) {
list.add("第" + i + "个导航菜单");
}
return list;
}
/**
* @author kk_imgod 列表的item的点击监听,在这里我们动态的创建一个fragment并加载到指定的布局中
*/
public class MyListItemClick implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// 动态的加载fragment
fragment_content fragment_content = new fragment_content();
Bundle bundle = new Bundle();
bundle.putString("text", strlist.get(position));
fragment_content.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment_content);
fragmentTransaction.commit();
// 实现抽屉的隐藏,以下三种方式都可以实现抽屉的隐藏
// drawerLayout.closeDrawers();//关闭所有的抽屉,,因为我们可以左右分别设置一个抽屉
// drawerLayout.closeDrawer(R.id.lv_leftmenu);//关闭指定id的抽屉
drawerLayout.closeDrawer(lv_leftmenu);// 关闭某一个view抽屉
}
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
* invalidateOptionsMenu();函数会调用这个函数
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
boolean isshow = drawerLayout.isDrawerOpen(R.id.lv_leftmenu);
menu.findItem(R.id.menu_search).setVisible(!isshow);
return super.onPrepareOptionsMenu(menu);
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
* 加载我们menu目录下的一个布局到界面上的actionbar来
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* optionmenu的菜单点击之后的相应
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// 一般的想法是在activity的onOptionsItemSelected方法中判断点击事件是否来自于app图标,然后用DrawerLayout.closeDrawer和DrawerLayout.openDrawer来隐藏与展开
// 下面的一个case语句就是使用的第一种思想,判断我们的item的id为android.R.id.home这个时候就是点击了app图标了
// 。但是drawerLayout提供了更优雅的方式:
// 使用ActionBarDrawerToggle的onOptionsItemSelected方法。该方法activity的onOptionsItemSelected方法中根据传递进来的menu
// item做了上面我们在“一般想法”中提到的事情。用官方的说法是”ActionBarDrawerTogglewill take care
// of this”。我们只需这样做就ok了
// actionbar和drawlayout关联起来,实现点击左上角图片的时候可以伸缩抽屉
if (mActionBarDrawerToggle.onOptionsItemSelected(item)) {
return false;// 话说这个地方返回true false都可以伸缩抽屉啊...
// 看来这个返回值果然是留给系统的,好让系统做一些震动啊,声音啊的一些事情
}
// actionbar上的item被选择的时候执行的操作
switch (item.getItemId()) {
case R.id.menu_search:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
break;
/*
* case android.R.id.home: boolean isshow =
* drawerLayout.isDrawerOpen(R.id.lv_leftmenu); if(isshow) {
* drawerLayout.closeDrawer(R.id.lv_leftmenu); } else {
* drawerLayout.openDrawer(R.id.lv_leftmenu); } break;
*/
}
return super.onOptionsItemSelected(item);
}
// 这个是实现左上角的那个动画的,主要是利用toggle的同步状态方法,把toggle的icon设置给actionbar
@Override
protected void onPostCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onPostCreate(savedInstanceState);
mActionBarDrawerToggle.syncState();
}
// 屏幕旋转的时候,我们所需要执行的同步配置
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
}
fragment的代码:
package com.example.testdrawerlayoutleft;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class fragment_content extends Fragment {
private View view;
private TextView tv;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//2015年4月10日 23:43:03
// 这个地方的inflater需要注意,自己比较喜欢使用两个参数的inflater,直接第一个是资源id,第二个是需要加载到的哪一个viewgroup对象
// 但是在这里会有一个很操心的问题,那就是this view alerly hava a parpent,you must clear
// this view
// 这个异常会导致我们的程序崩溃掉,而产生这个问题的原因也就是,我们的inflater默认把我们新加载的布局,和父布局关联起来
// Whether the inflated hierarchy should be attached to the root
// parameter? If false, root is only used to create the correct subclass
// of LayoutParams for the root view in the XML.
//这里我们使用三个参数的inflater,然后第三个参数指定为false就可以满足我们的需求了...
view = inflater.inflate(R.layout.fragment_content, container, false);
tv = (TextView) view.findViewById(R.id.tv_title);
Bundle bundle = getArguments();
String text = bundle.getString("text");
tv.setText(text);
return view;
}
}