最佳的UI体验-----Material Design实战
使用Material Design来设计界面
Toolbar
Toolbar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件来完成一些Material Design的效果.
新建一个项目都会显示ActionBar其实是跟项目中指定的主题来显示的,打开AndroidMainfest.xml,如下:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
...
</application>
AppTheme在哪定义的呢?
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.Mytest" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
</style>
</resources>
现在使用Toolar来替代ActionBar.修改布局:
<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">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</FrameLayout>
然后接着修改MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
}
其中,这边会有一个错误:
这个错误主要来源于,其导包错误,导成了
import android.widget.Toolbar;
而在选择时,应该选为
import androidx.appcompat.widget.Toolbar;
修改后的代码:
为了使Toolbar更加丰富一点,准备几张图片来作为按钮的图标,右击res目录→New→Directory,创建一个menu文件夹,然后右击menu文件夹→New→Menu resource file,创建一个toolbar.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/backup"
android:icon="@drawable/ic_launcher_background"
android:title="Backup"
app:showAsAction="always" />
<item
android:id="@+id/delete"
android:icon="@drawable/ic_launcher_foreground"
android:title="Delete"
app:showAsAction="always" />
<item
android:id="@+id/settings"
android:icon="@mipmap/ic_launcher"
android:title="Settings"
app:showAsAction="never" />
</menu>
通过标签来定义action按钮,android:id用于指定按钮的id,android:icon用于指定按钮的图标,android:title用于指定按钮的文字.
app:showAsAction来指定按钮的显示位置,之所以这里再次使用了app命名空间,同样是为了能够兼容低版本的系统.showAsAction主要有以下几种值可选:always表示永远显示在Toolbar中,如果屏幕空间不够则不显示;ifRoom表示屏幕空间足够的情况下显示在Toolbar中,不够的话就显示在菜单中;never则表示永远显示在菜单当中.注意:Toolbar中的action按钮只会显示图标,菜单中的action按钮只会显示文字.
接着,修改MainActivity中的代码,如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar 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(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}
return true;
}
}
逻辑十分简单,在onCreateOptionsMenu()方法中加载了toolbar.xml菜单文件,然后在onOptionsItemSelected()方法中处理各个按钮的点击事件
效果如下:
滑动菜单
DrawerLayout
所谓的滑动菜单就是将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后通过滑动的方式将菜单显示出来.这种方式既节省了屏幕空间,有实现了非常好的动画效果,是比较推荐的.
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_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="This is menu"
android:textSize="30sp"
android:background="#FFF" />
</androidx.drawerlayout.widget.DrawerLayout>
可以看到,最外层的控件使用了DrawerLayout,DrawerLayout中放置了两个直接子控件,第一个子控件是FrameLayout,用于作为主屏幕中显示的内容,当然里面还有刚定义的Toolbar.第二个子控件使用了一个TextView,用于作为滑动菜单中显示的内容.
关于第二个子控件需要注意:layout_gravity这个属性是必须指定的,因为需要告诉DrawerLayout滑动菜单是在屏幕的左边还是右边,指定left表示滑动菜单在左边,指定right表示滑动菜单在右边,指定start,表示会根据系统语言进行判断.
现在可以在Toolbar的最左边加入一个导航按钮,点击了按钮也会将滑动菜单的内容展示出来.首先准备了一张导航图片,ic_menu.png,将它放在mimap-xxxhdpi目录下,然后修改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 = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.ic_menu);
}
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == android.R.id.home){
mDrawerLayout.openDrawer(GravityCompat.START);
}
return true;
}
}
首先调用findViewById()方法得到了DrawerLayout的实例,然后调用getSupportActionBar()方法得到了ActionBar的实例,接着调用ActionBar的setDisplayHomeAsUpEnabled()方法让导航按钮显示出来,又调用setHomeAsUpIdicator()方法设置了一个导航按钮图标,实际上,Toolbar最左侧的这个按钮就是叫做HomeAsUp按钮,他默认的是一个返回的箭头,含义是返回上一个活动
接下来在onOptionsItemSelected()方法中对HomeAsUp按钮的点击事件进行处理,HomeAsUp按钮的id永远是android.R.id.home.然后调用DrawerLayout的openDrawer()方法将滑动菜单展示出来
NavigationView
第一步:添加如下依赖:
implementation 'de.hdodenhof:circleimageview:3.1.0'
这个依赖的作用就是可以用来轻松实现图片圆形化的功能.
在使用NavigationView之前,还需要准备两个东西:menu和headerLayout.menu是用来在NavigationView中显示具体的菜单项,headerLayout则是用来在NavigationView中显示头部布局的.
先来准备menu,实现找了几张图片作为按钮的图标,并将他们放在了mimap-xxxhdpi目录下,然右击menu文件夹→New→Menu resource file,创建一个nav_menu.xml文件,然后编写以下代码:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@mipmap/collect_select"
android:title="Call" />
<item
android:id="@+id/nav_friends"
android:icon="@mipmap/collect_selected"
android:title="Friends"/>
<item
android:id="@+id/nav_location"
android:icon="@mipmap/ic_launcher"
android:title="Location" />
<item
android:id="@+id/nav_mail"
android:icon="@mipmap/pwd"
android:title="Mail" />
<item
android:id="@+id/nav_task"
android:icon="@mipmap/my_selected"
android:title="Tasks" />
</group>
</menu>="single">
<item
android:id="@+id/nav_call"
android:icon="@mipmap/collect_select"
android:title="Call" />
<item
android:id="@+id/nav_friends"
android:icon="@mipmap/collect_selected"
android:title="Friends"/>
<item
android:id="@+id/nav_location"
android:icon="@mipmap/ic_launcher"
android:title="Location" />
<item
android:id="@+id/nav_mail"
android:icon="@mipmap/pwd"
android:title="Mail" />
<item
android:id="@+id/nav_task"
android:icon="@mipmap/my_selected"
android:title="Tasks" />
</group>
</menu>
其中,group表示一个组,checkableBehavior指定为single表示组中的所有菜单项只能单选.
接下来准备headerLayout,这是一个可以随意定制的布局,可以在headerLayout中放置头像,用户名,邮箱地址
最好准备一张正方形图片,右击layout文件夹→New→Layout resource file,创建一个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:layout_width="70dp"
android:layout_height="70dp"
android:id="@+id/icon_image"
android:src="@mipmap/img"
android:layout_centerInParent="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id = "@+id/mail"
android:layout_alignParentBottom="true"
android:text="tonygreendev@gmail.com"
android:textColor="#FFF"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/username"
android:layout_above="@+id/mail"
android:text="Tony Green "
android:textColor="#FFF"
android:textSize="14sp" />
</RelativeLayout>
现在menu和headerLayout都准备好了,可以使用NavigationView.修改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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</FrameLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.DrawerLayout>
将之前的TextView换成了NavigationView,这样滑动菜单中显示的内容也就变成了NavigationView了 app:menu和 app:headerLayout将刚才设置好的东西设置进去了.
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.ic_menu);
}
navView.setCheckedItem(R.id.nav_call);
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();
return true;
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == android.R.id.home){
mDrawerLayout.openDrawer(GravityCompat.START);
}
return true;
}
}
悬浮按钮和可交互提示
FloatingActionButton
此控件可以帮助我们轻松的实现悬浮按钮的效果,准备一张图片,然后修改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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end" //将这个控件放入到了屏幕的右下角
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</FrameLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
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 = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"FAB clicked",Toast.LENGTH_SHORT).show();
}
});
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.ic_menu);
}
navView.setCheckedItem(R.id.nav_call);
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();
return true;
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == android.R.id.home){
mDrawerLayout.openDrawer(GravityCompat.START);
}
return true;
}
}
Snackbar
之前处理点击事件时,都是使用Toast来作为提示工具的,Snackbar就是更为先进的提示工具.
Toast只能进行提示,而Snackbar可以进行交互
修改MainActivity中的代码
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"Data deleted",Snackbar.LENGTH_SHORT)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Data restored",
Toast.LENGTH_SHORT).show();
}
}).show();
}
});
这里调用了Snackbar的make()方法来创建一个Snackbar对象,make()方法中的第一个参数传入一个View,只要是当前布局的任意一个View即可,Snackbar会使用这个View来自动查找最外层的布局,用于显示Snackbar.第二个参数是Snackbar中显示的内容,第三个参数是Snackbar显示的时长
但是有一个问题,Snackbar会将悬浮按钮给挡住,这样子用户体验不是很好.需要借助CoordinatorLayout解决.
CoordinatorLayout
CoordinatorLayout是一个加强版的FrameLayout,其可以监听所有子控件的各种事件,然后帮我们做出最为合理的响应.例如:刚才弹出的Snackbar提示将悬浮按钮挡住了,如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,他就会自动的将内部的FloatingActionButton向上偏移
修改布局中的代码,
<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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.DrawerLayout>
CoordinatorLayout可以监听其所有子控件的各种事件,但是Snackbar好像并不是CoordinatorLayout的子控件
因为在Snackbar的make()方法,第一个参数VIew是FloatingAActionBar触发的,而FloatingActionBar是Coordu=inatorLayout中的子控件.
卡片式布局
CardView
由于在此程序中,实现我们需要RecyclerView,CardView这几个控件,因此我们要加入如下依赖:
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
最后一行是Glide库的依赖,Glide是一个超级强大的图片加载器.
接下来修改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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.DrawerLayout>
然后定义一个Fruit类,如下:
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;
}
}
然后需要为RecyclerView的子项指定一个我们自定义的布局,在layout目录下新建fruit_item.xml,代码如下:
<androidx.cardview.widget.CardView
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="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:id="@+id/fruit_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fruit_name"
android:layout_gravity="center_horizontal"
android:layout_margin="5dp"
android:textSize="16sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
这里使用CardView来作为子项的最外层布局,从而使得RecyclerView中的每个元素都是在卡片中的.
这里注意在ImageView中我们使用了一个scaleType属性,这个属性可以指定图片的缩放模式.由于各张水果图片的长宽比例可能都不一样,为了让所有的图片填充整个ImageView,这里使用了centerCrop模式
然后新建一个FruitAdapter类
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private Context mContext;
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
CardView cardView;
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view){
super(view);
cardView = (CardView) view;
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitName = (TextView) view.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List<Fruit> fruitList){
mFruitList = fruitList;
}
@NonNull
@Override
public FruitAdapter.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 FruitAdapter.ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
}
@Override
public int getItemCount() {
return mFruitist.size();
}
}
其中Glide在内部做了很多非常复杂的逻辑,其中就包括了图片的压缩等,比较方便.
最后修改MainActivity中的代码,如下:
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private Fruit[] fruits = {new Fruit("Apple",R.mipmap.apple),
new Fruit("Orange",R.mipmap.orange),
new Fruit("Watermelon",R.mipmap.watermelon),
new Fruit("Pear",R.mipmap.pear),
new Fruit("Grape",R.mipmap.grape)};
private List<Fruit> fruitList = new ArrayList<>();
private FruitAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
GridLayoutManager layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"Data deleted",Snackbar.LENGTH_SHORT)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Data restored",
Toast.LENGTH_SHORT).show();
}
}).show();
}
});
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.ic_menu);
}
navView.setCheckedItem(R.id.nav_call);
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();
return true;
}
});
}
private void initFruits() {
fruitList.clear();
for(int i =0 ; i < 50; i++){
Random random = new Random();
int index = random.nextInt(fruits.length);
fruitList.add(fruits[index]);
}
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == android.R.id.home){
mDrawerLayout.openDrawer(GravityCompat.START);
}
return true;
}
}
AppBarLayout
因为此时出现了RecyclerView会把Toolbar遮挡住,此时的解决办法就是让RecyclerView向下偏移了一个Toolbar的高度,从而保证不会遮挡到Toolbar
使用AppBarLayout怎样解决问题?第一步将Toolbar嵌套到AppBarLayout中,第二步给RecyclerView指定一个布局行为.
修改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">
<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">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.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">
<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">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.DrawerLayout>
在Toolbar中添加了一个app:layout_scrollFlags属性,并将属性的值指定成了scroll|enterAlways|snap.其中,scroll表示当RecyclerView向上滚动的时候,Toolbar会跟着一起向上滚动并实现隐藏;enterAlways表示当RecyclerView向下滚动的时候,Toolbar会跟着一起向下滚动并重新显示;snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前滚动的距离,自动选择隐藏还是显示.
下拉刷新
首先需要添加依赖:
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
我们把想要实现下拉刷新功能的控件放置到SwipeRefreshLayout中,就可以让这个控件支持下拉刷新,而此时的控件应该是RecyclerView
修改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">
<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">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_refresh"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@mipmap/dianzan"
app:elevation="8dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_view"
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;
private SwipeRefreshLayout swipeRefresh;
private Fruit[] fruits = {new Fruit("Apple",R.mipmap.apple),
new Fruit("Orange",R.mipmap.orange),
new Fruit("Watermelon",R.mipmap.watermelon),
new Fruit("Pear",R.mipmap.pear),
new Fruit("Grape",R.mipmap.grape)};
private List<Fruit> fruitList = new ArrayList<>();
private FruitAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(com.google.android.material.R.color.design_default_color_primary);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshFruits();
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"Data deleted",Snackbar.LENGTH_SHORT)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Data restored",
Toast.LENGTH_SHORT).show();
}
}).show();
}
});
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.ic_menu);
}
navView.setCheckedItem(R.id.nav_call);
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();
return true;
}
});
}
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();
swipeRefresh.setRefreshing(false);
}
});
}
}).start();
}
private void initFruits() {
fruitList.clear();
for(int i =0 ; i < 50; i++){
Random random = new Random();
int index = random.nextInt(fruits.length);
fruitList.add(fruits[index]);
}
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId() == R.id.backup){
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.delete){
Toast.makeText(this,"You clicked Delete",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == R.id.settings){
Toast.makeText(this,"You clicked Settings",Toast.LENGTH_SHORT).show();
}if(item.getItemId() == android.R.id.home){
mDrawerLayout.openDrawer(GravityCompat.START);
}
return true;
}
}
可折叠式标题栏
CollapsingToolbarLayout
CollapsingToolbarLayout是不能单独存在的,他只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout的子布局
首先需要一个额外的活动来作为水果的详情展示页面,
在activity_fruit.xml中的内容主要分为两部分,一个是水果标题栏,一个是水果内容详情.
首先是实现标题栏部分,这里使用CoordinatorLayout来作为最外层布局,接着在CoordinatorLayout中嵌套一个AppBarLayout,接下来再在AppBarLayout中再嵌套一个CollapsingToolbarLayout.接下来在CollapsingToolbarLayout中定义标题栏的内容,在里面定义了一个ImageView和一个Toolbar.
这样就将水果标题栏的界面编写完成了,下面开始编写水果页面的内容详细部分.
水果内容详细的最外层布局就是使用了一个NestedScrollView,它和AppBarLLayout是平级的.
不管是ScrollView还是NestedSrollView,它们的内部都是只允许存在一个直接子布局,因此,如果我们想要在里面放入很多东西的话,通常先会嵌套一个LinearLatout,然后再在LinearLayout中放入具体的内容就可以了.
在LinearLayout中放入具体的内容,这里准备一个TextView来显示水果的内容详情,并将TextView放入到一个卡片式布局当中.再放入一个悬浮按钮,此时,布局页面就好了.
<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:layout_width="match_parent"
android:layout_height="250dp"
android:id="@+id/appBar"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/collapsing_toolbar"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fruit_image_view"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<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="35dp"
app:cardCornerRadius="4dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fruit_content_text"
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="@mipmap/dianzan"
app:layout_anchor="@id/appBar"
app:layout_anchorGravity="bottom|end" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
接下来修改FruitActivity中的代码,如下:
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(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit);
Intent intent = getIntent();
String fruitName = intent.getStringExtra(FRUIT_NAME);
int fruitImaged = intent.getIntExtra(FRUIT_IMAGE_ID,0);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbarLayout =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
ImageView fruitImageView = (ImageView) findViewById(R.id.fruit_image_view);
TextView fruitContentText = (TextView) findViewById(R.id.fruit_content_text);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
}
collapsingToolbarLayout.setTitle(fruitName);
Glide.with(this).load(fruitImaged).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) {
if(item.getItemId() == android.R.id.home){
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
接着在修改FruitAdapter中的代码,如下:
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private Context mContext;
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
CardView cardView;
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view){
super(view);
cardView = (CardView) view;
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitName = (TextView) view.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List<Fruit> fruitList){
mFruitList = fruitList;
}
@NonNull
@Override
public FruitAdapter.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);
final ViewHolder holder = new ViewHolder(view);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
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;
}
@Override
public void onBindViewHolder(@NonNull FruitAdapter.ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
rent, int viewType) {
if(mContext == null){
mContext = parent.getContext();
}
View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);
final ViewHolder holder = new ViewHolder(view);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
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;
}
@Override
public void onBindViewHolder(@NonNull FruitAdapter.ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}