Android 导航
2016-03-19 16:19
459 查看
一.导航抽屉Navigation Drawer
想必用过Android的人都熟悉导航抽屉,这算是一个比较经典的导航方式了,个人也非常喜欢这种导航方式。下面介绍这种导航方式的开发方法。
创建一个抽屉布局DrawerLayout
<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 --> <ListViewandroid: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>
这里有一些需要注意的地方:
要添加一个导航抽屉,首先应该用support库提供的DrawerLayout布局来作为你的主布局的根布局,在根布局中,应该包含显示主要内容的布局和drawer的布局。
第一个布局必须是你的主要内容的布局(因为XML文件是根据z轴的顺序来显示,而抽屉要在主要内容的上面)
主要内容布局需要将长宽都设置为铺满父容器,因为当抽屉隐藏时,它是主要显示的容器。
抽屉view(the ListView)必须指定horizontal_gravity,通过设置
android:layout_gravity。为了支持从右向左的语言,最好指定值为
"start"而不是
left。
为了让用户能看见主页面的一部分,抽屉view的宽度应该用
dp来设置,并且尽量不要超过320dp。
初始化Drawer List
在你的activity中,第一件事就应该去初始化导航抽屉列表的每一项。不管你怎么去组织你的app内容,一个导航抽屉通常都是由一个列表组成的,所以我们应该从一个适配器Adapter开始入手(比如
ArrayAdapter或者
SimpleCursorAdapter)。
例如,这段代码演示了如何通过一个string array来初始化你的列表。
publicclassMainActivityextendsActivity { private String[] mPlanetTitles; private DrawerLayout mDrawerLayout; private ListView mDrawerList; ... @Override publicvoidonCreate(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); // 为list设置一个适配器 mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mPlanetTitles)); // 设置一个监听器 mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); ... } }
通过
setOnItemClickListener()接收导航抽屉的列表点击事件。接下来展示如何实现这个接口和当选择一项时改变主页面。
处理导航点击事件
当用户点击抽屉的列表时,系统会在你通过setOnItemClickListener()设置的监听器
OnItemClickListener()上调用
onItemClick()
你的
onItemClick()的功能取决于你的app的功能。在下面的例子中,选择每一项都会动态的插入一个不同的
Fragment到主页面(
FrameLayout)中。
privateclassDrawerItemClickListenerimplementsListView.OnItemClickListener { @Override publicvoidonItemClick(AdapterView parent, View view, int position, long id) { selectItem(position); } } /** 替换主页面中的fragment */privatevoidselectItem(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); // 通过替换已存在的fragment来插入 FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction()// 开始事务 .replace(R.id.content_frame, fragment)// 替换 .commit();// 提交 // 高亮选中项,设置标题,关闭抽屉 mDrawerList.setItemChecked(position, true); setTitle(mPlanetTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } @Overridepublic voidsetTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); }
监听打开和关闭抽屉事件
要监听打开和关闭事件,首先应该在你的DrawerLayout上设置监听器
setDrawerListener(),还要实现
DrawerLayout.DrawerListener,这个接口提供回调函数,比如
onDrawerOpened()和
onDrawerClosed()。
回调函数解析
然而,与其实现这个接口,如果你的activity包含了
actionbar,你可以替换为使用
ActionBarDrawerToggle类,这个类实现了
DrawerLayout.DrawerListener这个接口,你仍可以去重载那些回调函数,但是使用ActionBarDrawerToggle可以促进action
bar的图标和导航抽屉的正确的交互。
当抽屉可见时,你应该改变action bar的内容,像是改变标题,移除action items来适应主页面的内容,下面的代码通过一个
ActionBarDrawerToggle类展示了如何去重载
DrawerLayout.DrawerListener回调函数。
publicclassMainActivityextendsActivity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; private CharSequence mDrawerTitle; private CharSequence mTitle; ... @Override publicvoidonCreate(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.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) { /** 当抽屉完全关闭时调用*/ publicvoidonDrawerClosed(View view) { super.onDrawerClosed(view); getActionBar().setTitle(mTitle); invalidateOptionsMenu(); // 创建调用onPrepareOptionsMenu() } /** 当抽屉完全打开时调用 */ publicvoidonDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getActionBar().setTitle(mDrawerTitle); invalidateOptionsMenu(); // 创建调用onPrepareOptionsMenu() } }; // 设置toggle为抽屉监听器 mDrawerLayout.setDrawerListener(mDrawerToggle); } /* 当调用invalidateOptionsMenu()时调用 */ @Override publicbooleanonPrepareOptionsMenu(Menu menu) { // 如果导航抽屉式打开的,根据内容隐藏action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); returnsuper.onPrepareOptionsMenu(menu); } }
下个部分介绍
ActionBarDrawerToggle的构造函数参数和与action icon交互的其他要求。
通过App Icon来打开和关闭抽屉
用户能够通过右滑来打开抽屉,但是如果你使用action bar,那么你也应该允许用户通过点击App Icon来打开和关闭抽屉。同时也应该通过一个特殊的icon来显示隐藏抽屉的存在。你能够通过之前介绍的ActionBarDrawerToggle来实现。
为了使
ActionBarDrawerToggle工作,在这里创建一个例子和他的构造函数,他需要以下的元素:
托管抽屉的
Activity
DrawerLayout
一个图片资源用作抽屉开关的指示器
图片资源
一个描述抽屉打开的string(为了用户友好)
一个描述抽屉关闭的string(为了用户友好)
不管你是否创建了
ActionBarDrawerToggle的子类作为你抽屉监听器,你需要在你的activity的整个生命周期中能够调用
ActionBarDrawerToggle
publicclassMainActivityextendsActivity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; ... publicvoidonCreate(Bundle savedInstanceState) { ... mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle( this, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */ 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. */ publicvoidonDrawerClosed(View view) { super.onDrawerClosed(view); getActionBar().setTitle(mTitle); } /** Called when a drawer has settled in a completely open state. */ publicvoidonDrawerOpened(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 protectedvoidonPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override publicvoidonConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override publicbooleanonOptionsItemSelected(MenuItem item) { // Pass the event to ActionBarDrawerToggle, if it returns // true, then it has handled the app icon touch event if (mDrawerToggle.onOptionsItemSelected(item)) { returntrue; } // Handle your other action bar items... returnsuper.onOptionsItemSelected(item); } ... }
最后给一个例子的完整版
导航抽屉完整版
未完待续……
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories