[Android]Android Design之Navigation Drawer

概述

在以前ActionBar是Android 4.0的独有的,后来的ActionBarSherlock的独步武林,对了还有SlidingMenu,但是这个可以对4.0下的可以做很好的适配。自从Google Io大会(去年的,今年过几天也要开始了)。

看知乎日报,豆瓣这些应用明显感觉到Android Design的风格。

效果

image

左侧是可以滑出来的SlidingMenu,后面的则是我们的内容视图,这样可以吧我们的常用的一些操作放到这个Navigation Drawer.不过这个交互有个比较别扭的是Navigation打开时必须手指贴着最左侧,不过这也增加了和IOS的差异。

 

对于开发者而言,这些都是浮云。对我们最大的好处就是,我们的V4已经开始支持这个Navigation Drawer。由于我是后知者,所以写的一些东西可能是基础的东西,不过我会把我认识的一些东西都做个分享。

 

 

 

使用

由于google被zf给墙了,Android Developer访问不太稳定,我就将就着用本地的Doc文档来处理做一个简单的翻译吧。

文档地址{Sdk目录}/docs/training/implementing-navigation/nav-drawer.html

这个Demo使用是在刚才就是知乎日报的一个Demo版:

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



        // Set the adapter for the list view

        mDrawerList.setAdapter(new ArrayAdapter<String>(this,

                R.layout.drawer_list_item, mPlanetTitles));

        // Set the list's click listener

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());



        ...

    }

}

附上布局文件:

<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>

 

其中content_frame是个内容面板,我们可以从Fragmeng来填充。而这个listVIew就是我们左侧可以滑动的抽屉视图(现在是一个ListView)。

注意事项:

  1 内容视图必须是DrawerLayout的第一个子视图。原因在于 XML 布局文件中的View顺序为Android系统中的 z-ordering顺序,而Navigation Drawer必须出现在内容之上。

2 内容视图必须填充父组件填充这个视图,因为当Drawer隐藏时,所展示的就是我们的内容视图。

3、Navigation Drawer 必须使用android:layout_gravity属性设置水平的 gravity值 .如果要支持 right-to-left (RTL,从右向左阅读)语言 用 "start" 代替 "left" (当在 RTL语言运行时候,菜单出现在右侧)。

 

4、抽屉菜单的宽度为 dp 单位而高度和父View一样。抽屉菜单的宽度应该不超过320dp,这样用户可以在菜单打开的时候看到部分内容界面。

由于Navigation Drawer展开和关闭时,有相关的toggle,这个是由DrawerLayout.DrawerListener来处理的。

  mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,

                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {



            /** Called when a drawer has settled in a completely closed state. */

            public void onDrawerClosed(View view) {

                getActionBar().setTitle(mTitle);

                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()

            }



            /** Called when a drawer has settled in a completely open state. */

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

    }

展开和关闭时的图标又不太一样:

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 the drawer toggle as the DrawerListener

        mDrawerLayout.setDrawerListener(mDrawerToggle);



        getActionBar().setDisplayHomeAsUpEnabled(true);

        getActionBar().setHomeButtonEnabled(true);

    }



    @Override

    protected void onPostCreate(Bundle savedInstanceState) {

        super.onPostCreate(savedInstanceState);

        // Sync the 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) {

        // Pass the event to ActionBarDrawerToggle, if it returns

        // true, then it has handled the app icon touch event

        if (mDrawerToggle.onOptionsItemSelected(item)) {

          return true;

        }

        // Handle your other action bar items...



        return super.onOptionsItemSelected(item);

    }

 

对了,漏了一段翻译,就是左侧的为啥是listview,这个问题不是问题,那需要填充一个view,这个view可以使GridView,scrollview等,随意吧,只要有内容就行。

你可能感兴趣的:(android)