欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android基础知识——Material Design实战

程序员文章站 2022-04-10 09:49:56
文章目录1.什么是Material Design2.Toolbar3.滑动菜单3.1DrawerLayout3.2NavigationView1.什么是Material DesignMaterial Design是由谷歌的设计工程师们基于传统的优秀设计原则,结合丰富的创意和科学技术所发明的一套全新的界面设计语言,包含了视觉,运动,互动效果等特性。而事实上,Material Design更像是一种设计思想和理念,而本节我们并不是要以设计师的角度去学习Material Design,而是以一个开发者的角度去...

1.什么是Material Design

Material Design是由谷歌的设计工程师们基于传统的优秀设计原则,结合丰富的创意和科学技术所发明的一套全新的界面设计语言,包含了视觉,运动,互动效果等特性。而事实上,Material Design更像是一种设计思想和理念,而本节我们并不是要以设计师的角度去学习Material Design,而是以一个开发者的角度去学习使用一些符合Material Design理念的一些控件。

2.Toolbar

Toolbar继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件来完成一些Material Design的效果。

基本使用步骤:
1.更改程序的标题栏主题。
2.在布局中加入Toolbar。
3.在活动中替换标题栏。

示例:

//步骤一,values下的styles文件
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">//因为我们要引入toolbar,所以这里选择无标题栏主题
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>
//步骤二
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    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" />//令标题栏中的菜单项为浅色主题

</LinearLayout>
//步骤三
public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);//将标题栏替换为toolbar
    }
}

更改toolbar上显示的文字:

我们可以在活动中加入android:label属性来指定toolbar上显示的文字。

给toolbar添加菜单项:

使用步骤与给普通的actionbar添加菜单项类似。

示例:

//菜单布局
<?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/back"
        android:icon="@drawable/back"
        android:title="Back"
        app:showAsAction="always" />//始终以图片的形式存在于标题栏

    <item
        android:id="@+id/setting"
        android:icon="@drawable/setting"
        android:title="Setting"
        app:showAsAction="ifRoom" />//如果空间允许则以图片的形式存在于标题栏,否则以文字的形式

    <item
        android:id="@+id/delete"
        android:icon="@drawable/delete"
        android:title="Delete"
        app:showAsAction="never" />//始终以文字的形式存在于标题栏
</menu>
//活动
public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {//引入菜单布局
        getMenuInflater().inflate(R.menu.toolbra,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {//给菜单中的各个菜单项设置点击事件
        switch (item.getItemId()){
            case R.id.back:
                finish();
                break;
            case R.id.setting:
                Toast.makeText(MainActivity.this,"setting",Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(MainActivity.this,"delete",Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

3.滑动菜单

就是我们手机上常见的侧拉栏。

3.1DrawerLayout

使用方法:

DrawerLayout布局只允许其下有两个直接子布局,第一个是主界面的布局,第二个是侧拉栏的布局。

示例:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        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="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />


    </FrameLayout>

    <TextView
        android:id="@+id/text_view"
        android:text="This is menu"
        android:background="#fff"
        android:textSize="30sp"
        android:layout_gravity="start"//侧拉栏的布局必须声明这一属性,left表示侧拉栏在左,right表示侧拉栏在右,start则会根据系统语言来自动选择
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.drawerlayout.widget.DrawerLayout>

一个小问题:

这里可能存在一个问题,用户可能并不知道你的程序会有侧拉栏的功能,所以这里谷歌建议我们在标题栏中添加一个侧拉栏对应的按钮,用于打开侧拉栏。

示例:

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar);
        drawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout);
        setSupportActionBar(toolbar);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);//toolbar的最左侧有一个系统默认存在的按钮,而该方法能让该按钮显示出来
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);//这个按钮本身的图案是一个返回的箭头,而这里我们可以更改它的图案
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home://给这个系统默认存在的按钮添加点击事件
                drawerLayout.openDrawer(GravityCompat.START);
                break;
            case R.id.back:
                finish();
                break;
            case R.id.setting:
                Toast.makeText(MainActivity.this,"setting",Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(MainActivity.this,"delete",Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

3.2NavigationView

在上节中我们侧拉栏中的内容有些单薄,而NavigationView可以帮助我们很轻松的丰富侧拉栏中的内容。

使用步骤:

1.声名依赖。
2.准备好NavigationView的menu项。
3.准备好NavigationView的headerLayout
4.在布局中加入NavigationView。
5.可以在活动中给NavigationView的各个菜单项设置点击事件。

示例:

//步骤一
dependencies {
    implementation 'com.google.android.material:material:1.2.1'//material design的相关库
    implementation 'de.hdodenhof:circleimageview:3.1.0'//这是一个开源项目,可以帮助我们很轻松的实现图片圆形化的功能。
}
//步骤二
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">//表示组内的所有菜单项只能单选
        <item
            android:id="@+id/call"
            android:title="Call"
            android:icon="@drawable/nav_call" />

        <item
            android:id="@+id/friends"
            android:title="Friends"
            android:icon="@drawable/nav_friends" />

        <item
            android:id="@+id/location"
            android:title="Location"
            android:icon="@drawable/nav_location" />

        <item
            android:id="@+id/mail"
            android:title="Mail"
            android:icon="@drawable/nav_mail" />

        <item
            android:id="@+id/task"
            android:title="Task"
            android:icon="@drawable/nav_task" />
    </group>
</menu>
//步骤三
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:background="@color/colorPrimary"
    android:layout_width="match_parent"
    android:layout_height="180dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/image_view"
        android:src="@drawable/nav_icon"
        android:layout_centerInParent="true"
        android:layout_width="70dp"
        android:layout_height="70dp" />

    <TextView
        android:id="@+id/mail"
        android:textColor="#fff"
        android:text="mail: 1938796569@qq.com"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/username"
        android:textColor="#fff"
        android:text="username: yangxu"
        android:layout_above="@+id/mail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
//步骤四
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        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="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </FrameLayout>

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

</androidx.drawerlayout.widget.DrawerLayout>
//步骤五
final DrawerLayout drawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView=(NavigationView) findViewById(R.id.nav_view);
navigationView.setCheckedItem(R.id.call);//将call菜单项设置为选中状态
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {//可以在这里使用switch语句区分各个菜单项
        drawerLayout.closeDrawers();
        return true;
    }
});

4.悬浮按钮和可交互提示

4.1FloatingActionButton

该控件可以帮助我们很轻松的实现悬浮按钮的效果。

示例:

<FrameLayout
    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="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:src="@drawable/ic_done"
        android:layout_margin="16dp"
        android:layout_gravity="bottom|end"//此处的end同样也是根据系统语言来自动选择left或right
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:elevation="8dp"/>//该属性可以调整悬浮按钮下的阴影状态
        
</FrameLayout>

//我们还可以给这个悬浮按钮注册一个点击事件
FloatingActionButton fab=(FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Toast.makeText(MainActivity.this,"ok",Toast.LENGTH_SHORT).show();
    }
});

4.2Snackbar

在此之前我们向用户发送提示信息时最常用的便是Toast了,但是Toast仅仅只能通知用户一些简单的信息,而用户则只能被动接收,因为没有什么办法能让用户来进行选择。

现在让我们设想一个场景当用户在删除文件时,如果不小心删除了几个重要的文件,假设我们只是用Toas来提示用户而没有给出取消的方法时,相信用户肯定会抓狂吧。而Snackbar则可以很好的解决这个问题。

示例:

fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Snackbar.make(view,"you delete some import data",Snackbar.LENGTH_SHORT).setAction("Undo", new View.OnClickListener() {//setAction()方法的第一个参数是按钮名,第二个是监听器
            @Override
            public void onClick(View view) {a
                Toast.makeText(MainActivity.this,"Data restored",Toast.LENGTH_SHORT).show();
            }
        }).show();
    }
});

4.3CoordinatorLayout

