安卓学习之Material

Toolbar

首先把ActionBar的主题改成Theme.AppCompat.Light.NoActionBar或者Theme.AppCompat.NoActionBar,这样就隐藏了ActionBar。

然后修改activity_main.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/Theme.AppCompat.Light"

    />


</FrameLayout>

activity

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=findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        }
   }
        

添加标题的话新建一个menu.xml文件

<?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/item1"
        android:icon="@drawable/ic_settings"
        android:title="你好"
        app:showAsAction="ifRoom"/>
</menu>

加载menu中的菜单

@Override
    public boolean onCreateOptionsMenu(Menu menu) {//加载menu中的菜单
        getMenuInflater().inflate(R.menu.mneu,menu);
        return true;
    }

实现监听

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {//监听
        switch (item.getItemId()){
            case R.id.item1:
                Toast.makeText(this, "你好", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }

在这里插入图片描述

滑动菜单

DrawerLayout

直接在布局文件添加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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <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/colorAccent"/>
    </FrameLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hello World!"
        android:layout_gravity="start"//一定要添加这个 要告诉DrawerLayout滑动屏幕的菜单时左边还是右边
        android:textSize="30sp"
        />

</androidx.drawerlayout.widget.DrawerLayout>

添加导航按钮 让用户知道可以滑动菜单


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.drawerlayout);
        ActionBar actionBar=getSupportActionBar();//调用getSupportActionBar()得到ActionBar的实例
        if (actionBar!=null){//如果不为空
            actionBar.setDisplayHomeAsUpEnabled(true);//调用setDisplayHomeAsUpEnabled 把导航按钮显示出来
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);//设置导航按钮图标
        }

    }
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                break;
            default:
        }
        return true;
    }
}
NavigationView
  • 添加依赖
implementation 'com.google.android.material:material:1.1.0-alpha09' //这个是design库
implementation 'de.hdodenhof:circleimageview:2.1.0'//这个是实现图片圆形化的库
  • 在使用NavigationView时,需要提前准备好两个东西,menu和headerLayout。menu是用来在NavigationView中显示菜单项的,headerLayout则是在NavigationView中显示头部布局的

先来看menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--   checkableBehavior指定为single表示组中的所有菜单项只能单选 groun表示一个组-->
<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_call"
        android:icon="@drawable/nav_call"
        android:title="打电话"/>
    <item
        android:id="@+id/nav_mail"
        android:icon="@drawable/nav_mail"
        android:title="发邮箱"/>
    <item
        android:id="@+id/nav_friends"
        android:icon="@drawable/nav_friends"
        android:title="发邮箱"/>
    <item
        android:id="@+id/nav_task"
        android:icon="@drawable/nav_task"
        android:title="tasks"/>

</group>
</menu>

再来看headerLayout,去新建一个布局文件 ,这个可以随意定制布局,我们为了简单起见,只设置头像和邮箱地址

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="180dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary"
    >
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:id="@+id/icon_image"
        android:src="@drawable/nav_icon"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="你好世界"
        android:textColor="#fff"
        android:textSize="14sp"/>

</RelativeLayout>

设置好menu和headerlayout之后,就可以使用NavigationView,修改activity_main

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <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/colorAccent"/>
    </FrameLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/headerlayout"/>

</androidx.drawerlayout.widget.DrawerLayout>

NavigationView的定义完成了,但是还差菜单项的单击事件,修改MainActivity中的代码

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
        NavigationView navigationView=findViewById(R.id.nav_layout);//获取NavigationView实例
       ......
        navigationView.setCheckedItem(R.id.nav_call);//将call菜单项设置为默认选中
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()){
                    case R.id.nav_call:
                        Toast.makeText(MainActivity.this, "打电话", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }

在这里插入图片描述

悬浮按钮和可交互提示

FloatingActionButton

FloatingActionButton是Design库中的一个控件,它可以帮助我们实现悬浮按钮的效果。

下面开始具体操作

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 
       .......
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.appcompat.widget.Toolbar
           ......../>
           
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"//指定把控件放置在右下角
            android:layout_margin="16sp"
            android:src="@drawable/ic_done"/>
    </FrameLayout>
......

</androidx.drawerlayout.widget.DrawerLayout>

效果
在这里插入图片描述
实现监听器,和button一样

FloatingActionButton fb=findViewById(R.id.floatbutton);
        fb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "我是弹窗", Toast.LENGTH_SHORT).show();
            }
        });
Snackbar

也是Design库中的 ,有着更为先进的提示工具
它允许在提示中加入一个可交互按钮,当用户点击按钮的时候执行一些额外的逻辑操作。

用法

FloatingActionButton fb=findViewById(R.id.floatbutton);
        fb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * make()方法的第一个参数是view,只要是当前界面布局的任意一个View都可以,
                 * Snackbar会使用这个view来自动查找最外层的布局,用于展示Snackbar
                 * 第二个参数是显示内容,第三个参数是显示的时长
                 * 然后调用setAction()方法来设置一个动作。从而可以和用户进行交互
                 */

                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();
            }
        });

