DrawerLayout的基本使用

DrawerLayout

介绍

DrawerLayout作为最顶部的View容器提供侧拉抽屉的功能.他依靠子View的android:layout_gravity属性来决定侧拉抽屉放置的方向.(记得使用start/end来支持不同的布局方向)

要使用DrawerLayout,将其作为你的根布局,然后主内容作为第一个子View添加进来,并且使用match_parent指定高度和宽度,接着侧拉抽屉的内容作为第二个子View添加进来,使用layout_gravity来控制侧拉抽屉放置的方向.一般侧拉抽屉使用match_parent作为高度,并且指定一个确定的宽度.

DrawerLayout.DrawerListener可以用来监听抽屉的动作和状态,避免在抽屉动画的时候执行layout动作等费时的操作,否则会导致卡顿,尽量在STATE_IDLE状态执行这些费时的操作.另外DrawerLayout.SimpleDrawerListener提供了默认的实现,你可以继承他来挑你感兴趣的进行监听.

根据安卓设计规范,任何在左边的抽屉都应该执行导航的操作,任何在右边的抽屉都应该执行对当前内容的一些操作,这个和Action Bar的逻辑相呼应.

例子

创建布局

首先将android.support.v4.widget.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 -->
    <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>
  • 主内容必须是第一个DrawerLayout的子View,因为抽屉要显示在主内容的上方.
  • 主内容View必须设置宽高为match_parent,因为当抽屉隐藏时它代表你整个的UI内容.
  • 抽屉View必须设置androidLlayout_gravity属性为水平方向的值left/right或者为了支持其他水平布局的语言start/end
  • 抽屉View应当指定高度为match_parent,宽度为不大于320dp的值,这样可以保证抽屉显示时也可以看到主内容的一部分.

初始化抽屉的内容

就在Activity的onCreate方法初始化抽屉的内容就可以了,并不需要特殊处理.

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());

        ...
    }
}

监听抽屉的打开和关闭事件

通过你的DrawerLayout对象的setDrawerListener()设置一个DrawerLayout.DrawerListener来监听.
如果你使用Actionbar,那么你可以继承ActionBarDrawerToggle类.这个类也实现了DrawerLayout.DrawerListener接口,所以你还可以通过复写那些回调方法,而且,那个类也自动的帮你处理了action bar图标和抽屉的交互.

根据抽屉使用规范,你应该在抽屉显示的时候改变action bar的内容,例如改变title或者移除相对于主内容上下文关系的action.以下代码展示了你可以通过一个ActionBarDrawerToggle实例来复写DrawerLayout.DrawerListener的回调方法.

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) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); 
            }

            /** 当抽屉彻底打开的时候调用. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); 
            }
        };

        // 把drawer toggle当做DrawerListener一样使用
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* 当我们调用invalidateOptionsMenu()时调用 */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // 当抽屉打开或者隐藏时,加载对应的action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
}

接下来讨论ActionBarDrawerToggle构造函数的参数和处理action bar 图标交互的一些步骤.

随着App图标打开和关闭

用户可以通过侧拉手势打开导航抽屉,但是如果你在使用action bar,那么你也应该允许用户在点击action bar图标时打开和关闭抽屉.并且这个应用图标也应该使用一个特殊的图标来指示导航抽屉的存在.

为了使ActionBarDrawerToggle可以工作,我们还需要加一些代码,以便在特定的时候刷新状态.

public class MainActivity extends Activity {
    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 */
                ) {


            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
            }


            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
            }
        };

               mDrawerLayout.setDrawerListener(mDrawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // 同步状态
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 为了使action bar图标可以响应点击
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    ...
}

摘录翻译自Android Developer

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值