MaterialDesign设计(中)

上一节主要是讲解MaterialDesign的一些简单案例,接下来要讲的是一个比较复杂的案例:CoordinatorLayout.实际上,它就是一个类似于5大布局的viewgroup.下面我们要实现的案例如下:

1.要展示上面的界面 需要在app的build.gradle中添加依赖脚本:

compile ‘com.android.support:design:25.3.1‘

2.找到对应的布局,添加代码:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- 创建顶部图片控件 AppBarLayout其父类是LinearLayout -->
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!-- 这是内部的一个可以帮助我们上拉折叠的界面 -->
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="fitXY"
                android:src="@drawable/lf" />
        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <!-- 创建底部可以滑动的文本界面 -->
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/content"/>
    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

如果细心一点你会发现我们的界面是没有ActionBar的 于是在styles.xml中修改如下:

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

于是界面展示如下,:

有没发现 文本被前面的图片控件隐藏掉了,显示不全,我们希望文字就显示在图片控件下。点击外部布局 可以看到CoordinatorLayout实际上是ViewGroup的子类。此时只需要在标签中添加一个属性layout_behavior即可达到想要的效果:

<android.support.design.widget.CoordinatorLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"  >
    <android.support.v4.widget.NestedScrollView
        app:layout_behavior="@string/appbar_scrolling_view_behavior" >
    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

现在效果差不多了 然后滑动的时候发现只有底部的文本控件才能滑动,为了让顶部的界面也可以跟着滑动,需要可折叠的控件CollapsingToolbarLayout添加一个属性:

app:layout_scrollFlags="scroll"

layout_scrollFlags的几个属性

  1. 除了scroll可以实现滑动之外,还有一个属性值enterAlways,添加了该属性后,如果你上面的图片被隐藏了,并且字体的上部分也被隐藏了,此刻下拉,不会按着顺序展示出来,而是每次都先展示完图片,再显示被隐藏的字体。

    app:layout_scrollFlags=”scroll|enterAlways”

2.还有一个属性,叫enterAlwaysCollapsed,该属性需要配合enterAlways一起属性,并且需要指定minHeight.代码如下:

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="100dp"
        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" />

上面的代码运行效果是如下,下拉显示的时候 先显示特定的高度的图片,在慢慢显示文字,当文字显示到顶部的时候如下还往下拉,则会完全显示图片:

3.这里还有另外一个属性值exitUntilCollapsed。他可以帮助我们在上拉的过程中隐藏图片控件的只一部分。如下的代码,我们在上拉过程中图片会被部分隐藏,直到剩下高度的100dp位置可以停止隐藏,接着隐藏文字。

   <android.support.design.widget.CollapsingToolbarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:minHeight="100dp"
       app:layout_scrollFlags="scroll|exitUntilCollapsed" >

当然,为了达到我们上面案例的样子,需要去掉android:minHeight属性。

视差

在上拉的过程中,你会发现滑动的距离远大于图片被隐藏的距离。也就是图片是按着我们往上滑的距离进行比例隐藏的,这就是视差,如何设置才属性了,找到对应的图片添加属性即可 代码如下:

 <ImageView
     android:layout_width="match_parent"
     android:layout_height="200dp"
     android:scaleType="fitXY"
     android:src="@drawable/lf"
     app:layout_collapseMode="parallax"
     app:layout_collapseParallaxMultiplier="0.8" />

layout_collapseMode设置了parallax属性值代表以视差的方式滑动 下面的layout_collapseParallaxMultiplier属性指定了视差值的比例为0.8。

添加工具栏

为了让界面在上拉的过程中展示工具栏 这里需要给它添加一个ToolBar,因为CollapsingToolbarLayout是FrameLayout的子类,所以只需要在ImageView后面添加一个ToolBar则会覆盖在图片上面显示。?android:attr/actionBarSize高度指定的是工具栏的高度为系统ActionBar高度。

<android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed" >
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="fitXY"
                android:src="@drawable/lf"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.8" />

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                android:background="@color/colorPrimary" />

        </android.support.design.widget.CollapsingToolbarLayout>

