抽屉显示控件SlidingDrawer入门
SlidingDrawer是一个抽屉控件,代码具体路径为:android.widget.SlidingDrawer,该控件从API Level3引入,在API 17及之后的版本将不再被支持。具体效果如下图所示,它有委托视图handle和内容显示视图content组成:
抽屉显示控件支持横竖屏,它由两个子视图(用户拖动句柄handle和内容显示视图)组成,可以通过拖动或者点击handle的方式呼出内容显示视图,注意,SlidingDrawer的父布局只能是FrameLayout和RelativeLayout或者他们的子视图。
这个范例是在参考他人的基础上写的:
布局文件如下:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <SlidingDrawer
- android:id="@+id/slidingDrawer"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="200dip"
- android:content="@+id/content"
- android:handle="@+id/handle">
- <RelativeLayout
- android:id="@+id/handle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <ImageView
- android:id="@+id/handlebg"
- android:layout_width="wrap_content"
- android:layout_height="30dip"
- android:layout_centerHorizontal="true"
- android:scaleType="fitXY"
- android:src="@drawable/handle" />
- <ImageView
- android:id="@+id/directionImage"
- android:layout_width="20dip"
- android:layout_height="20dip"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:layout_marginLeft="5dip"
- android:src="@drawable/up" />
- <TextView
- android:id="@+id/handTextView"
- android:paddingLeft="4dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/directionImage"
- android:layout_centerVertical="true"
- android:textColor="#ffffffff"/>
- </RelativeLayout>
- <LinearLayout
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="150dip"
- android:background="#4455AA">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="SlidingDrawer Content Layout!"
- android:textAppearance="?android:attr/textAppearanceLarge" />
- </LinearLayout>
- </SlidingDrawer>
- </RelativeLayout>
对应代码如下:
- package com.demo.slidingdrawer;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.widget.ImageView;
- import android.widget.SlidingDrawer;
- import android.widget.TextView;
- public class SlidingDrawerActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.slidingdrawer_layout);
- initSlidingDrawer();
- }
- private void initSlidingDrawer( ){
- mDirectionImageView = (ImageView) findViewById(R.id.directionImage);
- mHandleTextView = (TextView) findViewById(R.id.handTextView);
- mHandleTextView.setText("展开");
- mSlidingDrawer = (SlidingDrawer) findViewById(R.id.slidingDrawer);
- mSlidingDrawer.setOnDrawerOpenListener(new SlidingDrawer.OnDrawerOpenListener() { // 打开抽屉
- @Override
- public void onDrawerOpened() {
- mDirectionImageView.setImageResource(R.drawable.down);
- Animation animation = AnimationUtils.loadAnimation(SlidingDrawerActivity.this, R.anim.arrowrote);
- mDirectionImageView.setAnimation(animation);
- mHandleTextView.setText("收起");
- }
- });
- mSlidingDrawer.setOnDrawerCloseListener(new SlidingDrawer.OnDrawerCloseListener() { // 关闭抽屉
- @Override
- public void onDrawerClosed() {
- mDirectionImageView.setImageResource(R.drawable.up);
- Animation animation = AnimationUtils.loadAnimation(SlidingDrawerActivity.this, R.anim.arrowrote);
- mDirectionImageView.setAnimation(animation);
- mHandleTextView.setText("展开");
- }
- });
- }
- private ImageView mDirectionImageView = null;
- private SlidingDrawer mSlidingDrawer = null;
- private TextView mHandleTextView = null;
- }
附:
抽屉导航是一个在应用程序主界面左侧显示的面板,它多数时候处于隐藏状态,用户可以通过用手指从屏幕左侧拖动或者点击Acion Bar的应用程序图标来呼出抽屉导航。
本课介绍如何使用android-support-v4.jar中的DrawerLayout来实现抽屉导航功能。
创建一个抽屉布局
为了在你的程序中实现抽屉导航功能,需要在你的窗口布局中定义一个DrawerLayout对象作为根视图,并且需要添加一个包含界面显示内容的视图(当抽屉导航处于隐藏状态下窗口所显示的视图)和包含抽屉导航显示内容的视图作为DrawerLayout的子视图。
比如,如下所示的布局就是将DrawerLayout作为布局的跟标签,包含一个FrameLayout帧布局作为内容显示视图和一个ListView作为抽屉导航显示视图。
- <span style="font-size:18px"><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:choiceMode="singleChoice"
- android:divider="@android:color/transparent"
- android:dividerHeight="0dp"
- android:background="#111"/>
- </android.support.v4.widget.DrawerLayout>
- </span>
上面这个布局展示了抽屉导航布局的一些重要布局特点:
界面的内容显示视图(FrameLayout)必须是DrawerLayout的第一个子视图。
因为在抽屉导航处于隐藏状态时内容显示视图作为窗口的主界面,所以内容显示视图应设置为填充父布局。
抽屉显示视图(ListView)必须通过android:layout_gravity指定其水平Gravity属性。为了支持从右到左的语言,应该将android:layout_gravity属性指定为”start”而不是”left”,所以当布局模式为从右到左时抽屉显示在窗口右边。
初始化抽屉列表
在Acitivity里面,应该首先初始化抽屉视图。你如何处理取决于你程序的显示情况。但多数时候抽屉导航都是有ListView组成的,所以应该为抽屉列表指定一个Adapter(比如ArrayAdapter或者SimpleCursonAdapter)。
比如,如下所示的代码将教会你通过字符串数组初始化抽屉导航列表:
- <span style="font-size:18px">public class MainActivity extends Activity {
- private String[] mPlanetTitles;
- private DrawerLayout mDrawerLayout;
- private ListView mDrawerList;
- ...
- @Override
- public void onCreate(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);
- // 为抽屉导航列表设置适配器
- mDrawerList.setAdapter(new ArrayAdapter<String>(this,
- R.layout.drawer_list_item, mPlanetTitles));
- // 为列表点击设置监听器
- mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
- ...
- }
- }
- </span>
上面的代码通过调用setOnItemClickListener()方法监听抽屉导航列表项的点击事件,下面将介绍如何实现这个接口并在选择抽屉列表项时更新内容显示视图。
处理抽屉导航点击事件
当用户选择抽屉列表的某一项时,系统将调用OnItemClickListener接口的onItemClick()方法。
在onItemClick()方法中你做什么取决于如何实现你应用程序的结构,在下面的示例中,每选中列表的一项将在内容显示视图插入一个不同的Fragment(FrameLayout标签通过R.id.content_frame定义):
- <span style="font-size:18px">private class DrawerItemClickListener implements ListView.OnItemClickListener {
- @Override
- public void onItemClick(AdapterView parent, View view, int position, long id) {
- selectItem(position);
- }
- }
- /** 在主视图中切换Fragment */
- private void selectItem(int position) {
- // 创建一个fragment并根据列表项的位置指定fragment的显示内容
- Fragment fragment = new PlanetFragment();
- Bundle args = new Bundle();
- args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
- fragment.setArguments(args);
- // 将该fragement替换掉原fragment
- FragmentManager fragmentManager = getFragmentManager();
- fragmentManager.beginTransaction()
- .replace(R.id.content_frame, fragment)
- .commit();
- // 高亮选中项,更新标题并且关闭抽屉
- mDrawerList.setItemChecked(position, true);
- setTitle(mPlanetTitles[position]);
- mDrawerLayout.closeDrawer(mDrawerList);
- }
- @Override
- public void setTitle(CharSequence title) {
- mTitle = title;
- getActionBar().setTitle(mTitle);
- }
- </span>
监听抽屉打开和关闭事件
通过实现DrawerLayout.DrawerListener接口来监听抽屉的打开和关闭事件。这个接口提供了如onDrawerOpened()和onDrawerClosed()。
除了通过实现DrawerLayout.DrawerListener接口来监听抽屉的打开和关闭事件外,如果你的窗口中包含action bar,你可以通过几成ActionBarDrawerToggle类来实现同样的功能,ActionBarDrawerToggle同样实现了DrawerLayout.DrawerListener接口,但它更利于action和抽屉导航栏的交互(将在下一部分讨论)。
正如在Navagation Drawer设计范式中讨论的一样,你可以在抽屉导航处于可见状态时修改action bar的显示内容,比如改变标题等。下例中的代码展示了怎样通过ActionBarDrawerToggle实例复写DrawerLayout.DrawerListener回调方法。
- <span style="font-size:18px">public class MainActivity extends Activity {
- private DrawerLayout mDrawerLayout;
- private ActionBarDrawerToggle mDrawerToggle;
- private CharSequence mDrawerTitle;
- private CharSequence mTitle;
- ...
- @Override
- public void onCreate(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) {
- /** 在抽屉导航完全处于关闭状态时调用. */
- public void onDrawerClosed(View view) {
- getActionBar().setTitle(mTitle);
- invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
- }
- /** 在抽屉导航完全处于打开状态时调用. */
- public void onDrawerOpened(View drawerView) {
- getActionBar().setTitle(mDrawerTitle);
- invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
- }
- };
- // Set the drawer toggle as the DrawerListener
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- }
- /* Called whenever we call invalidateOptionsMenu() */
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- // If the nav drawer is open, hide action items related to the content view
- boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
- menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
- return super.onPrepareOptionsMenu(menu);
- }
- }
- </span>
通过应用程序图标打开和关闭抽屉
用户可以通过从屏幕左边缘滑动的方式来开启和关闭抽屉导航,如果你同时也使用了action bar,你也需要在当用户点击应用程序图标时实现打开和关闭抽屉导航的功能。也要指定一个特殊的图标来指示抽屉导航的存在,你可以通过使用ActionBarDrawerToggle方法来显示之前的选择。
为了使ActionBarDrawerToggle能够工作,通过其带参构造方法实例化该类,必须包含如下参数:
抽屉导航附属的窗口实例
DrawerLayout实例
指示抽屉的图标资源
描述“打开抽屉”动作的字符串资源
描述“关闭抽屉”动作的字符串资源
然后,你是否创建了一个ActionBarDrawerToggle的子类作为你对抽屉的监听,你需要在你窗口的生命周期回调中调用ActionBarDrawerToggle的相关方法。
publicclassMainActivityextendsActivity{
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
...
public void onCreate(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. */
public void onDrawerClosed(View view){
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView){
getActionBar().setTitle(mDrawerTitle);
}
};
// Set thedrawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
@Override
protected void onPostCreate(Bundle savedInstanceState){
super.onPostCreate(savedInstanceState);
// Syncthe toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
// Passthe event to ActionBarDrawerToggle, if it returns
// true,then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)){
return true;
}
// Handleyour other action bar items...
return super.onOptionsItemSelected(item);
}
...
}
详细地示例请在本页面的顶部下载。
原文:Creating a Navigation Drawer
关于抽屉导航的设计,极客公园的这篇文章不错:Android Design 趋势——Navigation Drawer
第一次翻译文档,难免会有很多错误,呵呵。
抽屉显示控件SlidingDrawer入门的更多相关文章
- echart图表控件配置入门(一)
现在主流的web图表控件主要有hightchart.fusionchart.echart: echart作为百度前端部门近期推出的一个基于html5的免费图表控件,以其丰富图表类型和良好的兼容性速度得 ...
- echart图表控件配置入门(二)常用图表数据动态绑定
上一节 <echart图表控件配置入门(一)>介绍了echarts图表控件的入门配置,使开发人员可以快速搭建出一个静态的图表.但是在实际开发过程这还是不够的,不可能所有的图表控件都是静态数 ...
- BarTender 2016表单中的“秤显示”控件
BarTender 2016中的表单是一个非常实用的工具,它可以实现数据输出提示,查询提示和同一表单的记录选择.这些都离开可供添加的控件,“秤显示”控件也是我们打印尝尝需要涉及的,今天我们就来看看什么 ...
- AvalonEdit-基于WPF的代码显示控件
AvalonEdit是基于WPF的代码显示控件,项目地址:https://github.com/icsharpcode/AvalonEdit,支持C#,javascript,C++,XML,HTML, ...
- [转] 基于C#的波形显示控件的实现
转自 基于C#的波形显示控件的实现[附完整源码下载] 编者记: 09年暑假正好在学院实验室呆了一段时间,做了个完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的 ...
- Expression Blend实例中文教程(4) - 布局控件快速入门Canvas
上一篇,我介绍了Silverlight控件被分为三种类型, 第一类: Layout Controls(布局控件) 第二类: Item Controls (项目控件) 第三类: User Interac ...
- CAD全屏显示控件
主要用到函数说明: MxDrawXCustomFunction::Mx_FullScreen 全屏显示控件,详细说明如下: 参数 说明 int iFull = 2 0: 不完屏,1:全屏,2:自动切换 ...
- 基于C#的波形显示控件的实现[转]
编者记: 09年暑假正好在学院实验室呆了一段时间,做了个完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的数据进行处理和保存,并以图形的方式显示),整个项目边学 ...
- DELPHI中如何让FORM窗体透明,只显示控件?
DELPHI中如何让FORM窗体透明,只显示控件?分享到: 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:7largewanglargewanglargewang等级:Blank ...
随机推荐
- [C++]默认构造函数
默认构造函数(default constructor)就是在没有显示提供初始化式时调用的构造函数.它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义.若个定义某个类的变量时没有提供初始 ...
- oracle实现自增列
手动创建了一个表格,但是id字段无法实现自增,查看了一下网上的信息,没有找到满意的答案.一下是自己总结摸索的,仅供参考 第一步:手动创建表和列中的字段 (本例中,表明 T_VIDEO,第一个字段:ID ...
- nmap使用详解
nmap是一个网络探测和安全扫描程序, 系统管理者和个人可以使用这个软件扫描大型的网络,获取那台主机正在运行以及提供什么服务等信息.nmap支持很多扫描技术,例如:UDP.TCP connect(). ...
- Linux查看机器型号
dmidecode | grep “Product Name”
- kindeditor.net应用
1.网址:http://kindeditor.net/docs/usage.html
- 深入浅出Java并发包—指令重排序
前面大致提到了JDK中的一些个原子类,也提到原子类是并发的基础,更提到所谓的线程安全,其实这些类或者并发包中的这么一些类,都是为了保证系统在运行时是线程安全的,那到底怎么样才算是线程安全呢? Java ...
- 李洪强iOS开发支付集成之支付宝支付
iOS开发支付集成之支付宝支付 下载支付宝SDK 首先是开发包下载,还是比较难发现的,网上以前文章中的链接都打不开,我找了好久才找到的.最新的地址在这里(注意的是下载出来的SDK包里面并没有传说中的开 ...
- lintcode :旋转字符串
题目: 旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdef ...
- switch… case 语句的用法
switch… case 语句的用法 public class Test7 { public static void main(String[] args) { int i=5; switch(i ...
- Mybatis全部查询遇到的返回类型的小问题
在学习Mybatis3过程中遇到一个小问题,觉得需要注意就把它写下来了 在查询所有数据的时候方法是这样的 public List<User> findAll(){ ..... } 在它的u ...