MaterialDesigner学习笔记

MaterialDesigner介绍

Material Design 是一种独一无二的底层系统,在这个系统的基础之上,构建跨平台和超越设备尺寸的统一体验。遵循基本的移动设计定则,同时支持触
摸、语音、鼠标、键盘等输入方式

特点

Material Design 有以下的特点:
1. 实体感的操作
2. 鲜明、形象的视觉效果
3. 有意义的动画效果

MaterialDigner样式

新增样式
@android:style/Theme.Material
@android:style/Theme.Material.Light
@android:style/Theme.Material.Light.DarkActionBar

自定义样式

属性

xml中修改:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
代码中修改样式:

//注意版本适配
Window window = getWindow();
window.setStatusBarColor(ContextCompat.getColor(this, R.color.colorBlue));
window.setNavigationBarColor(ContextCompat.getColor(this, R.color.colorGreen));

新增高度属性

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="版本21"
        //新增的高度属性,可以通过该属性来控制显示的图层
        android:translationZ="100dp"
        //与高度相关的属性:阴影,注意只有在设置了背景以后才能有效果
        android:elevation="10dp"
        />

新增波纹触摸反馈

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        //没有边界的波纹
        android:background="?android:attr/selectableItemBackgroundBorderless"
        //到控件边界自动消失的波纹
        android:background="?android:attr/selectableItemBackgroundBorder"
        android:text="版本21"/>

布局中@和?的区别

与往常不同,在引用波纹反馈时用到了?而不是@
那么?和@的区别是什么呢?

通常我们都是通过@去获取一个,这些属性有一个特点,都是写死的.
那如果我们想获取一个与手机主题相关的属性怎么办?
这就是?的作用,为了解决这个问题.

为了和当前的系统主题保持一致,我们常常需要获取当前应用主题与系统主题的一些属性,这些属性是会根据主题的变化发
生变化,所以我们不能使用@符号取,@符号是取某个固定的值。在这种情况下面,我们需要使用?,?符号代表在当前的主题下面去获取值。

实践

定义一个属性

//res/values/attrs.xml
<resources>
    <declare-styleable name="show">
        <attr name="myTextColor" format="color"/>
    </declare-styleable>
</resources>

在主题中设置该属性

//res/values/styles
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--设置该属性-->
        <item name="myTextColor">@android:color/holo_red_light</item>
    </style>
</resources>

在控件中引用该属性

    <TextView
        android:textColor="?attr/myTextColor"
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:text="TextView"/>

版本适配

静态版本适配

//5.0以后会优先从该目录读取layout文件
res/右键/Direct/layout-v21

动态版本适配

        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setNavigationBarColor(Color.RED);
            getWindow().setStatusBarColor(Color.GREEN);
        }

CardView控件

CardView 是MD提供的一种带圆角、阴影的容器。

引包

    compile 'com.android.support:cardview-v7:25.+'

属性

    <android.support.v7.widget.CardView
        //背景颜色
        app:cardBackgroundColor="@android:color/holo_purple"
        //圆角半径大小
        app:cardCornerRadius="13dp"
        //阴影大小
        app:cardMaxElevation="100dp" >
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/content"
                android:textColor="@android:color/black"
                android:textSize="22sp"
            />
        </ScrollView>
    </android.support.v7.widget.CardView>

TextInputLayout

提供更加友善的界面.TextInputLayout可以作
为EditText的父控件,能够将提示上浮,并自带文本字数控制的功能.

引包

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

属性

    <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout"
        //提示文本
        android:hint="提示文本"
        //开启提示文本的动画效果
        app:hintAnimationEnabled="true"
        //是否开启长度计数
        app:counterEnabled="true"
        //设置最大长度
        app:counterMaxLength="10"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </android.support.design.widget.TextInputLayout>

错误提示

public class TextInputLayoutActivity extends AppCompatActivity {