如果你已经运行了我们在上面讲的代码的话,那你一定会发现Snackbar的提示信息将我们的悬浮按钮给遮挡住了,这样是十分影响界面的美观的,而我们本节要讲的CoordinatorLayout就可以解决这个问题了。

CoordinatorLayout是一个升级版的FrameLayout,它可以监听其所有子控件的各种事件,然后帮助我们做出最为合理的响应。

示例:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    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="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:src="@drawable/ic_done"
        android:layout_margin="16dp"
        android:layout_gravity="bottom|end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:elevation="8dp"/>
        
</androidx.coordinatorlayout.widget.CoordinatorLayout>

5.卡片式布局

5.1CardView

卡片式布局中的所有控件都将被放置在一张卡片上,给人一种立体的感觉,接下来我们就用RecyclerView来展示卡片布局的特点。

示例:

//主活动布局
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
//RecyclerView子项布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp"//该属性用来指定卡片布局圆角的弧度
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/fruit_image"
            android:src="@drawable/orange"
            android:scaleType="centerCrop"//该属性表示以同步的比例对图片进行缩放
            android:layout_width="match_parent"
            android:layout_height="100dp" />

        <TextView
            android:id="@+id/fruit_name"
            android:text="orange"
            android:textSize="16sp"
            android:layout_margin="5dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</androidx.cardview.widget.CardView>
//子项的类
public class Fruit {
    private String name;
    private int image;
    
    public Fruit(String name,int image){
        this.image=image;
        this.name=name;
    }

    public String getName() {
        return name;
    }

    public int getImage() {
        return image;
    }
}
//RecyclerView的适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private List<Fruit> mList;

    public MyAdapter(List<Fruit> list){
        mList=list;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView name;
        ImageView image;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            name=itemView.findViewById(R.id.fruit_name);
            image=itemView.findViewById(R.id.fruit_image);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
        ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Fruit fruit=mList.get(position);
        holder.name.setText(fruit.getName());
        holder.image.setImageResource(fruit.getImage());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}
//主活动
private List<Fruit> list=new ArrayList<>();

initFruits();
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_view);
GridLayoutManager manager=new GridLayoutManager(this,2);
recyclerView.setLayoutManager(manager);
MyAdapter adapter=new MyAdapter(list);
recyclerView.setAdapter(adapter);

public void initFruits(){
    for(int i=0;i<50;i++){
        Fruit fruit=new Fruit("orange",R.drawable.orange);
        list.add(fruit);
    }
}

5.2AppBarLayout

如果你已经运行过上一节示例中的代码的话,那么你一定会发现RecyclerView布局将Toolbar标题栏给遮挡住了,这同样会影响我们界面的美观,而我们在本节中要学的AppBarLayout就可以解决这个问题了。

AppBarLayout实际上是一个垂直方向上的LinearLayout,不同的是它在内部做了很多滚动事件的封装,并应用了Material Design的设计理念。

示例:

<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="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_scrollFlags="scroll|snap|enterAlways"/>
        //该属性可以使控件更好的配合滑动事件。
        //其中scroll表示当recyclerview向上滚动时,Toolbar会跟着一起向上移动并实现隐藏;
		//snap表示当Toolbar还没有完全隐藏或显示时,会根据当前的距离自动选择隐藏还是显示;
		//enterAlways表示当recyclerview向下滚动时,Toolbar会跟着向下移动并重新显示。
        
</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>//我们这里让recyclerview向下偏移一个标题栏的长度

6.下拉刷新

我们在日常使用app时,经常会用到下拉刷新这个功能,而在本节中我们就来实现该功能。

示例:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipe_layout"
    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/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
        
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

//我们还要在活动中去处理刷新的逻辑
final SwipeRefreshLayout swipeRefreshLayout=(SwipeRefreshLayout) findViewById(R.id.swipe_layout);
swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);//设置进度条的颜色
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        //刷新的逻辑代码,此处一般是从网咯中获取数据,因此会开辟一个线程来进行处理。
        swipeRefreshLayout.setRefreshing(false);//刷新完成后,关闭进度条
    }
});

7.可折叠式标题栏

7.1CollapsingToolbarLayout

我们可以利用CollapsingToolbarLayout布局,来帮助我们实现可折叠式的标题栏。不过CollapsingToolbarLayout是不能单独存在的,它只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout的子布局。接下来我们就来看一个CollapsingToolbarLayout的示例吧。

示例:

//新活动的布局
<androidx.coordinatorlayout.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">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"//该属性用于设置当标题栏完全折叠式的背景颜色
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/fruit_image_view"
                android:src="@drawable/orange"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"/>//该属性表示该控件会随着折叠而折叠

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar02"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>//该属性表示该控件不会随着折叠而折叠


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

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

    <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="match_parent"
                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_margin="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>

            </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"
        app:layout_anchor="@id/appBar"//该属性用于给悬浮按钮定义一个锚点
        app:layout_anchorGravity="bottom|end" />//该属性用于设置悬浮按钮相对于锚点的位置

</androidx.coordinatorlayout.widget.CoordinatorLayout>
//新活动的代码
public class MainActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Intent intent=getIntent();
        String name=intent.getStringExtra("name");
        int image=intent.getIntExtra("image",-1);
        Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar02);
        CollapsingToolbarLayout collapsingToolbarLayout=(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        ImageView fruitImage=(ImageView) findViewById(R.id.fruit_image_view);
        TextView fruitContent=(TextView) findViewById(R.id.fruit_content_text);
        setSupportActionBar(toolbar);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        collapsingToolbarLayout.setTitle(name);
        fruitImage.setImageResource(image);
        StringBuilder content=new StringBuilder();
        for(int i=0;i<3000;i++){
            content.append(name);
        }
        fruitContent.setText(content.toString());
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                finish();
                break;
            default:
        }
        return super.onOptionsItemSelected(item);
    }
}
//recyclerview的适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private List<Fruit> mList;

    public MyAdapter(List<Fruit> list){
        mList=list;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        View view;
        TextView name;
        ImageView image;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            view=itemView;
            name=itemView.findViewById(R.id.fruit_name);
            image=itemView.findViewById(R.id.fruit_image);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
        final ViewHolder viewHolder=new ViewHolder(view);
        viewHolder.view.setOnClickListener(new View.OnClickListener() {//设置点击事件
            @Override
            public void onClick(View view) {
                int position=viewHolder.getAdapterPosition();
                Fruit fruit=mList.get(position);
                Intent intent=new Intent(parent.getContext(),MainActivity2.class);
                intent.putExtra("name",fruit.getName());
                intent.putExtra("image",fruit.getImage());
                parent.getContext().startActivity(intent);//开启新活动
            }
        });
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Fruit fruit=mList.get(position);
        holder.name.setText(fruit.getName());
        holder.image.setImageResource(fruit.getImage());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

7.2充分利用系统状态栏空间

如果你运行了我们上一节中的代码,那么你一定发现了系统状态栏哪里感觉与我们的界面非常不搭配,而要解决这一问题也非常简单,只需把系统状态栏设置为透明色即可。

示例:

//首先给你要实现融合的控件及其父布局都设置上android:fitsSystemWindows="true"属性
<androidx.coordinatorlayout.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"
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true"
        android:layout_height="250dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/fruit_image_view"
                android:src="@drawable/orange"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:fitsSystemWindows="true"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar02"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>

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

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

    <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="match_parent"
                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_margin="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>

            </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"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

//将系统状态栏的颜色设置为透明色(因为只有在Android5.0后我们才可以这样做,因此我们要对此做区分)
//values-v21下的styles文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="FruitActivityTheme" parent="AppTheme">//使其继承自AppTheme,这样AppTheme所拥有的特性它也会拥有
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>
//values下的styles文件
<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">
    </style>

</resources>

//给第二个活动使用我们新建的主题
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.temp">

    <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=".MainActivity2"
            android:theme="@style/FruitActivityTheme" />
        <activity
            android:name=".MainActivity"
            android:label="MyBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

本文地址:https://blog.csdn.net/ABded/article/details/108554840