第一行代码-第二版(郭霖著)笔记十一(Material Design)

目录

一、什么是Material Design

二、Toolbar

三、滑动菜单

1.DrawerLayout

2.NavigationView

四、悬浮按钮和可交互提示

1.FloatingActionButton:悬浮按钮

2.Snackbar:提示工具

3.CoordinatorLayout:加强版FrameLayout

五、卡片式布局

1.MaterialCardView

2.AppBarLayout

六、下拉刷新

七、可折叠式标题栏

1.CollapsingToorbarLayout

2.充分利用系统状态栏空间


一、什么是Material Design

一套全新的界面设计语言

二、Toolbar

修改D:\soft\projects\MaterialTest\app\src\main\res\values\themes.xml

//界面的主体颜色设成深色,陪衬颜色设成淡色
<style name="Theme.MaterialTest" parent="Theme.MaterialComponents.NoActionBar">


//界面的主体颜色设成淡色,陪衬颜色设成深色
<style name="Theme.MaterialTest" parent="Theme.MaterialComponents.Light.NoActionBar">


 

如何使用Toolbar?

 首先修改themes.xml文件:

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.MaterialTest" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

其次在activity_main.xml添加:

<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/purple_500"

        tools:ignore="MissingConstraints" />

 最后修改MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
}

效果如下图:

 

添加android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"让Toolbar单独使用深色主题,这样文字就会变成浅色,如下图

<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/purple_500"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        tools:ignore="MissingConstraints" />

 

在Toolbar中添加一些按钮

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <item
        android:id="@+id/backup"
        android:title="Backup"
        android:icon="@drawable/ic_backup"
        app:showAsAction="always"
        />
    <item
        android:id="@+id/delete"
        android:title="Delete"
        android:icon="@drawable/ic_delete"
        app:showAsAction="ifRoom"
        />
    <item
        android:id="@+id/settings"
        android:title="Settings"
        android:icon="@drawable/ic_settings"
        app:showAsAction="never"
        />
</menu>
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.backup:
                Toast.makeText(this, "你点击了返回", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this, "你点击了删除", Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this, "你点击了设置", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
}

如果不指定android:icon="@drawable/ic_backup",会用title作为按钮,如下图:

 加了icon属性如下图:

 当你点最右边三个点时如下图:

 只需要在布局文件中的Toolbar添加如下代码就可以,如下图:

app:popupTheme="@style/Theme.AppCompat.Light"

 


三、滑动菜单

1.DrawerLayout

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </FrameLayout>
<!--指定start表示会根据系统语言进行判断,系统语言是从左往右的,滑动菜单在左边,系统语言从右往左的,滑动菜单在右边-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"  
        android:layout_gravity="start"
        android:text="这是菜单"
        android:textSize="30sp"
        android:background="#FFF"
        />

</androidx.drawerlayout.widget.DrawerLayout>


Toorbar的最左边加入一个导航按钮

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!=null){
            //让导航按钮显示出来
            actionBar.setDisplayHomeAsUpEnabled(true);
            //设置导航按钮图标
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            //HomeAsUp按钮的id永远都是android.R.id.home
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                break;
            case R.id.backup:
                Toast.makeText(this, "你点击了返回", Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this, "你点击了删除", Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this, "你点击了设置", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
}

2.NavigationView

添加依赖:

//开源项目CircleImageView,可以用来轻松实现图片圆形化的功能
implementation 'de.hdodenhof:circleimageview:3.1.0'

 NavigationView不用添加依赖,直接

<com.google.android.material.navigation.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:menu="@menu/nav_menu"
    app:headerLayout="@layout/nav_header"
    />


四、悬浮按钮和可交互提示

1.FloatingActionButton:悬浮按钮

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@drawable/ic_done"
    //指定高度值,高度值越大,投影范围也越大,投影效果越淡;高度值越小,投影范围越小,投影效果越浓
    app:elevation="8dp"
    />


2.Snackbar:提示工具

Snackbar允许在提示中加入一个可交互按钮

FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //第一个参数需要传入一个View,当前界面布局的任意一个View都可以;第二个参数是内容;第三个参数是显示的时长
        Snackbar.make(v,"数据删除",Snackbar.LENGTH_SHORT).setAction("不做", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "数据保存", Toast.LENGTH_SHORT).show();
            }
        }).show();
    }
});


3.CoordinatorLayout:加强版FrameLayout

CoordinatorLayout可以监听其所有子控件的各种事件,然后自动帮助我们做出最为合理的响应。

比如可以实现提示条不会挡住悬浮按钮

<androidx.coordinatorlayout.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"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorOnSecondary"
        android:theme="@style/ThemeToolbar"
        app:titleTextColor="@color/white"
        />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@drawable/ic_done"
        app:elevation="8dp"
        />

</androidx.coordinatorlayout.widget.CoordinatorLayout>


五、卡片式布局