    @BindView(R.id.et)
    EditText mEt;
    @BindView(R.id.text_input_layout)
    TextInputLayout mTextInputLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_input_layout);
        ButterKnife.bind(this);
        mEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
            //edittext 设置error
                if (s.length()>10){
                    mEt.setError("请输入10以内的文本");
                }else {
                    mEt.setError(null);
                }

            }
        });
    }
}

自定义错误提示样式

//res/values/style
<resources>
    <style name="myError" parent="TextAppearance.Design.Error">
        <item name="android:textSize">33sp</item>
        <item name="android:textColor">@android:color/holo_purple</item>
    </style>
</resources>
    <android.support.design.widget.TextInputLayout
        android:id="@+id/text_input_layout"
        android:hint="提示文本"
        app:hintAnimationEnabled="true"
        app:counterEnabled="true"
        app:errorTextAppearance="@style/myError">

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

NestedScrollView

在一个列表控件(ListView RecyerView)中,除了能够上下滚动外,也可以对内部的某个滚动(如下图二)。
在以前,我们要实现这样的功能需要重写触摸事件的传递。现在Material Design提供了一个进阶版本的ScrollView给我们使用。

引包

compile 'com.android.support:cardview-v7:25.+'

1.在ScrollView中嵌套使用

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#8888">
    <LinearLayout
        android:background="#fff"
        android:layout_width="match_parent"
        android:layout_height="800dp"
        android:orientation="vertical">
        //会优先滑动NestedScrollView,当NestedScrollView不能再滑动的时候滑动外部的ScrollView
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="400dp">
            <TextView
                android:background="#00f"
                android:text="@string/content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </android.support.v4.widget.NestedScrollView>
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="400dp">
            <TextView
                android:background="#0ff"
                android:text="@string/content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </android.support.v4.widget.NestedScrollView>
    </LinearLayout>
</ScrollView>

2.在ListView的item中嵌套使用

FloatActionButton

android 在 Material Designer 中提供了一种漂浮的按钮

引包

compile 'com.android.support:cardview-v7:25.+'

属性

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        //中间的图标的
        android:src="@mipmap/ic_launcher_round"
        //背景颜色
        app:backgroundTint="#F00"
        //中间的图标的大小
        app:fabSize="normal"
        //应该设置为0,否则在4.1版本显示为正方形,5.0以后没有阴影效果
        app:borderWidth="0dp"
        //配合coordinator_layout使用,稍后讲解
        app:layout_anchor="@id/coordinator_layout"  
        app:layout_anchorGravity="bottom|right"  
        app:elevation="30dp"
        android:translationZ="3dp"/>

ToolBar

google在旧版本推出过一个控件ActionBar,但是ActionBarzhi只能固定在顶部,不能灵活使用,所以google推出了一个ToolBar来替换ActionBar,我们可以配合一些新的控件实现很多酷炫的效果。

引包

compile 'com.android.support:cardview-v7:25.+'

ToolBar的内容讲解

这里写图片描述

使用

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        android:background="#F00"
    />
        //参考开头的Toolbar内容介绍
        mToolbar.setTitle("你好啊");
        mToolbar.setSubtitle("小小的你好啊");
        mToolbar.setNavigationIcon(R.mipmap.ic_launcher_round);
        mToolbar.setLogo(R.mipmap.ic_launcher);
        mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                return false;
            }
        });
        //将其设置为actionbar,从而实现对actionbar各种兼容
        setSupportActionBar(mToolbar);
        android.support.v7.app.ActionBar actionBar = getSupportActionBar();

SnackBar

Toast是我们在日常开发中经常使用的控件,简单易用,但是现在有这样的需求,需要与Toast交互,比如登陆失败了,弹出Toast后,点击Toast能够重新
登陆,但是就目前的Toast来说是无法解决这种问题的。因此google提供了一个新的控件给开发者,Snackbar。Snackbar除了有Toast的功能外,还具备
了Toast不具备的交互功能。
        mFab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar
                        //第一个参数是view,是snackbar依附的控件
                        .make(mFab, "你好啊", 3000)
                        .setAction("点击交互", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(getApplicationContext()
                                ,"弹出一个吐司",Toast.LENGTH_SHORT).show();
                            }
                        })
                        .show();
            }
        });

波纹动画

MD动画中有大量波纹动画,我们来看看如何通过代码来实现。
注意下面的api是5.0以上的系统提供的,注意好版本判断。
//核心api
ViewAnimationUtils.createCircularReveal(View view,int centerX,int centerY,float startRadius, float endRadius)

使用

public class CircularRevealActivity extends AppCompatActivity {

    @BindView(R.id.fab)
    FloatingActionButton mFab;
    @BindView(R.id.layout)
    ConstraintLayout mLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circular_reveal);
        ButterKnife.bind(this);
        if (Build.VERSION.SDK_INT>=21){
            mFab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //以指定view的背景作为动画的元素
                    Animator reveal = ViewAnimationUtils.createCircularReveal(mLayout, (int)mFab.getX()+mFab.getWidth()/2
                            , (int)mFab.getY()+mFab.getHeight()/2, 0, 1800);
                    reveal.setInterpolator(new LinearInterpolator());
//                    mLayout.setBackgroundColor(Color.parseColor("#0000ff"));
                    reveal.start();
                }
            });
        }
    }
}

监听共享动画

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= 21) {
            ChangeBounds changeBounds = new ChangeBounds();
            //开启transition
            getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
            getWindow().setSharedElementEnterTransition(changeBounds);
            //监听过场动画
            changeBounds.addListener(new Transition.TransitionListener() {
                @Override
                public void onTransitionStart(Transition transition) {
                }

                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onTransitionEnd(Transition transition) {
                    showAnimation();
                }

                @Override
                public void onTransitionCancel(Transition transition) {
                }

                @Override
                public void onTransitionPause(Transition transition) {
                }

                @Override
                public void onTransitionResume(Transition transition) {
                }
            });
        }
        setContentView(R.layout.activity_round_toolbar_detail);
    }

Palette

Material Design 建议使用大色块来进行显示需要加重的内容,我们常常需要UI人员进行配合才能实现相应的功能,但是在Material Design中,google提供
了一个工具类给我们,让我们可以根据图片获取相应的对应的颜色,能够动态的显示在UI上面。

引包

compile 'com.android.support:palette-v7:25.3.1'

核心api

创建取色器

//同步的⽅方式⽣生成⼀一个取⾊色器,会卡顿UI
Palette.from(BitMap).generate();
//异步的⽅方式⽣生成⼀一个取⾊色器
Palette.from(BitMap).generate(PaletteAsyncListener lis);

获取这个取色器内部的颜色,!!!这些颜色可能为空,使用前需要做非空判断

Vibrant (有活力)
Vibrant dark(有活力 暗色)
Vibrant light(有活力 亮色)
Muted (柔和)
Muted dark(柔和 暗色)
Muted light(柔和 亮色)

使用方法

创建一个子线程的Handler

        //HandlerThread对Thread的looper进行了封装
        woker = new HandlerThread("worker"); //开启了一直存在
        woker.start();
        //mHandler绑定到woker子线程的looper上面
        mHandler = new Handler(woker.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if(msg.what==99){
                    title.setText("aaaaa");
                }else{
                    int index = msg.arg1;
                    //一定是在子线程
                    changeColor(index);
                }

            }
        };

取色器

        Bitmap bm = BitmapFactory.decodeResource(getResources(), darwables[index]);
        Palette.from(bm).generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                //取某种风格的颜色,注意需要做非空判断
                if (palette.getDarkMutedSwatch() != null) {
                    //获取颜色
                    int color = palette.getDarkMutedSwatch().getRgb();
                }else if(palette.getLightVibrantSwatch() != null){

                    int color = palette.getLightVibrantSwatch().getRgb();

                    Message message = uiHandler.obtainMessage();
                    message.arg1 = color;
                    uiHandler.sendMessage(message);
                }
            }
        });

修改颜色

        Window window = getWindow();
        if(Build.VERSION.SDK_INT>=21){
            window.setStatusBarColor(color);
            window.setNavigationBarColor(color);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SkylakeXun

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值