在这里插入图片描述
但是有一个bug,这个Snackbar居然把我们的悬浮按钮遮挡了,这个我们可以用CoordinatorLayout来解决

CoordinatorLayout

CoordinatorLayout是一个加强版的FrameLayout,也是Design库提供的。
CoordinatorLayout可以监听其所有的子控件的各种事件,然后自动帮助我们做出最为合理的响应,比如刚才弹出的提示把悬浮按钮遮挡了,但是如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,那么他会自动将悬浮按钮向上偏移,从而不会被遮挡。

试试把。

  • 修改布局文件,把FrameLaout替换成CoordinatorLayout。
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        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/colorAccent"/>
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/floatbutton"
            android:layout_gravity="bottom|end"
            android:layout_margin="16sp"
            android:src="@drawable/ic_done"/>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/headerlayout"/>

</androidx.drawerlayout.widget.DrawerLayout>

运行
在这里插入图片描述

卡片式布局

CardView

CardView是用于实现卡片式布局效果的重要控件,实际上,CardView也是一个FrameLayout,只是额外提供了圆角和阴影等效果,看上去会有立体的效果。

用法

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
<!--            卡片圆角弧度-->
            app:cardCornerRadius="4dp"
<!--            卡片的高度,高度值越大,投影范围就越大-->
            android:elevation="5dp">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </androidx.cardview.widget.CardView>

实战

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        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/colorAccent"/>

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

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

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/headerlayout"/>

</androidx.drawerlayout.widget.DrawerLayout>

新建Friut类

package com.dos.material;

public class Fruit {
    private String name;
    private int imageId;

    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }



    public String getName() {
        return name;
    }


    public int getImageId() {
        return imageId;
    }

}

创建适配器

package com.dos.material;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;

import java.util.List;

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
   private Context context;
   private List<Fruit> fruitList;

    static class ViewHolder extends RecyclerView.ViewHolder{
        CardView cardView;
        ImageView fruitImage;
        TextView textView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            fruitImage=itemView.findViewById(R.id.fruit_image);
            textView=itemView.findViewById(R.id.fruit_name);
            cardView= (CardView) itemView;
        }
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Fruit fruit=fruitList.get(position);
        holder.textView.setText(fruit.getName());
        //with()方法是传入一个context,然后调用load()加载图片,然后用into()方法将图片设置到具体某一个imageview就可以了
        Glide.with(context).load(fruit.getImageId()).into(holder.fruitImage);
    }

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


    public FruitAdapter(List<Fruit> fruitList) {
        this.fruitList = fruitList;
    }
}

Mainactivity


public class MainActivity extends AppCompatActivity {

    private List<Fruit> fruitList=new ArrayList<>();
    private FruitAdapter adapter;

    private Fruit[] fruits = {new Fruit("Apple", R.drawable.apple), new Fruit("Banana", R.drawable.banana),
            new Fruit("Orange", R.drawable.orange), new Fruit("Watermelon", R.drawable.watermelon),
            new Fruit("Pear", R.drawable.pear), new Fruit("Grape", R.drawable.grape),
            new Fruit("Pineapple", R.drawable.pineapple), new Fruit("Strawberry", R.drawable.strawberry),
            new Fruit("Cherry", R.drawable.cherry), new Fruit("Mango", R.drawable.mango)};



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

        initfruit();
        RecyclerView recyclerView=findViewById(R.id.recycle_view);
        GridLayoutManager gridLayoutManager=new GridLayoutManager(this,2);
        recyclerView.setLayoutManager(gridLayoutManager);
        adapter=new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
        }

    private void initfruit() {
            fruitList.clear();
            for (int i=0;i<50;i++){
                Random random=new Random();
                int index=random.nextInt(fruits.length);
                fruitList.add(fruits[index]);
            }
    }

在这里插入图片描述
我们发现我们的Toolbar被遮挡了。

AppBarLayout

那么怎么解决前面的遮挡问题呢?
只需要两步
第一把Toolbar嵌套在Appbarlayout中,第二部给RecyclerView指定一个布局行为。

  <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/colorAccent"/>
        </com.google.android.material.appbar.AppBarLayout>
        
        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycle_view"
            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="@color/colorAccent"
                app:layout_scrollFlags="scroll|enterAlways|snap"/>
        </com.google.android.material.appbar.AppBarLayout>

这里添加了一个app:layout_scrollFlags属性
srcoll表示当RecyclerView向上滚动的时候,Toolbar会跟着一起向上滚动并实现隐藏,
enterAlways表示当RecyclerView向下滚动的时候,Toolbar会跟着一起向下滚动并重新显示,
snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前滚动的距离,自动选择隐藏还是显示。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值