上面的代码运行后,会发现工具栏跟着滑动一起被隐藏了实际上我们希望他置顶,那么应该添加滑动置顶的属性。那么你会想到的就是layout_collapseMode。pin值就是让某个控件可以在滑动的时候置顶的。并且一开始ToolBar是没有显示出来的,所以应该将颜色去掉。代码如下:

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        app:layout_collapseMode="pin" />

为了让图片在向上拉的过程中,逐渐渐变成某单一色块,那么我们需要为CollapsingToolbarLayout添加一个新的属性contentScrim并指定一个颜色值:

  <android.support.design.widget.CollapsingToolbarLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:layout_scrollFlags="scroll|exitUntilCollapsed"
      app:contentScrim="@color/colorPrimary">

添加字体

图片中间本来是有字体的,那么他是如何实现的呢?

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:contentScrim="@color/colorPrimary"
        app:title="I like Lufu !"
        app:expandedTitleMarginStart="200dp"
        app:expandedTitleMarginEnd="0dp" >
  1. title指定标题文本
  2. expandedTitleMarginStart指定文本还没上滑时距离左边的间距
  3. expandedTitleMarginEnd指定滑动后距离左边的间距

字体是黑色的是不是很难看,可以指定字体样式 首先在style.xml文件中定义样式:

<style name="TextStyle" parent="TextAppearance.Design.CollapsingToolbar.Expanded">
    <item name="android:textColor">@android:color/white</item>
    <item name="android:textSize">18sp</item>
</style>

在CollapsingToolbarLayout控件中指定属性:

app:expandedTitleTextAppearance="@style/TextStyle"

添加FloatingActionButton

从图中可以看出该控件是在两个大的容器中间,也是在CoordinatorLayout的内部。实际上他有一个锚点的概念,就是根据界面存在的某个控件来布局的。代码如下:

<android.support.design.widget.CoordinatorLayout  >

    <!-- 创建顶部图片控件 AppBarLayout其父类是LinearLayout -->
    <android.support.design.widget.AppBarLayout
        ...
        android:id="@+id/appbar">

    </android.support.design.widget.AppBarLayout>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:fabSize="mini"
        android:src="@mipmap/ic_launcher"
        app:backgroundTint="@color/colorPrimary"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|center_horizontal" />
</android.support.design.widget.CoordinatorLayout>
  1. layout_anchor指定以某一个控件来布局
  2. layout_anchorGravity指定在该控件的某个位置。

自定义布局依赖

接下来我们要重新回去理解scrollView的layout_behavior属性。该属性接收一个字符串,帮我们滑动scrollView的时候,顶部的appbarlayout也跟着移动。接下来我们学习下如何自定义一个layout_behavior。

实际上,这里我们要做的就是让图片移动,只要图片一移动 文本也跟着一起移动。这个操作如何实现呢,首先看下布局,这里我们还是使用CoordinatorLayout布局(翻译过来叫协调者布局 通过他来协调内部的操作)。

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_behavior="com.example.demo.MyBehavior"
        android:text="aaaaaaaaaa" />
</android.support.design.widget.CoordinatorLayout>

注意到了上面的图片控件,随着手指的移动而移动,我们的代码很简单,这里不做过多解释,至于TextView的layout_behavior属性如何配置,后面会讲到:

public class BehaviorActivity extends AppCompatActivity implements View.OnTouchListener {

    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_behavior);

        iv = (ImageView) findViewById(R.id.iv);
        iv.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction()==MotionEvent.ACTION_MOVE){
            iv.setX(event.getRawX());
            iv.setY(event.getRawY());
        }
        return true;
    }
}

现在的重点来了,怎么让文本控件跟图片控件一起移动呢,经过分析:

文本控件:时刻观察图片控件的行为(观察者)

图片控件:被文本控件监听的对象(被观察者)

接下来我们需要创建一个类,用来绑定这2个对象。

/**
 * Behavior<TextView> 内部的泛型就是观察者的类型
 */
public class MyBehavior extends CoordinatorLayout.Behavior<TextView> {

    /**
     * 默认需要实现如下两个构造器
     * */
    public MyBehavior() {
    }

