Oak先生-利用DrawerLayout来写侧滑菜单
Android,Oak先生,DrawerLayout侧滑菜单2016-11-09
在之前呢,我们通常都是用的SlidingMenu来做侧滑菜单,随后Google也推出来自己的侧滑菜单,就是DrawerLayout。下面我们利用ADT开发工具来一起开发吧。
源码下载:http://download.csdn.net/detail/liuyu973971883/9596952
点击左上角可以实现打开菜单,右滑也可以,打开菜单后,标题栏标题发生变化,右边搜索图标消失,选择任意菜单,菜单消失,标题和搜索图标恢复,主页面显示内容
效果图:
首先呢,我们需要在主布局文件activity_main.xml上将DrawerLayout作为根节点,然后里面分为两部分:一:FrameLayout节点,用于存放在菜单点击后显示的Fragment;二:菜单listView节点,我们的侧滑菜单就用listView来做,代码如下:
下面代码中listView中的代码详解:
android:layout_width="240dp"表示侧滑后显示菜单的宽度大小
android:layout_gravity="start"表示菜单在左边,右滑即可,如果为end则反之
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_height="match_parent" android:layout_width="match_parent" > <!-- 存放内容的布局 --> <FrameLayout android:id="@+id/content_frame" android:layout_height="match_parent" android:layout_width="match_parent" > </FrameLayout> <!-- 存放菜单的布局,菜单里面有什么就在这里加 --> <ListView android:id="@+id/left_drawer" android:layout_height="match_parent" android:layout_width="240dp" android:layout_gravity="start" android:background="#ffffcc"> </ListView> </android.support.v4.widget.DrawerLayout>
————————————————————————————————————————
然后我们需要创建一个类用来呈现Fragment用的,我命名为ContentFragment,用来呈现内容,代码如下:
package com.oak.learndrawerlayout; import com.oak.learndrawerlayout.R; 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 ContentFragment extends Fragment { private TextView tv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //将fragment布局文件加载进来 View root = inflater.inflate(R.layout.fragment_content, container, false); //找到fragment中TextView,用于显示菜单选中的内容 tv = (TextView) root.findViewById(R.id.text); //获取传过来的信息,显示在TextView中 tv.setText(getArguments().getString("text")); return root; } }
<?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" > <!-- 用于区别不同的Fragment --> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/text"/> </LinearLayout>
基本工作已经做完了,下面我们来写代码。
首先我先说下具体的流程以及涉及到的方法
1、获取到布局文件中的DrawerLayout跟布局,listView,由于listView要显示内容,所以我们需要为其设置adapter,让其菜单有内容显示,到这里我们运行项目,侧滑菜单就已经好了,但是还没有点击等效果,只是简单的能看到
2、为侧滑菜单设置点击效果,点击菜单项,侧滑菜单消失,显示对应的fragment
3、利用ActionBarDrawerToggle类来进行监听侧滑菜单是否打开,如果打开则进行设置标题,关闭后还原标题,并用invalidateOptionsMenu()方法重新初始化标题栏,随后系统会自动调用onPrepareOptionsMenu方法,我们重写这个方法,在里面设置右边搜索图标的显示和隐藏。
4、用getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);这两个方法打开标题栏左边的按钮设置为可用,如果报错则需将最低SDK设置为14
_________________________________________________________
整个MainActivity的代码如下:
package com.oak.learndrawerlayout; import java.util.ArrayList; import com.oak.learndrawerlayout.R; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.Intent; import android.content.res.Configuration; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity implements OnItemClickListener { private DrawerLayout mDrawerLayout;//DrawerLayout根布局 private ListView mDrawerList;//侧滑listview private ArrayAdapter<String> adapter;//listview适配器 private ArrayList<String> list;//用于存放适配器内容 private ActionBarDrawerToggle mDrawerToggle;//标题菜单 protected String mTitle;//记录初始标题 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //将应用初始标题记录下来 mTitle = (String) getTitle(); //获取DrawerLayout根布局 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); //添加数据,以显示在菜单listview中 list = new ArrayList<String>(); list.add("111"); list.add("222"); list.add("333"); //配置适配器 adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,list); //找到listView菜单组件 mDrawerList = (ListView) findViewById(R.id.left_drawer); //将适配器绑定上去 mDrawerList.setAdapter(adapter); //设置菜单监听,当点击菜单选项时跳转到对应的fragment mDrawerList.setOnItemClickListener(this); /* 下面的mDrawerToggle是ActionBarDrawerToggle类型,如果你的 * 应用有标题栏则使用这个方法来进行菜单打开和关闭的监听,因为这个类 * 有效的将标题栏的设置和DrawerLayout结合在一起; * 如果你的应用没有标题栏,则new一个DrawerListener即可,同时实现 * onDrawerOpened和onDrawerClosed方法即可。 */ /* 这边我用的是有标题栏的设置 * 第一个参数是Activity,第二个参数是要结合的菜单根布局 * 第三个参数是应用左上角那个菜单按钮图标 * 第四个参数和第五个参数是一个String类型的资源文件, * 在Vlaues的String中设置,主要功能便于视力不好的人群进行语音播报 */ mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) { //重写onDrawerOpened方法,在菜单打开后设置应用标题 @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); //设置应用标题 getActionBar().setTitle("请选择"); //调用这个方法是因为我们需要在菜单或关闭的时候显示或隐藏右边的搜索按钮 //在调用这个方法后,程序会自动调用onPrepareOptionsMenu方法,所以我们 //在这里面设置右边搜索按钮的显示和隐藏 invalidateOptionsMenu(); } //重写onDrawerClosed方法,在菜单关闭后设置应用标题为原来的标题 @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); getActionBar().setTitle(mTitle); //此处的invalidateOptionsMenu方法和上面一样,用于更新右边搜索按钮的显示和隐藏 invalidateOptionsMenu(); } }; //为mDrawerLayout设置打开菜单或关闭菜单监听,将上面设置的监听类传入 mDrawerLayout.setDrawerListener(mDrawerToggle); //下面的两个方法是用于设置菜单栏左边的按钮可用 getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); } //下面的判断侧滑菜单是否选中,如果选中则关闭侧滑菜单,打开相应的fragment @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { //new一个新的fragment Fragment fragment = new ContentFragment(); //将侧滑菜单所选中的内容显示在fragment中 Bundle bundle = new Bundle(); bundle.putString("text", list.get(arg2)); //将信息发送给fragment fragment.setArguments(bundle); //获取fragment管理器 FragmentManager fm = getFragmentManager(); //显示新的fragment fm.beginTransaction().replace(R.id.content_frame, fragment).commit(); //关闭侧滑菜单 mDrawerLayout.closeDrawer(mDrawerList); } //标题栏按钮选中后的业务逻辑 @Override public boolean onOptionsItemSelected(MenuItem item) { //将标题栏左边的按钮和Drawerlayout结合起来,判断是否按下,如果true则打开侧滑菜单 if(mDrawerToggle.onOptionsItemSelected(item)){ return true; } //这边是标题栏右边的搜索图标,如果按下的话就打开系统默认浏览器,打开百度页面 switch (item.getItemId()) { case R.id.web_search: Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.setData(Uri.parse("http://wwww.baidu.com")); startActivity(intent); break; } return super.onOptionsItemSelected(item); } //判断侧滑菜单是否打开,如果打开则不显示搜索图标,反之 @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.web_search).setVisible(!isDrawerOpen); return super.onPrepareOptionsMenu(menu); } //在Activity整个创建完毕后用mDrawerToggle,也就是我们刚刚设置的标题栏和 //菜单栏结合的监听类,调用syncState()方法,呈现左边按钮的图标 @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } //这里onConfigurationChanged方法是用于横竖屏发生改变的时候,mDrawerToggle进行新的配置。 @Override public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }