zoukankan      html  css  js  c++  java
  • android开发(38) 使用 DrawerLayou t实现左侧抽屉式导航菜单

    最近流行 左侧抽屉式的导航条菜单,知乎,360,QQ都使用了这样的导航菜单,我们也了解下:

      Android Design 的流行趋势:Navigation Drawer 导航抽屉

    参考这篇文章:http://www.geekpark.net/topics/183724

    效果图:

                     

    特点

      1.标题栏(或者actionBar) 做的有个 菜单图标按钮(三条线或者其他)。一般这样的标题栏左侧和右侧都会有图标按钮。如图1所示。

      2.点击图标按钮 从左侧向右 慢慢退出一个 菜单视图(View),遮盖在 内容页(首页)的视图上,同时,产生遮盖层。如图2所示。

    怎么实现?

      官方示例

        参考自谷歌开发者网站的示例,在这个页面可以下载到示例。http://developer.android.com/training/implementing-navigation/nav-drawer.html

      引用类库

        需要android-support-v4.jar

      主要控件

        谷歌提供的抽屉控件: android.support.v4.widget.DrawerLayout

        参考这片文章的解释:http://blog.csdn.net/xiahao86/article/details/8995827

    具体实现

      首页(比如叫:MainActivity)内容布局,写一个 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" >
    
        <!--
             As the main content view, the view below consumes the entire
             space available using match_parent in both dimensions.
        -->
    
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <!--
             android:layout_gravity="start" tells DrawerLayout to treat
             this as a sliding drawer on the left side for left-to-right
             languages and on the right side for right-to-left languages.
             The drawer is given a fixed width in dp and extends the full height of
             the container. A solid background is used for contrast
             with the content view.
        -->
    
        <zyf.demo.navigationdrawer.NavigationMenu
            android:id="@+id/navigation_menu"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start" >
        </zyf.demo.navigationdrawer.NavigationMenu>
    
    </android.support.v4.widget.DrawerLayout>

    我在这里写了个自定义控件 “ zyf.demo.navigationdrawer.NavigationMenu " ,注意它的 android:layout_gravity="start" ,是 start 不是left。

    MainActivity需要获得为DrawerLayout 注册一个回调事件接口ActionBarDrawerToggle ,这个事件的实现者监听器会获得 抽屉弹出(onDrawerOpened)和关闭(onDrawerClosed)的事件。

    MainActivity 的代码

    package zyf.demo.navigationdrawer;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.content.res.Configuration;
    import android.graphics.drawable.ColorDrawable;
    import android.support.v4.app.ActionBarDrawerToggle;
    import android.support.v4.widget.DrawerLayout;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
        private NavigationMenu mNavigationMenu;
        private DrawerLayout mDrawerLayout;
        private ActionBarDrawerToggle mDrawerToggle;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 获得抽屉控件
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            // 获得菜单控件
            mNavigationMenu = (NavigationMenu) findViewById(R.id.navigation_menu);
            mNavigationMenu.attacthDrawer(mDrawerLayout);
    
            // enable ActionBar app icon to behave as action to toggle nav
            // drawer
            getActionBar().setDisplayHomeAsUpEnabled(true);
            // 使actionbar 的logo图标透明不可见
            getActionBar().setIcon(
                    new ColorDrawable(getResources().getColor(
                            android.R.color.transparent)));
    
            // 注册导航菜单抽屉 的弹出和关闭事件
            mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
            mDrawerLayout, /* DrawerLayout object */
            R.drawable.ic_notification_content, /*
                                                 * nav drawer image to replace 'Up'
                                                 * caret
                                                 */
            R.string.drawer_open, /* "open drawer" description for accessibility */
            R.string.drawer_close /* "close drawer" description for accessibility */
            ) {
                // 当导航菜单抽屉 关闭后
                public void onDrawerClosed(View view) {
                    // 显示当前内容页的标题
                    getActionBar().setTitle(getTitle());
                    invalidateOptionsMenu(); // creates call to
                                                // onPrepareOptionsMenu()
                }
    
                // 当导航菜单抽屉 打开后
                public void onDrawerOpened(View drawerView) {
                    // 显示导航菜单的标题
                    getActionBar().setTitle(mNavigationMenu.getTitle());
                    invalidateOptionsMenu(); // creates call to
                                                // onPrepareOptionsMenu()
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            // 显示首页的内容
            showFragment(new HomeFragment());
            
            // 当更换主页内的 子页面(fragment)时,隐藏导航菜单
            mNavigationMenu.hide();
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.main, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        /* 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
            // 当弹出导航菜单时,使 actionbar的扩展按钮不可见
            boolean drawerOpen = mDrawerLayout.isDrawerOpen(mNavigationMenu);
            menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
            return super.onPrepareOptionsMenu(menu);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // The action bar home/up action should open or close the drawer.
            // ActionBarDrawerToggle will take care of this.
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle action buttons
            switch (item.getItemId()) {
            case R.id.action_websearch:
                Toast.makeText(this, "你点击了搜索按钮", Toast.LENGTH_LONG).show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }
    
        private void showFragment(Fragment fragment) {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame, fragment).commit();
        }
    
        @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);
            // Pass any configuration change to the drawer toggls
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    
    }

    下面给出我写的自定义控件的实现:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        
     <ListView
            android:id="@+id/listView1"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:choiceMode="singleChoice"
    
            android:background="#FFFFFF"/>
    </RelativeLayout>
    package zyf.demo.navigationdrawer;
    
    import android.content.Context;
    import android.support.v4.widget.DrawerLayout;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.Toast;
    
    public class NavigationMenu extends RelativeLayout {
        LayoutInflater mLayoutInflater;
        ListView mlistView1;
        String[] menuItemsDataSource;
        private DrawerLayout mDrawerLayout;// 关联到的抽屉控件
    
        public NavigationMenu(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initLayout(context);
        }
    
        public NavigationMenu(Context context, AttributeSet attrs) {
            super(context, attrs);
            initLayout(context);
        }
    
        public NavigationMenu(Context context) {
            super(context);
            initLayout(context);
        }
    
        private void initLayout(Context context) {
            mLayoutInflater = LayoutInflater.from(context);
            View contentView = mLayoutInflater.inflate(R.layout.navigation_menu,
                    null);
            RelativeLayout.LayoutParams lp = new LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            this.addView(contentView, lp);
    
            mlistView1 = (ListView) contentView.findViewById(R.id.listView1);
            menuItemsDataSource = getResources().getStringArray(
                    R.array.navigation_menu_items_array);
    
            mlistView1.setAdapter(new ArrayAdapter<String>(context,
                    R.layout.navaigation_menu_list_view_item, menuItemsDataSource));
            mlistView1.setOnItemClickListener(new DrawerItemClickListener());
        }
    
        /**
         * 包含 的 listView的点击事件
         * @author yunfei
         *
         */
        private class DrawerItemClickListener implements
                ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                // selectItem(position);
    
                mlistView1.setItemChecked(position, true);
                hide();
    
                Toast.makeText(getContext(), "你选择了" + position, 0).show();
            }
        }
    
        
        public CharSequence getTitle() {
            return "导航菜单";
        }
    
        /**
         * 关联到 drawerLayout
         * @param drawerLayout
         */
        public void attacthDrawer(DrawerLayout drawerLayout) {
            mDrawerLayout = drawerLayout;
        }
    
        /**
         * 隐藏
         */
        public void hide() {
            if (mDrawerLayout != null)
                mDrawerLayout.closeDrawer(NavigationMenu.this);
        }
        
        /**
         * 出现
         */
        public void show() {
            if (mDrawerLayout != null)
                mDrawerLayout.openDrawer(NavigationMenu.this);
        }
        
        
    }

    代码下载: http://yunpan.cn/cggiDkFNCp2Jw 访问密码 c3ed

    参考:

    http://blog.csdn.net/xiahao86/article/details/8995827
    http://developer.android.com/training/implementing-navigation/nav-drawer.html
    http://www.geekpark.net/topics/183724

      

      

  • 相关阅读:
    五、Java对象和类
    四、JavaString字符串
    三、Java语句
    二、Java基本数据类型
    一、Java主类结构
    bat常用命令
    iOS 如何获得app的版本和系统的版本
    英语----时态---将来时态的四种对比
    英语----时态---将来时态的
    英语----时态---现在进行时与过去进行时
  • 原文地址:https://www.cnblogs.com/vir56k/p/3990227.html
Copyright © 2011-2022 走看看