Material Design
简介
- 一套全新的界面设计语言,包含了视觉、运动、互动效果等特性
ToolBar
- 在res下新建一个menu文件夹,新建一个toobar.xml文件
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- showAsAction的三种含义
always表示永远显示在toolBar中
ifRoom表示若屏幕空间足够显示在toolBar中
never表示永远显示在菜单当中
且toolBar中只会显示图片
菜单中只会显示文字-->
<item
android:id="@+id/backup"
android:icon="@drawable/ic_backup"
android:title="@string/backup"
app:showAsAction="always"/>
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="@string/delete"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings"
app:showAsAction="never"/>
</menu>
- activity_main.xml
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/Theme.AppCompat.Light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- 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);
}
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,"You clicked backup",Toast.LENGTH_SHORT).show();
//能响应点击事件
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.delete:
Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You clicked settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
滑动菜单DrawerLayout
- activity_main.xml
<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_width="match_parent"
android:layout_height="match_parent">
<!-- 该控件用于作为主屏幕中显示的内容,以及toolBar -->
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight" />
</FrameLayout>
<!-- layout_gravity指定了菜单所处的方向,且必须指定
如果是left就在左边,right就在右边,start表示跟随系统语言方向,从左往右就在左边-->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="@string/this_is_menu"
android:textSize="30sp"
android:background="#FFF" />
</androidx.drawerlayout.widget.DrawerLayout>
- MainActivity
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//得到DrawerLayout实例
mDrawerLayout = findViewById(R.id.drawer_layout);
//得到ActionBar实例,具体实现由ToolBar来完成
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//让导航按钮显示出来
actionBar.setDisplayHomeAsUpEnabled(true);
//设置一个导航按钮图标,将图片传进去
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
}
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永远是这一个
case android.R.id.home:
//调用该方法将菜单展示出来,传入的参数是Gravity参数
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this,"You clicked backup",Toast.LENGTH_SHORT).show();
//能响应点击事件
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.delete:
Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You clicked settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
滑动菜单控件NavigationView
- 在menu中新建一个nav_menu.xml文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 在menu里面嵌套一个group,将之属性设置为single,表示菜单中的所有属性只能单选 -->
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@drawable/nav_call"
android:title="@string/nav_call"/>
<item
android:id="@+id/nav_friends"
android:icon="@drawable/nav_friends"
android:title="@string/nav_friend"/>
<item
android:id="@+id/nav_location"
android:icon="@drawable/nav_location"
android:title="@string/nav_location"/>
<item
android:id="@+id/nav_mail"
android:icon="@drawable/nav_mail"
android:title="@string/nav_mail"/>
<item
android:id="@+id/nav_task"
android:icon="@drawable/nav_task"
android:title="@string/nav_task"/>
</group>
</menu>
- 在layout中新建一个nav_header.xml文件
<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:id="@+id/icon_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/header"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/mail"
android:textColor="#fff"
android:textSize="14sp"/>
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/mail"
android:text="@string/username"
android:textColor="#fff"
android:textSize="14sp"/>
</RelativeLayout>
- activity_main.xml
<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_width="match_parent"
android:layout_height="match_parent">
<!-- 该控件用于作为主屏幕中显示的内容,以及toolBar -->
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight"/>
</FrameLayout>
<!-- layout_gravity指定了菜单所处的方向,且必须指定
如果是left就在左边,right就在右边,start表示跟随系统语言方向,从左往右就在左边-->
<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"/>
</androidx.drawerlayout.widget.DrawerLayout>
- MainActivity
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//得到DrawerLayout实例
mDrawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
//得到ActionBar实例,具体实现由ToolBar来完成
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//让导航按钮显示出来
actionBar.setDisplayHomeAsUpEnabled(true);
//设置一个导航按钮图标,将图片传进去
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
navigationView.setCheckedItem(R.id.nav_call);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
mDrawerLayout.closeDrawers();
//Toast.makeText(MainActivity.this,"This is nav",Toast.LENGTH_SHORT).show();
return true;
}
});
}
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永远是这一个
case android.R.id.home:
//调用该方法将菜单展示出来,传入的参数是Gravity参数
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this,"You clicked backup",Toast.LENGTH_SHORT).show();
//能响应点击事件
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.delete:
Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You clicked settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
悬浮按钮FloatingActionButton
- activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 该控件用于作为主屏幕中显示的内容,以及toolBar -->
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight"/>
<!-- 替换系统背景颜色android:backgroundTint="#fff"
替换系统背景颜色和系统边框颜色app:backgroundTint="#009688"
替换图标默认颜色android:tint="#fff"-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:tint="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
android:elevation="8dp"
android:onClick="fabClick"
app:backgroundTint="#009688" />
</FrameLayout>
<!-- layout_gravity指定了菜单所处的方向,且必须指定
如果是left就在左边,right就在右边,start表示跟随系统语言方向,从左往右就在左边
通过menu和headerLayout属性将刚才准备好的布局添加进去-->
<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"/>
</androidx.drawerlayout.widget.DrawerLayout>
- MainActivity
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//得到DrawerLayout实例
mDrawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
//得到ActionBar实例,具体实现由ToolBar来完成
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//让导航按钮显示出来
actionBar.setDisplayHomeAsUpEnabled(true);
//设置一个导航按钮图标,将图片传进去
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
navigationView.setCheckedItem(R.id.nav_call);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
mDrawerLayout.closeDrawers();
//Toast.makeText(MainActivity.this,"This is nav",Toast.LENGTH_SHORT).show();
return true;
}
});
}
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永远是这一个
case android.R.id.home:
//调用该方法将菜单展示出来,传入的参数是Gravity参数
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this,"You clicked backup",Toast.LENGTH_SHORT).show();
//能响应点击事件
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.delete:
Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You clicked settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
public void fabClick(View view) {
Toast.makeText(this,"You clicked FloatingActionButton",Toast.LENGTH_SHORT).show();
}
}
可交互提示SnackBar
- MainActivity
public void fabClick(View view) {
Snackbar.make(view,"Data deleted",Snackbar.LENGTH_INDEFINITE)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"Data Restored",Toast.LENGTH_SHORT).show();
}
}).show();
//Toast.makeText(this,"You clicked FloatingActionButton",Toast.LENGTH_SHORT).show();
}
布局CoordinatorLayout
是加强版的FrameLayout,可以监听其所有子控件的各种事件,自动帮我们做出合理的响应
它会监听到弹出事件然后将你的控件合理的移动
<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="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight"/>
<!-- 替换系统背景颜色android:backgroundTint="#fff"
替换系统背景颜色和系统边框颜色app:backgroundTint="#009688"
替换图标默认颜色android:tint="#fff"-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:tint="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
android:elevation="8dp"
android:onClick="fabClick"
app:backgroundTint="#009688" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
卡片式布局CardView
- activity_main.xml
<?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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 该控件用于作为主屏幕中显示的内容,以及toolBar -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 防止页面内容覆盖住标题层 -->
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- layout_scrollFlags属性中,scroll表示当RecyclerView向上滚动的时候,ToolBar会跟着一起向上滚动并实现隐藏
enterAlways表示当向下滚动时,会一起向下滚动并显示
snap表示当ToolBar还没有完全显示或隐藏的时候,会根据当前滚动的距离,自动选择是隐藏还是显示-->
<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/ThemeOverlay.AppCompat.DayNight"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</com.google.android.material.appbar.AppBarLayout>
<!--实现下拉刷新-->
<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/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<!-- 替换系统背景颜色android:backgroundTint="#fff"
替换系统背景颜色和系统边框颜色app:backgroundTint="#009688"
替换图标默认颜色android:tint="#fff"-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:tint="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
android:elevation="8dp"
android:onClick="fabClick"
app:backgroundTint="#009688"
tools:targetApi="lollipop" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- layout_gravity指定了菜单所处的方向,且必须指定
如果是left就在左边,right就在右边,start表示跟随系统语言方向,从左往右就在左边
通过menu和headerLayout属性将刚才准备好的布局添加进去-->
<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"/>
</androidx.drawerlayout.widget.DrawerLayout>
- fruit_item.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 指定图片的缩放模式,按原比例,超出部分会被剪裁掉android:scaleType="centerCrop" -->
<ImageView
android:id="@+id/fruit_image"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="5dp"
android:textSize="16sp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
- Fruit.java
/**
* Description
* <p>
* 用于封装水果的信息
* @author qricis on 2020/9/2 9:17
* @version 1.0.0
*/
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;
}
}
- FruitAdapter.java
/**
* Description
* <p>
* RecyclerView的适配器,继承自RecyclerView.Adapter,泛型指定为FruitAdapter.ViewHolder
* @author qricis on 2020/9/2 10:07
* @version 1.0.0
*/
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private Context mContext;
private List<Fruit> mFruitList;
/**
* 寻找定义fruit_item的控件
* */
static class ViewHolder extends RecyclerView.ViewHolder {
private CardView mCardView;
private ImageView fruitImage;
private TextView fruitName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mCardView = (CardView) itemView;
fruitImage = itemView.findViewById(R.id.fruit_image);
fruitName = itemView.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
/**
* 返回一个ViewHolder(fruit_item),将recyclerView的视图返回
* */
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mContext == null) {
mContext = parent.getContext();
}
View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
//传入一个context/fragment/activity参数,然后加载图片,可以是URL地址/本地路径/资源id,然后将图片设置到某一个imageView中
//不需要担心内存溢出
Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
- MainActivity.java
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Fruit[] mFruits = {new Fruit("Apple",R.drawable.apple),new Fruit("Cherry",R.drawable.cherry),
new Fruit("Orange",R.drawable.orange),new Fruit("Pear",R.drawable.pear),
new Fruit("Pineapple",R.drawable.pineapple),new Fruit("Strawberry",R.drawable.strawberry),
new Fruit("Watermelon",R.drawable.watermelon),new Fruit("Mango",R.drawable.mango),
new Fruit("Banana",R.drawable.banana),new Fruit("Grape",R.drawable.grape)};
private List<Fruit> mFruitList = new ArrayList<>();
private FruitAdapter mFruitAdapter;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 得到DrawerLayout实例
mDrawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// 得到ActionBar实例,具体实现由ToolBar来完成
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
// 让导航按钮显示出来
actionBar.setDisplayHomeAsUpEnabled(true);
// 设置一个导航按钮图标,将图片传进去
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
navigationView.setCheckedItem(R.id.nav_call);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
mDrawerLayout.closeDrawers();
//Toast.makeText(MainActivity.this,"This is nav",Toast.LENGTH_SHORT).show();
return true;
}
});
// 实现RecyclerView
// 初始化List<Fruit>数组
initFruits();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
// 定义布局方式 LinearLayoutManager直接是线性布局
//LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// 瀑布流布局,实现交错式布局,第一个参数是列数,第二个参数是显示方向
//StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
// 不设置的话,图片闪烁错位,有可能有整列错位的情况。
//layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
// GridLayoutManager是网格布局 第一个参数为context,第二个参数为列数
GridLayoutManager layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
mFruitAdapter = new FruitAdapter(mFruitList);
recyclerView.setAdapter(mFruitAdapter);
// 下拉刷新
mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
mSwipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.colorPrimary));
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshFruit();
}
});
}
/**
* 下拉刷新实现
* */
private void refreshFruit() {
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();
mFruitAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
}).start();
}
private void initFruits(){
mFruitList.clear();
for (int i = 0; i < 50; i++) {
Random random = new Random();
int index = random.nextInt(mFruits.length);
mFruitList.add(mFruits[index]);
}
}
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永远是这一个
case android.R.id.home:
// 调用该方法将菜单展示出来,传入的参数是Gravity参数
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this,"You clicked backup",Toast.LENGTH_SHORT).show();
// 能响应点击事件
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.delete:
Toast.makeText(this,"You clicked delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You clicked settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
public void fabClick(View view) {
Snackbar.make(view,"Data deleted",Snackbar.LENGTH_LONG)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"Data Restored",Toast.LENGTH_SHORT).show();
}
}).show();
//Toast.makeText(this,"You clicked FloatingActionButton",Toast.LENGTH_SHORT).show();
}
}
可折叠式标题栏CollapsingToolBarLayout
- activity_fruit
<?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"
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">
<!-- 设定高级的标题栏属性
contentScrim用于指定其趋于折叠状态以及折叠之后的背景色
layout_scrollFlags属性中,scroll表示会随着内容详情的滚动而滚动,exitUntilCollapsed表示当其随着滚动完成折叠之后就保留在界面上,不再移出屏幕-->
<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">
<!-- layout_collapseMode属性用于指定当前控件在其折叠过程中的折叠模式
parallax表示在折叠过程中产生一定的错位偏移,pin表示在折叠过程中位置始终保持不变-->
<ImageView
android:id="@+id/fruit_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
android:contentDescription="@string/this_is_a_pics" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
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>
<!-- 内容详情部分实现 -->
<!-- ScrollView实现滚动的方式来查看屏幕以外的数据
NestedScrollView增加了实现嵌套响应滚动事件的功能 -->
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="34dp"
app:cardCornerRadius="4dp">
<TextView
android:id="@+id/fruit_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<!-- 制作评论的悬浮图标 -->
<!-- layout_anchor指定了一个锚点,我们指定了AppBarLayout,该悬浮按钮就会出现在标题栏区域内 -->
<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>
- FruitActivity
/**
* Description
* <p>
*
* @author qricis on 2020/9/2 14:45
* @version 1.0.0
*/
public class FruitActivity extends AppCompatActivity {
public static final String FRUIT_NAME = "fruit_name";
public static final String FRUIT_IMAGE_ID = "fruit_image_id";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit);
Intent intent = getIntent();
String fruitName = intent.getStringExtra(FRUIT_NAME);
int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID,0);
Toolbar toolbar = findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
ImageView fruitImageView = findViewById(R.id.fruit_image_view);
TextView fruitContentText = findViewById(R.id.fruit_name_view);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
collapsingToolbarLayout.setTitle(fruitName);
Glide.with(this).load(fruitImageId).into(fruitImageView);
// 循环输出水果名字
String fruitContent = generateFruitContent(fruitName);
fruitContentText.setText(fruitContent);
}
private String generateFruitContent(String fruitName) {
StringBuilder fruitContent = new StringBuilder();
for (int i = 0; i<500; i++) {
fruitContent.append(fruitName);
}
return fruitContent.toString();
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
- FruitAdapter
/**
* 返回一个ViewHolder(fruit_item),将recyclerView的视图返回
* */
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mContext == null) {
mContext = parent.getContext();
}
View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);
// 给CardView注册一个点击事件监听器
final ViewHolder holder = new ViewHolder(view);
holder.mCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Intent intent = new Intent(mContext, FruitActivity.class);
intent.putExtra(FruitActivity.FRUIT_NAME,fruit.getName());
intent.putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.getImageId());
mContext.startActivity(intent);
}
});
return holder;
}
可系统状态栏隐藏
- styles-v21
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 将状态栏的颜色设置成透明色 -->
<style name="FruitActivityTheme" parent="AppTheme">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
- 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>
- Manifest
<activity android:name=".activity.FruitActivity"
android:theme="@style/FruitActivityTheme"/>
- activity_fruit
<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:layout_height="250dp"
android:fitsSystemWindows="true">
<!-- 设定高级的标题栏属性
contentScrim用于指定其趋于折叠状态以及折叠之后的背景色
layout_scrollFlags属性中,scroll表示会随着内容详情的滚动而滚动,exitUntilCollapsed表示当其随着滚动完成折叠之后就保留在界面上,不再移出屏幕-->
<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"
android:fitsSystemWindows="true">
<!-- layout_collapseMode属性用于指定当前控件在其折叠过程中的折叠模式
parallax表示在折叠过程中产生一定的错位偏移,pin表示在折叠过程中位置始终保持不变
android:fitsSystemWindows="true"借助这一属性,让背景图和状态栏融合,且必须将其所有父布局都设成true,除此之外,需要在styles中将状态栏设定为透明色-->
<ImageView
android:id="@+id/fruit_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
android:contentDescription="@string/this_is_a_pics"
android:fitsSystemWindows="true"/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
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>
<!-- 内容详情部分实现 -->
<!-- ScrollView实现滚动的方式来查看屏幕以外的数据
NestedScrollView增加了实现嵌套响应滚动事件的功能
layout_behavior指定了一个布局行为,使得不挡住标题栏-->
<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="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="34dp"
app:cardCornerRadius="4dp">
<TextView
android:id="@+id/fruit_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<!-- 制作评论的悬浮图标 -->
<!-- layout_anchor指定了一个锚点,我们指定了AppBarLayout,该悬浮按钮就会出现在标题栏区域内 -->
<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>
完整代码展示
https://github.com/qricis/DoSomeAndroidTest/tree/main/MaterialTest