美文网首页
MaterialDesign控件之DrawLayout

MaterialDesign控件之DrawLayout

作者: 梦止惰 | 来源:发表于2017-02-20 15:49 被阅读2399次

    今天我们来学习一下DrawLayout控件,以前我们都是使用网上的开源框架slidingMenu,但是在安卓5.0后Google就推出了一个强大的design库,下面对于用法进行详细的介绍:

    一、DrawLayout介绍

    是Support Library包中实现了侧滑菜单效果的控件,可以说drawerLayout是因为第三方控件如MenuDrawer等的出现之后,google借鉴而出现的产物。drawerLayout分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(drawerLayout自身特性),主内容区的内容可以随着菜单的点击而变化(这需要使用者自己实现)。

    二、DrawLayout使用

    DrawLayout一般和NavigationView联合使用,达到侧滑的效果,也可以自己定义侧滑的内容或控件(如侧滑用的内容控件有listView),在这里我的事例使用的是NavigationView,这个控件我们后面会介绍。

    1,首先要添加依赖库,在Android studio项目model setting里面就可以找到:

    com.android.support:design:25.0.1

    2,看布局文件

    <?xml version="1.0" encoding="utf-8"?>
     <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
       <!--这里是主视图-->
        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    <!-这里是侧滑的部分,也可以用其他布局来代替,为了使用design库里面的这里就使用design库的NavigationView--->
        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:itemTextColor="@color/text_color"
            app:menu="@menu/draw_menu"/>
    </android.support.v4.widget.DrawerLayout>
    
    tools:openDrawer的位置可以设置start,end;这两个字段也即是在layout_gravity中表示left和right;但是由于DrawerLayout里面openDrawer只有start,end字段,所以在设置的时候我们就使用start,end
    顺带着说一下android:fitsSystemWindows的作用:

    具体的作用就是你的contentview是否忽略actionbar,title,屏幕的底部虚拟按键,将整个屏幕当作可用的空间。
    正常情况,contentview可用的空间是去除了actionbar,title,底部按键的空间后剩余的可用区域;这个属性设置为true,则忽略,false则不忽略

    1)app_bar_main的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>
    
        </android.support.design.widget.AppBarLayout>
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv"
            android:fillViewport="true"
            android:scrollbars="none"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/add"
            app:backgroundTint="@color/add_bg_color"
            app:elevation="6dp"
            app:fabSize="normal"
            app:pressedTranslationZ="25dp"
            app:rippleColor="@color/add_selected_color"/>
    
    </android.support.design.widget.CoordinatorLayout>
    

    三、NavigationView

    Paste_Image.png

    通过学习官方文档,我们知道NavigationView继承自FrameLayout。一般用于应用的导航菜单,菜单的内容来自于menu文件。NavigationView通常放置在DrawerLayout内部。
    其中:

    • android:fitsSystemWindows的值用于设置状态栏透明化与否。
    • android:layout_gravity可设置抽屉,也就是NavigationView从左边或是右边打开。
    • app:menu用于设置菜单内容的xml布局。
    • app:headerLayout用于设置NavigationView的HeaderView的xml布局文件。
      这里app:headerLayout我写到代码里面的
    编写NavigationView中的menu的xml文件
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_home"
                android:icon="@drawable/nav_icon_home"
                android:title="Toolbar"/>
            <item
                android:id="@+id/nav_favorite"
                android:icon="@drawable/nav_icon_favorite"
                android:title="CardView"/>
            <item
                android:id="@+id/nav_followers"
                android:icon="@drawable/nav_icon_followers"
                android:title="Palette"/>
    
            <item
                android:id="@+id/nav_settings"
                android:icon="@drawable/nav_icon_settings"
                android:title="仿稀土"/>
            <item
                android:id="@+id/nav_style"
                android:icon="@drawable/nav_icon_gift"
                android:title="主题style"/>
    
            <item
                android:id="@+id/night"
                android:icon="@drawable/abc_btn_radio_material"
                android:title="模式切换"
                />
    
        </group>
    
       <!-- <item android:title="分享和反馈">
            <menu>
                <item
                    android:id="@+id/nav_share"
                    android:icon="@drawable/nav_icon_settings"
                    android:title="分享"/>
                <item
                    android:id="@+id/nav_feedback"
                    android:icon="@drawable/nav_icon_settings"
                    android:title="意见反馈"/>
            </menu>
        </item>-->
    
    </menu>
    

    贴出主要代码实现:

        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //ToolBar
            toolbar = (Toolbar) findViewById(R.id.toolbar);
            recyclerView = (RecyclerView) findViewById(R.id.rv);
            //悬浮控件
            fab = (FloatingActionButton) findViewById(R.id.fab);
            //侧滑的DrawerLayout
            drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
            //NavigationView ,侧边栏
            navigationView = (NavigationView) findViewById(R.id.nav_view);
            getData();
            init();
        }
    
        private void getData() {
            datas = new int[]{R.drawable.img_0, R.drawable.img_1, R.drawable.img_2, R.drawable.img_3
                    , R.drawable.img_4, R.drawable.img_5, R.drawable.img_6, R.drawable.img_7
                    , R.drawable.img_8, R.drawable.img_9, R.drawable.img_10, R.drawable.img_11, R.drawable.img_12};
        }
    
        private void init() {
            //向系统设置toolbar
            setSupportActionBar(toolbar);
            //设置线性管理器
            LinearLayoutManager manager = new LinearLayoutManager(this);
            //给recycleView设置布局管理器
            recyclerView.setLayoutManager(manager);
            //若item的布局是固定的,设置这个属性可以提高性能
            recyclerView.setHasFixedSize(true);
            //创建并设置adapter
            adapter = new RecyclerViewAdapter(datas);
            recyclerView.setAdapter(adapter);
            //ActionBarDrawerToggle  是 DrawerLayout.DrawerListener实现,改变android.R.id.home返回图标。
            //.Drawer拉出、隐藏,带有android.R.id.home动画效果。.监听Drawer拉出、隐藏;
            ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
            // drawer.setDrawerListener(toggle);
            //上面的监听被下面的就监听给取代了,由于回报空指针异常,google推出了addDrawerListener(),
            // 对它做了空指针的判断
            drawer.addDrawerListener(toggle);
            //该方法会自动和actionBar关联, 将开关的图片显示在了action上,如果不设置,也可以有抽屉的效果,不过是默认的图标
            toggle.syncState();
            //为侧边栏的每一个子item设置监听
            navigationView.setNavigationItemSelectedListener(this);
            //为NavigationView设置头布局
            View headerView = navigationView.inflateHeaderView(R.layout.header_layout);
            ImageView imageView = (ImageView) headerView.findViewById(R.id.head_iv);
            imageView.setOnClickListener(this);
            //为悬浮控件设置监听
            fab.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.fab://悬浮控件
                    final Snackbar snackbar = Snackbar.make(view, "关注PANDA,赢得好礼!", Snackbar.LENGTH_LONG);
                    snackbar.show();
                    snackbar.setAction("关注站点", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            snackbar.dismiss();
                        }
                    });
                    break;
                case R.id.head_iv:
                    // TODO: 2017/2/20 进行头像的拍照和从相册中读取的操作
                    break;
            }
        }
    
    
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            //找到MenuItem的id
            int id = item.getItemId();
            switch (id) {
                case R.id.nav_home:
                    break;
                case R.id.nav_favorite:
                    break;
                case R.id.nav_followers:
                    break;
                case R.id.nav_settings:
                    break;
                case R.id.nav_style:
                    break;
                case R.id.night:
                    break;
            }
            drawer.closeDrawer(GravityCompat.START);
            return true;
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.recycle_menu, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            int itemId = item.getItemId();
            item.setChecked(true);
            switch (itemId) {
                case R.id.list://常规的listView列表
                    LinearLayoutManager manager = new LinearLayoutManager(this);
                    recyclerView.setLayoutManager(manager);
                    adapter.notifyDataSetChanged();
                    break;
                case R.id.grid://网格布局
                    GridLayoutManager  manager1= new GridLayoutManager(this, 2);
                    manager1.setOrientation(GridLayoutManager.VERTICAL);
                    recyclerView.setLayoutManager(manager1);
                    adapter.notifyDataSetChanged();
                    break;
                case R.id.stagger://瀑布流
                    StaggeredGridLayoutManager manager2 = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
                    recyclerView.setLayoutManager(manager2);
                    adapter.notifyDataSetChanged();
                    break;
            }
            return super.onOptionsItemSelected(item);
        }
      //按物理返回键的时候,收缩侧边栏
        @Override
        public void onBackPressed() {
            if(drawer.isDrawerOpen(GravityCompat.START)){
                drawer.closeDrawer(GravityCompat.START);
            }else {
                super.onBackPressed();
            }
        }
    

    最后来看看效果:


    Paste_Image.png

    相关文章

      网友评论

          本文标题:MaterialDesign控件之DrawLayout

          本文链接:https://www.haomeiwen.com/subject/sxcewttx.html