1. Xml -> View 对象
Xml 转换为 View 对象的三种方式
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
// 方式一,底层调用 LayoutInflater.from
// 参数一:上下文,参数二:布局资源 id
// 参数三:ViewGroup(比如如 LinearLayout,RelativeLayout),如果传入,创建出的 View 就是 ViewGroup 的子 View,如果不需要放入 ViewGroup,传入 null
view = View.inflate(mContext, R.layout.item, null);
// 方式二
view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
// 方式三,谷歌源码中使用这种方法
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, null);
}
2. BaseAdapter
Adapter 在 MVC 模式中起到控制器的作用,将数据填充到视图中
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
// 这个方法的返回值决定了当前 listview 究竟要展示多少条数据
return 5;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 有多少数据就会调用多少次 getView, getView 返回每一条数据的视图
// position: 此视图的位置
// convertView: 如果可能,要重用的旧视图
// parent: 此视图最终要附加到的父级
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
TextView txt_aName = convertView.findViewById(R.id.txt_aName);
txt_aName.setText("aaa");
return convertView;
}
}
3. BaseAdapter 优化
上面代码,每次我们都将 xml 转换为 View,如果我们滑动界面过快,导致系统来不及回收旧资源,并过多创建新的资源,会导致内存爆掉,所以我们需要尽可能的使用旧的视图。
convertView 即为系统给我们的可以重用的视图,如果为空,我们再去创建,不为空,直接使用即可。
findViewById 也会被调用多次,我们也需要优化,尽可能重用。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
// 为空则创建
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal, parent, false);
holder = new ViewHolder();
holder.txt_aName = convertView.findViewById(R.id.txt_aName);
convertView.setTag(holder); //将Holder存储到convertView中
} else {
// 不为空则复用
holder = (ViewHolder) convertView.getTag();
}
holder.txt_aName.setText("aaa");
return convertView;
}
static class ViewHolder {
TextView txt_aName;
}
4. ListView 入门
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Listview 宽度和高度不要使用 wrap_content,会导致 getView 多次被调用(浪费性能),因为要计算界面到底要放几条数据
5. ArrayAdapter
每个条目中需要修改的数据十分简单 只有一个 textview 的内容需要修改 这个时候可以使用 arrayadapter
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv_list = findViewById(R.id.lv_list);
String[] names = {"张三","李四","王五","赵六","冯奇"};
// 第一个参数:上下文
// 第二个参数:包含且只有一个 textview 的布局文件 id
// 第三个参数 要展示的数据
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item, names);
lv_list.setAdapter(adapter);
}
6. SimpleAdapter
功能比较强大,用起来比较复杂
Activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginLeft="5dp"
android:text="旧情复燃...."/>
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginLeft="5dp"
android:textColor="#88000000"
android:text="旧情复燃...."/>
</LinearLayout>
</LinearLayout>
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv_list = findViewById(R.id.lv_list);
List<Map<String, String>> data = new ArrayList<Map<String,String>>();
String[] from = {"title","content"};
Map<String, String> item1 = new HashMap<String, String>();
item1.put("title", "中国足球再次冲击世界杯");
item1.put("content", "9月6日晚在沈阳与伊朗0:0");
data.add(item1);
Map<String, String> item2 = new HashMap<String, String>();
item2.put("title", "黑马android95期高薪就业");
item2.put("content", "黑马android95期高薪就业平均薪水20k");
data.add(item2);
int[] to = new int[]{R.id.tv_title,R.id.tv_content};
// 第一个参数 上下文
// 第二个参数 要显示的数据,每一个条目的数据放到一个 map 中,再放到 list 里
// 第三个参数 要加载条目的布局文件的 id
// 第四个参数 string 数组,每一个元素,都是保存要展示数据的 map 中的 key,要显示的数据是 key 对应的 value
// 第五个参数 int 数组,存放的是要展示数据的控件 id,每一个元素跟 String 数组的元素要对应起来
// 总结: 展示数据是用 string 数组的元素作为 Key 到 map 中取值,取出的值展示到 int 数组中对应元素的控件 id 对应的控件上
SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item, from, to);
lv_list.setAdapter(adapter);
}
7. 可复用的 BaseAdapter
参考文献:菜鸟教程
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_book"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="0dp"/>
<ListView
android:id="@+id/list_app"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="0dp"/>
</LinearLayout>
item_one.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/img_icon"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@mipmap/iv_icon_baidu" />
<TextView
android:id="@+id/txt_aname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:text="百度"
android:textSize="20sp" />
</LinearLayout>
item_two.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/txt_bname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="《第一行代码Android》"
android:textColor="#F3684A"
android:textSize="18sp" />
<TextView
android:id="@+id/txt_bauthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="郭霖"
android:textColor="#44BDED"
android:textSize="18sp" />
</LinearLayout>
App.java
package com.mi.study;
public class App {
private int aIcon;
private String aName;
public App() {
}
public App(int aIcon, String aName) {
this.aIcon = aIcon;
this.aName = aName;
}
public int getaIcon() {
return aIcon;
}
public String getaName() {
return aName;
}
public void setaIcon(int aIcon) {
this.aIcon = aIcon;
}
public void setaName(String aName) {
this.aName = aName;
}
}
Book.java
package com.mi.study;
public class Book {
private String bName;
private String bAuthor;
public Book() {
}
public Book(String bName, String bAuthor) {
this.bName = bName;
this.bAuthor = bAuthor;
}
public String getbName() {
return bName;
}
public String getbAuthor() {
return bAuthor;
}
public void setbName(String bName) {
this.bName = bName;
}
public void setbAuthor(String bAuthor) {
this.bAuthor = bAuthor;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Context mContext;
private ListView list_book;
private ListView list_app;
private MyAdapter<App> myAdapter1 = null;
private MyAdapter<Book> myAdapter2 = null;
private List<App> mData1 = null;
private List<Book> mData2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
init();
}
private void init() {
list_book = (ListView) findViewById(R.id.list_book);
list_app = (ListView) findViewById(R.id.list_app);
//数据初始化
mData1 = new ArrayList<App>();
mData1.add(new App(R.mipmap.iv_icon_baidu, "百度"));
mData1.add(new App(R.mipmap.iv_icon_douban, "豆瓣"));
mData1.add(new App(R.mipmap.iv_icon_zhifubao, "支付宝"));
mData2 = new ArrayList<Book>();
mData2.add(new Book("《第一行代码Android》", "郭霖"));
mData2.add(new Book("《Android群英传》", "徐宜生"));
mData2.add(new Book("《Android开发艺术探索》", "任玉刚"));
//Adapter初始化
myAdapter1 = new MyAdapter<App>((ArrayList) mData1, R.layout.item_one) {
@Override
public void bindView(ViewHolder holder, App obj) {
holder.setImageResource(R.id.img_icon, obj.getaIcon());
holder.setText(R.id.txt_aname, obj.getaName());
}
};
myAdapter2 = new MyAdapter<Book>((ArrayList) mData2, R.layout.item_two) {
@Override
public void bindView(ViewHolder holder, Book obj) {
holder.setText(R.id.txt_bname, obj.getbName());
holder.setText(R.id.txt_bauthor, obj.getbAuthor());
}
};
//ListView设置下Adapter:
list_book.setAdapter(myAdapter2);
list_app.setAdapter(myAdapter1);
}
}
MyAdapter.java
public abstract class MyAdapter<T> extends BaseAdapter {
private ArrayList<T> mData;
private int mLayoutRes; //布局id
public MyAdapter() {
}
public MyAdapter(ArrayList<T> mData, int mLayoutRes) {
this.mData = mData;
this.mLayoutRes = mLayoutRes;
}
@Override
public int getCount() {
return mData != null ? mData.size() : 0;
}
@Override
public T getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes, position);
bindView(holder, getItem(position));
return holder.getItemView();
}
public abstract void bindView(ViewHolder holder, T obj);
//添加一个元素
public void add(T data) {
if (mData == null) {
mData = new ArrayList<>();
}
mData.add(data);
notifyDataSetChanged();
}
//往特定位置,添加一个元素
public void add(int position, T data) {
if (mData == null) {
mData = new ArrayList<>();
}
mData.add(position, data);
notifyDataSetChanged();
}
public void remove(T data) {
if (mData != null) {
mData.remove(data);
}
notifyDataSetChanged();
}
public void remove(int position) {
if (mData != null) {
mData.remove(position);
}
notifyDataSetChanged();
}
public void clear() {
if (mData != null) {
mData.clear();
}
notifyDataSetChanged();
}
public static class ViewHolder {
private SparseArray<View> mViews; //存储ListView 的 item中的View
private View item; //存放convertView
private int position; //游标
private Context context; //Context上下文
//构造方法,完成相关初始化
private ViewHolder(Context context, ViewGroup parent, int layoutRes) {
mViews = new SparseArray<>();
this.context = context;
View convertView = LayoutInflater.from(context).inflate(layoutRes, parent, false);
convertView.setTag(this);
item = convertView;
}
//绑定ViewHolder与item
public static ViewHolder bind(Context context, View convertView, ViewGroup parent, int layoutRes, int position) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder(context, parent, layoutRes);
} else {
holder = (ViewHolder) convertView.getTag();
holder.item = convertView;
}
holder.position = position;
return holder;
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(int id) {
T t = (T) mViews.get(id);
if (t == null) {
t = (T) item.findViewById(id);
mViews.put(id, t);
}
return t;
}
/**
* 获取当前条目
*/
public View getItemView() {
return item;
}
/**
* 获取条目位置
*/
public int getItemPosition() {
return position;
}
/**
* 设置文字
*/
public ViewHolder setText(int id, CharSequence text) {
View view = getView(id);
if (view instanceof TextView) {
((TextView) view).setText(text);
}
return this;
}
/**
* 设置图片
*/
public ViewHolder setImageResource(int id, int drawableRes) {
View view = getView(id);
if (view instanceof ImageView) {
((ImageView) view).setImageResource(drawableRes);
} else {
view.setBackgroundResource(drawableRes);
}
return this;
}
/**
* 设置点击监听
*/
public ViewHolder setOnClickListener(int id, View.OnClickListener listener) {
getView(id).setOnClickListener(listener);
return this;
}
/**
* 设置可见
*/
public ViewHolder setVisibility(int id, int visible) {
getView(id).setVisibility(visible);
return this;
}
/**
* 设置标签
*/
public ViewHolder setTag(int id, Object obj) {
getView(id).setTag(obj);
return this;
}
}
}
8. ListView 多布局实现
参考:菜鸟教程
MutiLayoutAdapter.java
public class MutiLayoutAdapter extends BaseAdapter {
//定义两个类别标志
private static final int TYPE_BOOK = 0;
private static final int TYPE_APP = 1;
private Context mContext;
private ArrayList<Object> mData = null;
public MutiLayoutAdapter(Context mContext, ArrayList<Object> mData) {
this.mContext = mContext;
this.mData = mData;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
if (mData.get(position) instanceof App) {
return TYPE_APP;
} else if (mData.get(position) instanceof Book) {
return TYPE_BOOK;
}
return super.getItemViewType(position);
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
ViewHolder1 holder1 = null;
ViewHolder2 holder2 = null;
if (convertView == null) {
switch (type) {
case TYPE_APP:
holder1 = new ViewHolder1();
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_one, parent, false);
holder1.img_icon = convertView.findViewById(R.id.img_icon);
holder1.txt_aname = convertView.findViewById(R.id.txt_aname);
convertView.setTag(holder1);
break;
case TYPE_BOOK:
holder2 = new ViewHolder2();
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_two, parent, false);
holder2.txt_bname = convertView.findViewById(R.id.txt_bname);
holder2.txt_bauthor = convertView.findViewById(R.id.txt_bauthor);
convertView.setTag(holder2);
break;
}
} else {
switch (type) {
case TYPE_APP:
holder1 = (ViewHolder1) convertView.getTag();
break;
case TYPE_BOOK:
holder2 = (ViewHolder2) convertView.getTag();
break;
}
}
Object obj = mData.get(position);
//设置下控件的值
switch (type) {
case TYPE_APP:
App app = (App) obj;
if (app != null) {
holder1.img_icon.setImageResource(app.getaIcon());
holder1.txt_aname.setText(app.getaName());
}
break;
case TYPE_BOOK:
Book book = (Book) obj;
if (book != null) {
holder2.txt_bname.setText(book.getbName());
holder2.txt_bauthor.setText(book.getbAuthor());
}
break;
}
return convertView;
}
private static class ViewHolder1 {
ImageView img_icon;
TextView txt_aname;
}
private static class ViewHolder2 {
TextView txt_bname;
TextView txt_bauthor;
}
}
核心:
- 重写 getItemViewType() 方法对应 View 是哪个类别。
- 重写 getViewTypeCount() 方法iew返回 总共多少个类别
- getView 会自动调用 getItemViewType 获得对应类别,再加载对应的 convertView
9. RecyclerView
替代 ListView 的,比 ListView 更强大,支持横向滚动
9.1 纵向滚动
布局:
fruit_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp" >
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
adapter
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).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.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}
@Override
public int getItemCount() {
return mFruitList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view) {
super(view);
fruitImage = view.findViewById(R.id.fruit_image);
fruitName = view.findViewById(R.id.fruitname);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<Fruit>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// 指定 recyclerView 的布局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
}
9.2 横向滚动
fruit_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<Fruit>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// 指定 recyclerView 的布局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
}
9.3 网格布局
RecyclerView 提供了 GridLayoutManager 实现网格布局。
9.4 瀑布流布局
RecyclerView 提供了 StaggeredGridLayoutManager 实现瀑布流布局。
fruit_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp" >
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp" />
</LinearLayout>
瀑布流布局的宽度根据布局的列数自动适配,不是固定值,使用 match_parent 即可
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<Fruit>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// 垂直方向 3 列
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
}
9.5 点击事件
RecyclerView 所有的点击事件都由具体的 View 去注册
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "you clicked view " + fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
}
}