    public MyBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 告诉系统我们要监听的对象是ImageView的图片控件
     * 实际上一个容器可能有多个图片控件 我更愿意使用tag属性来区别某个具体的控件
     * @param dependency 被观察者对象
     * @param child 观察者对象
     * */
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
        return dependency instanceof ImageView;
    }

    /**
     * 拿到被观察者对象的x y坐标,并计算出观察者的x y坐标
     *
     * @param dependency 被观察者对象
     * @param child 观察者对象
     * */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
        float x = dependency.getX();
        float y = dependency.getY();
        child.setX(x);
        child.setY(y+10+dependency.getHeight());
        return true;
    }
}

写完该类后,需要将该类配置到布局文件中,实际上也就是将类的全路径的字符串添加到观察者的标签中,这里指的就是TextView.

<TextView
    android:id="@+id/tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_behavior="com.example.demo.MyBehavior"
    android:text="aaaaaaaaaa" />

说到这里已经把该Demo写完了。接下来再来看看第一个Demo中为何添加一个字符串就能让头部的AppBarLayout跟着一起移动的。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

实际上该字符串指定的就是ScrollingViewBehavior类。让我们看看该类2个重要的方法吧,从下面可以看出,被观察者实际上就是AppBarLayout,也就是系统内部会根据AppBarLayout做出对应的调整。

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
    // We depend on any AppBarLayouts
    return dependency instanceof AppBarLayout;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
        View dependency) {
    offsetChildAsNeeded(parent, child, dependency);
    return false;
}
时间: 2024-10-12 00:00:27

MaterialDesign设计(中)的相关文章

杭州软装设计师必知灯光知识-灯光构成在室内设计中的运用

与办公室内环境相比,居室中灯光多为暖调,一般以白炽为主,居室给光应注意均匀柔和,然后再根据居室的不同功能具体布置光源,尽量减少荧光灯的使用,荧光灯光线偏冷,易破坏室内温馨气氛.所以,灯光的合理和谐的应用会为整个室内设计起到锦上添花的作用,灯光运用的不恰当,会造成成个设计的失败.今天,杭州五色光软装就给大家讲讲灯光在软装设计运用中的意义: 1.光表现情感.性格 可以运用"光"表现情感,性格的特点.表现室内的气氛.如光照度强表现了明快热烈,激情.公平等性格.而光照度弱时,则表现出沉闷阴暗,

数字设计中的时钟与约束

最近做完了synopsys的DC workshop,涉及到时钟的建模/约束,这里就来聊聊数字中的时钟(与建模)吧.主要内容如下所示: ·同步电路与异步电路: ·时钟/时钟树的属性:偏移(skew)与时钟的抖动(jitter).延时(latency).转换(transition)时间: ·内部时钟: ·多路复用时钟: ·门控时钟: ·行波时钟: ·双沿时钟: ·Design Compiler中的时钟约束. 1.同步电路与异步电路 首先来谈谈同步电路与异步电路.那么首先就要知道什么是同步电路.什么是

设计趋势:网页设计中的幽灵按钮

幽灵按钮——那些透明的.可点击的物体——忽然间就变得无处不在.以狂风暴雨之势席卷正网页设计领域.谁能想到,像按钮这么简单的事物,能够改变我们看待网页设计的方式? 参考:预测网页设计趋势 什么是幽灵按钮? 幽灵按钮有着最简单的扁平外形——正方形.矩形.圆形.菱形——没有填充色,只有一条淡淡的轮廓.除了外框和文字,它完完全全(或者说几乎完全)透明.(因此得名“幽灵”) 这些按钮通常比网页上传统的可点击按钮大,也被置于显要位置,例如屏幕的正中央. 各种类型的网站(包括移动APP)中都能发现幽灵按钮的身

在Java API设计中,面向接口编程的思想,以及接口和工厂的关系

