Material Design技术分享

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悬停状态

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只是一个普通的布局。
    侧滑菜单
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值