美文网首页Android收藏集
Material Design技术分享

Material Design技术分享

作者: Funny灬 | 来源:发表于2019-06-17 14:52 被阅读144次

    Material design 的核心思想是把物理世界的体验带进屏幕。去掉现实中的杂质和随机性,保留其最原始纯净的形态、空间关系、变化与过渡,配合虚拟世界的灵活特性,还原最贴近真实的体验,达到简洁与直观的效果。
    Material design引入了z轴的概念,z轴垂直于屏幕,用来表现元素的层叠关系。z值(海拔高度)越高,元素离界面底层(水平面)越远,投影越重。这里有一个前提,所有的元素的厚度都是1dp。所有元素都有默认的海拔高度,对它进行操作会抬升它的海拔高度,操作结束后,它应该落回默认海拔高度。同一种元素,同样的操作,抬升的高度是一致的。

    Toolbar简单使用

    Toolbar结构
     <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:minHeight="?attr/actionBarSize"
                    app:contentInsetStartWithNavigation="0dp"
                    app:layout_collapseMode="pin"
                    app:logo="@drawable/ic_android_white_24dp"
                    app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
                    app:popupTheme="@style/AppTheme.PopupOverlay"
                    app:subtitle="subtitle"
                    app:title="title">
    
            // Logo
            toolbar.setLogo(R.drawable.ic_android_white_24dp);
     
            // 主标题
            toolbar.setTitle("Title");
     
            // 副标题
            toolbar.setSubtitle("subtitle");
            
            //设置toolbar
            setSupportActionBar(toolbar);
     
            //左边的小箭头(注意需要在setSupportActionBar(toolbar)之后才有效果)
            toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
            
             //返回按钮的点击事件
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    finish();
                }
            });
    
            //菜单的点击事件
            mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()){
                        case R.id.action_search:
                            Toast.makeText(ToolbarActivity.this, "search", Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.action_share:
                            Toast.makeText(ToolbarActivity.this, "share", Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.action_setting:
                            Toast.makeText(ToolbarActivity.this, "setting", Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.action_about:
                            Toast.makeText(ToolbarActivity.this, "about", Toast.LENGTH_SHORT).show();
                            break;
                        default:
                            break;
                    }
                    return true;
                }
            });
    

    设置Toolbar的theme,可以让弹窗不遮挡标题栏,处于标题栏的下方。

    <item name="overlapAnchor">false</item>
    
    Toolbar

    AppBarLayout + CollapsingToolbarLayout + Toolbar的使用

    1. CollapsingToobbarLayout常用属性:
    • app:contentScrim设置折叠时工具栏布局的颜色,默认是colorPrimary的色值
    • app:statusBarScrim设置折叠时状态栏的颜色,默认是colorPrimaryDark的色值
    • app:collapsedTitleGravity设置折叠时标题的对齐方式
    • app:expandedTitleGravity设置展开时标题的对齐方式
    • app:titleEnabled设置是否显示标题
    • app:toolbarId设置关联的Toolbar的id
    1. AppBarLayout是一种支持响应滚动手势的app bar布局(比如工具栏滚出或滚入屏幕),CollapsingToolbarLayout则是专门用来实现子布局内不同元素响应滚动细节的布局,CollapsingToolbarLayout是不能独立存在的,它必须只能作为AppBarLayout 的子布局来使用。

    2. 与AppBarLayout组合的滚动布局(Recyclerview、NestedScrollView等)需要设置app:layout_behavior="@string/appbar_scrolling_view_behavior"(上面代码中NestedScrollView控件所设置的)。没有设置的话,AppBarLayout将不会响应滚动布局的滚动事件。

    3. AppBarLayout的子布局有5种滚动标识

    • scroll:将此布局和滚动时间关联。这个标识要设置在其他标识之前,没有这个标识则布局不会滚动且其他标识设置无效。
    • enterAlways:任何向下滚动操作都会使此布局可见。这个标识通常被称为“快速返回”模式。只要向下滑动,布局就完全展开。
    • enterAlwaysCollapsed:假设你定义了一个最小高度(minHeight)同时enterAlways也定义了,那么view将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。向下滑动时,先显示ToolBar,当内容滑动都滑动完时,再显示图片。
    • exitUntilCollapsed:当你定义了一个minHeight,此布局将在滚动到达这个最小高度的时候折叠。ToolBar不会被隐藏。
    • snap:当一个滚动事件结束,如果视图是部分可见的,那么它将被滚动到收缩或展开。例如,如果视图只有底部25%显示,它将折叠。相反,如果它的底部75%可见,那么它将完全展开。
    1. CollapsingToolbarLayout的子布局有3种折叠模式。CollapsingToobarLayout折叠后的高度就是Toorbar的高度。
    • none:这个是默认属性,布局将正常显示。布局会被滑动进去
    • pin:CollapsingToolbarLayout折叠后,此布局将固定在顶部。
    • parallax:CollapsingToolbarLayout折叠时,此布局也会有视差折叠效果。当CollapsingToolbarLayout的子布局设置了parallax模式时,我们还可以通过app:layout_collapseParallaxMultiplier设置视差滚动因子,值为:0~1。

    CollasToolbarLayout + TabLayout的使用

    TabLayout没有设置app:layout_collapseMode,在CollapsingToolbarLayout收缩时就不会消失。
    CollapsingToolbarLayout收缩时的高度是Toolbar的高度,所以我们需要把Toolbar的高度增加,给TabLayout留出位置,这样收缩后TabLayout就不会和Toolbar重叠。
    Toolbar的高度增加,title会相应下移。android:gravity="top"方法使Toolbar的title位于Toolbar的上方,然后通过app:titleMarginTop调整下title距顶部高度,这样Toolbar就和原来显示的一样了。

    展开状态
    折叠状态

    TabLayout悬停

    项目中有时候会遇到这样的UI设计需求,标题 + 头部布局 + 可滑动切换的tab页 + ViewPager(里面的Fragment是可滑动的列表)。

    可以利用AppBarLayout + CollapsingToolbarLayout可折叠的特性,把头部布局折叠起来,呈现出TabLayout在标题栏下方悬停的效果。
    使用AppBarLayout + CollapsingToolbarLayout把头部布局包裹起来,这样 整个头部布局都可以折叠和展开,当头部布局全部折叠时,TabLayout就悬停在标题下面。

    优点:实现简单,代码量少。只需要写XML文件就可以实现该效果,不需要额外写代码来处理滑动事件的冲突。


    TabLayout展开状态
    TabLayout悬停状态

    CardView的使用

    CardView继承自FramLayout。CardView常用属性:

    • app:cardCornerRadius设置四格圆角的半径
    • app:cardBackgroundColor设置背景色,使用android:background设置无效
    • app:cardElevation设置阴影
    • app:cardMaxElevation:设置阴影最大高度
    • android:foreground="?android:attr/selectableItemBackground"设置点击的波纹效果
    • app:contentPadding设备CardView内容的padding,用android:padding设置无效
    • app:cardUseCompatPadding,在Android 5.0及以下的系统中,CardView会添加一个额外的padding来绘制阴影,但是在5.0以上的系统中是没有这个padding的,是直接绘制阴影。所以这个属性只对5.0以上的系统起作用,如果设置为true,则会在卡片与卡片之间增加额外的padding。
    • app:cardPreventCornerOverlap,是否设置卡片和卡片里面内容的padding,只对5.0以下系统起作用,如果设置为false,content与圆角会重叠,圆角被覆盖。

    BottomNavigationView

    1. 主要需要设置五个个属性
    • app:itemBackground背景颜色
    • app:itemTextColor文字颜色
    • app:menu指定菜单文件
    • app:layout_behavior设置滑动行为,可以设置BottomNavigationView上滑消失,下滑显示
    <android.support.design.widget.BottomNavigationView
                android:id="@+id/bottom_navigation"
                style="@style/Widget.Design.BottomNavigationView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_gravity="bottom"
                app:elevation="@dimen/dp_16"
                app:itemBackground="@color/viewBackground"
                app:itemIconTint="@drawable/selector_nav_item_color"
                app:itemTextColor="@drawable/selector_nav_item_color"
                app:layout_behavior="com.example.think.widget.BottomNavigationBehavior"
                app:menu="@menu/bottom_navigation_main"/>
    

    BottomNavigationView可以设置一个OnNavigationItemSelectedListener用来响应切换的动作

     mBottomNavigation.setOnNavigationItemSelectedListener(item -> {
                switch (item.getItemId()) {
                    case R.id.action_news:
                        mToolbar.setTitle(R.string.title_news);
                        NewsFragment newsFragment = NewsFragment.newInstance();
                        switchFragment(newsFragment, R.id.frame_layout);
                        break;
                    case R.id.action_photo:
                        mToolbar.setTitle(R.string.title_photo);
                        PictureFragment pictureFragment = PictureFragment.newInstance();
                        switchFragment(pictureFragment, R.id.frame_layout);
                        break;
                    case R.id.action_video:
                        mToolbar.setTitle(R.string.title_video);
                        VideoFragment videoFragment = VideoFragment.newInstance();
                        switchFragment(videoFragment, R.id.frame_layout);
                        break;
                    case R.id.action_media:
                        mToolbar.setTitle(R.string.title_media);
                        ChannelFragment channelFragment = ChannelFragment.newInstance();
                        switchFragment(channelFragment, R.id.frame_layout);
                        break;
                    default:
                        break;
                }
                return true;
            });
    
    1. 使用BottomNavigationView的问题

    当BottomNavigationView超过三个menu时(三个及三个以下是正常显示的),只有选中的menu会显示图片和文字,其他的menu都只显示图片。且宽度不是均匀分布的,选中的menu宽度比其他的大。

    可以通过一个工具方法解决这个问题

    public  void disableShiftMode(BottomNavigationView navigationView) {
            BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
            try {
                Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
                shiftingMode.setAccessible(true);
                shiftingMode.setBoolean(menuView, false);
                shiftingMode.setAccessible(false);
    
                for (int i = 0; i < menuView.getChildCount(); i++) {
                    BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
                    itemView.setShiftingMode(false);
                    itemView.setChecked(itemView.getItemData().isChecked());
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
    底部导航栏

    DrawerLayout + NavigationView

    DrawerLayout一般有两个子布局,第一子布局是内容布局,第二个子布局为侧滑菜单的布局。也可以有三个布局,第一子布局是内容布局,第二、三个布局分别为左右的侧滑菜单。

    NavigationView,可以自行填充头部布局和菜单布局,还可以再添加任意布局。

    • app:headerLayout指定头布局的布局文件
    • app:menu指定目录xml文件
    • android:layout_gravity,一定要设置这个属性,start表示从左边滑出,可以和Toolbar联动。end表示从右边滑出,不能和Toolbar联动。如果不设置这个属性,NavigationView只是一个普通的布局。


      侧滑菜单

    相关文章

      网友评论

        本文标题:Material Design技术分享

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