现在的java API的设计中,提倡面向接口的编程,即在API的设计中,参数的传递和返回建议使用接口,而不是具体的实现类,如一个方法的输入参数类型应该使用Map接口,而不是HashMap或Hashtable等具体的实现类.这样做的好处是,程序容易扩展.如果使用Map作为参数,用户可以使用任何实现Map接口的类作为参数,而不是仅仅限制使用HashMap或Hashtable作为参数,使程序的实现更加灵活. 接口(Java的Interface),只定义了一些抽象的方法(也可以定义一些常量,但不鼓励这么

移动应用交互设计中合理使用动态

一个优秀的交互师可以轻松地解释每一个动作逻辑背后的设计概念,包括信息框架,页面内容的继承,每一个点击动作对于页面跳转的影响等. 不久的将来,动效将被广泛的引入到原型的概念设计当中,然而随之带来的是交互设计方案的确定与分析变得越来越复杂.影响这些决定的原因当中,诸如“这样看起来很 炫”,“这样看酷”等等,将会让动效设计失去了它本来的目的.接下来,我们将试着站在用户体验的角度来定义动效设计,以及解释引入动效设计的目的. 什么是功能性的动效? 功能性的动效就是被我们引入到交互设计当中的微动效(moti

产品设计中,场景很重要

今天笔者想简单的和你们聊聊产品设计中的场景问题.首先抛出一个问题,产品设计时是否需要考虑到用户的使用场景? 首先,假设我们需要考虑到用户的使用场景,那么我们再抛出另一个问题:为什么要考虑到用户的使用场景? 让我们换个角度想想这个问题,我们现在使用的最多的电子产品是什么?是手机.无论我们是在挤公交,还是走路,吃饭,甚至是上厕所,无时无刻,我们都在使用手机,那么问题又来了:我们在使用手机的什么?收发信息?接听电话?不,是聊天上网玩游戏,这些无非都要使用到APP.而APP的使用是有多场景化的,不像传统

数据库设计中的Soft Delete模式

最近几天有点忙,所以我们今天来一篇短的,简单地介绍一下数据库设计中的一种模式——Soft Delete. 可以说,该模式毁誉参半,甚至有非常多的人认为该模式是一个Anti-Pattern.因此在本篇文章中,我们不仅仅会对该模式进行介绍,同时也会列出该模式可能导致的一系列问题,以帮助大家正确地决定是否使用该模式. Soft Delete简介 首先先来想一个需求,那就是对用户操作的回滚支持.例如我现在正在用Word编写这篇文章.当我执行了一个错误操作的时候,我仅仅需要键入Ctrl + Z就可以进行回

unity3f游戏开发之游戏设计中运营重用体系

游戏设计中,运用重用体系重用资源包括有以下几个设计目的: 1).方便玩家识别 为了方便玩家识别某一类游戏中的要素,而采用的设计目的.如某种某种动物的皮毛的道具图标.为了区分不同,除了基本图素相同外,不同之处只是以变换颜色和更改名称加以区分,这样可以方便玩家快速识别图标. 2).降低客户端的容量 游戏中最占用硬盘空间的,其实是大量的资源,如模型文件.贴图等美术资源文件.为了降低客户端的容量,开发者除了要采用压包技术进行资源压包外,在设计的过程中,设计师还要考虑到客户端容量大小的问题(特别是某些2D

网页设计中的切图

一般的网站制作步骤大体上为:设计效果图–>切图+制作静态html模板–>嵌套至CMS,其中,切图虽然是很简单的一个步骤,但其中也有很多技巧,以下是我个人总结出来的几点. 总体上,把握一个原则,能用css写的,坚决不要用图片. 经验告诉我们,首页图片很多的网站打开会很慢,一是因为图片多,需要下载的文件体积就增大,二是每一个图片下载都会对服务器有一个请求,增大了浏览器与服 务端的交互次数,如果能把纯色的部分用css来写,而不因为省事直接切图,就会极大提高网站的运行效率,我最早开始学习制作网站时,就

游戏设计中的道德

最近一直在思考一些关于游戏设计方面的问题.入行已经两年了,以前跟所有刚入行的朋友一样,一直想着怎么从自己设计的游戏中赚钱.怎么让玩家为我的劳动成果买单.当然,我并不是说这样不好,因为只要形成一个良性的循环,优秀的游戏才会持续不断的出现,君不见,几年前国内还是有很多优秀的单机游戏的,但是由于破解的存在,以及中国人在几年前还有着"我都花钱买了电脑了,难道软件还要钱吗?更别提游戏了."这些众所周知的原因,现在中国的市场上已经很难看到新的优秀单机游戏的出现了,还好手游平台拓宽了国内的游戏市场,