1.MaterialCardView

也是一个FrameView,只是额外提供了圆角和阴影等效果

添加Glide库依赖:Glide是一个超级强大的图片加载库

implementation 'com.github.bumptech.glide:glide:4.12.0'
<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="4dp"
    app:elevation="5dp">
    <TextView
        android:id="@+id/infoText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</com.google.android.material.card.MaterialCardView>

 

2.AppBarLayout

实际上是一个垂直方向的LinearLayout,在内部做了很多滚动事件的封装

怎么解决Toolbar被覆盖的问题?

第一步将Toolbar嵌套到AppBarLayout中,第二部给RecycleView指定一个布局行为

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorOnSecondary"
        android:theme="@style/ThemeToolbar"
        app:titleTextColor="@color/white"
        />
</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycle_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    //指定一个布局行为
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    />

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorOnSecondary"
        android:theme="@style/ThemeToolbar"
        app:titleTextColor="@color/white"
        //scroll表示当RecycleView向上滚动时,Toolbar会跟着一起向上滚动并隐藏;enterAlways反之;snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前的滚动距离,自动选择是隐藏还是显示
        app:layout_scrollFlags="scroll|enterAlways|snap"
        />
</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycle_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    />

六、下拉刷新

SwipeRefreshLayout是用于实现下拉刷新功能的核心类

导入SwipeRefreshLayout依赖:

implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'

在RecycleView的外面嵌套一层SwipeRefreshLayout,这样RecycleView就自动拥有下拉刷新的功能了:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycle_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

修改MainActivity:

    protected void onCreate(Bundle savedInstanceState) {
        ......
        swipeRefreshLayout  = findViewById(R.id.swipe_refresh);
//        swipeRefreshLayout.setColorSchemeResources(R.color.design_default_color_primary);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshFruits();
            }
        });
    }

    private void refreshFruits(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        initFruits();
                        //通知数据发生了变化
                        adapter.notifyDataSetChanged();
                        //表示刷新事件结束,并隐藏刷新进度条
                        swipeRefreshLayout.setRefreshing(false);
                    }
                });
            }
        }).start();
    }

七、可折叠式标题栏

1.CollapsingToorbarLayout

一个作用于Toolbar基础之上的布局,可以让Toolbar的效果变得更加丰富,展示标题栏的同时实现非常华丽的效果。CollapsingToolbarLayout只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout的子布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
    tools:context=".FruitActivity"
    android:fitsSystemWindows="true">
    
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:fitsSystemWindows="true">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toorbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            //指定CollapsingToolbarLayout趋于折叠状态以及折叠之后的背景色
            app:contentScrim="@color/black"
            scroll表示CollapsingToolbarLayout会对着水果内容详情的滚动一起滚动,exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就保留在界面上,不再移出屏幕
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            >

            <ImageView
                android:id="@+id/fruit_image_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                //折叠模式parallax:在折叠过程中产生一定的错位偏移
                app:layout_collapseMode="parallax"
                android:fitsSystemWindows="true"
                />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                //折叠模式pin:在折叠的过程中位置始终保持不变
                app:layout_collapseMode="pin"
                />

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    //允许使用滚动的方式来查看屏幕以外的数据,并增加了嵌套响应滚动事件的功能 内部只允许存在一个直接子布局,如果想要在里面放入很多东西,通常会先嵌套一个LinearLayout
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="35dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginBottom="15dp"
                app:cardCornerRadius="4dp"
                >
                <TextView
                    android:id="@+id/fruit_content_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    />
            </androidx.cardview.widget.CardView>

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@drawable/ic_comment"
        //指定了一个锚点,锚点设置为AppBarLayout,这样悬浮按钮就会出现在水果标题栏的区域内
        app:layout_anchor="@id/appBar"
        //将悬浮按钮定位在标题栏区域的右下角
        app:layout_anchorGravity="bottom|end"
        />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

2.充分利用系统状态栏空间

第一步:将ImageView和ImageView布局的所有父布局都设置上下面的属性

android:fitsSystemWindows="true"

第二步:打开res/values/styles.xml文件,对主题的内容进行修改

<resources>
 <!-- Base application theme. -->
 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
 <!-- Customize your theme here. -->
 <item name="colorPrimary">@color/colorPrimary</item>
 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 <item name="colorAccent">@color/colorAccent</item>
 </style>
 <style name="FruitActivityTheme" parent="AppTheme">
 <item name="android:statusBarColor">@android:color/transparent</item>
 </style>
</resources>

 最后,还需要让FruitActivity使用这个主题才可以

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.materialtest">
 <application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:roundIcon="@mipmap/ic_launcher_round"
 android:supportsRtl="true"
 android:theme="@style/AppTheme">
 ...
 <activity
 android:name=".FruitActivity"
 android:theme="@style/FruitActivityTheme">
 </activity>
 </application>
</manifest>

完!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值