Adapter
什么是Adapter?
- ① 用于将数据与视图连接起来的“翻译官”
- ② 具体表现如图所示:
常见的Adapter
- BaseAdapter:适配器公共父类
- ArrayAdapter:只能够展示文本的适配器
- SimpleAdapter:可以展示复杂数据的适配器
- 自定义Adapter:根据自己的需求自定义适配器
自定义Adapter
- 继承BaseAdapter
- 重写BaseAdapter中的抽象方法
- 完成视图与数据的映射
- 创建视图
- 创建数据
- 使用Adapter
ListView
什么是ListView?
- ① 用于展示列表数据的控件
- ② 具体参照如图:
如何使用ListView
- 搭建ListView布局
- 准备数据和单条数据视图
- 创建Adapter并初始化ListView
- 展示
ListView的缓冲原理
- 为什么要进行缓冲
- 缓冲原理
- 优化适配器实现ListView缓冲
- 使用缓存
- 优化控件的获取
GridView
什么是GridView?
- ① 用于展示列表数据的控件
- ② 具体参照如图:
如何使用GridView
- 搭建GridView布局
- 准备数据和单条数据视图
- 创建Adapter 并初始化GridView
- 展示
GridView的缓冲原理
- 为什么要进行缓冲
- 缓冲原理同ListView
- 优化适配器实现ListView缓冲
- 使用缓存
- 优化控件的获取
代码部分:
part1:
activity_main.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="vertical">
<!-- 用于演示ListView控件 -->
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="ListView演示"
android:textAllCaps="false"
android:onClick="button1Click"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="GridView演示"
android:textAllCaps="false"/>
</LinearLayout>
效果图:
activity_list_view_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="列表演示"
android:textSize="25sp"
android:gravity="center"
android:textColor="#000000"/>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"/>
</RelativeLayout>
效果图:
Cost.java
/**
* 消费实体类
*/
public class Cost {
//类型
private String type;
//时间
private String time;
//金额
private double money;
/**
* 构造方法
* @param type
* @param time
* @param money
*/
public Cost(String type, String time, double money) {
this.type = type;
this.time = time;
this.money = money;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
cost_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:minHeight="90dp">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/money"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"/>
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="话费充值"
android:layout_toRightOf="@+id/image"
android:layout_marginTop="25dp"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="14sp"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2020-05-28"
android:layout_alignLeft="@+id/type"
android:layout_below="@id/type"
android:layout_marginTop="5dp"/>
<TextView
android:id="@+id/money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:textSize="20sp"
android:textColor="#B82121"/>
</RelativeLayout>
效果图:
money.png
CostAdapter.java
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
public class CostAdapter extends BaseAdapter {
//数据
private List<Cost> data;
/* 需要将xml文件转换成视图类 */
private Context context;
private int count = 0;
/**
* 构造方法
* @param data
* @param context
*/
public CostAdapter(List<Cost> data, Context context) {
this.data = data;
this.context = context;
}
/**
* 获取总条数
* @return
*/
@Override
public int getCount() {
return data.size();
}
/**
* 获取指定的数据
* @param position
* @return
*/
@Override
public Object getItem(int position) {
return data.get(position);
}
/**
* 获取id
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 获取视图,将数据转换成视图(将数据填充到视图)
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/* 终极版 */
ViewHolder viewHolder;
//1.获取视图
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.cost_item, null);
//创建
viewHolder = new ViewHolder();
viewHolder.type = convertView.findViewById(R.id.type);
viewHolder.time = convertView.findViewById(R.id.time);
viewHolder.money = convertView.findViewById(R.id.money);
//与视图绑定
convertView.setTag(viewHolder);
} else {
//取用
viewHolder = (ViewHolder) convertView.getTag();
}
//2.给视图赋值
TextView type = viewHolder.type;
TextView time = viewHolder.time;
TextView money = viewHolder.money;
Cost cost = data.get(position);
type.setText(cost.getType());
time.setText(cost.getTime());
money.setText(Double.toString(cost.getMoney()));
//3.返回视图
return convertView;
/* 缓存版 */
//1.获取视图
// if (convertView == null) {
// LayoutInflater inflater = LayoutInflater.from(context);
// convertView = inflater.inflate(R.layout.cost_item, null);
// count++;
// }
//2.给视图赋值
// TextView type = convertView.findViewById(R.id.type);
// TextView time = convertView.findViewById(R.id.time);
// TextView money = convertView.findViewById(R.id.money);
// Cost cost = data.get(position);
// type.setText(cost.getType());
// time.setText(cost.getTime());
// money.setText(Double.toString(cost.getMoney()));
// Log.i("count", "创建的视图的数目是:" + count);
//3.返回视图
// return convertView;
/* 最初版,没有经过优化 */
//1.获取视图
// LayoutInflater inflater = LayoutInflater.from(context);
// View view = inflater.inflate(R.layout.cost_item, null);
//2.给视图赋值
// TextView type = view.findViewById(R.id.type);
// TextView time = view.findViewById(R.id.time);
// TextView money = view.findViewById(R.id.money);
// Cost cost = data.get(position);
// type.setText(cost.getType());
// time.setText(cost.getTime());
// money.setText(Double.toString(cost.getMoney()));
//3.返回视图
// return view;
}
class ViewHolder {
public TextView type;
public TextView time;
public TextView money;
}
}
ListViewDemoActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class ListViewDemoActivity extends AppCompatActivity {
//列表数据
private List<Cost> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo);
//初始化列表数据
data = new ArrayList<>();
final Cost cost = new Cost("话费充值", "2020-05-28", 100);
data.add(cost);
Cost cost1 = new Cost("QQ币充值", "2020-05-28", 10);
data.add(cost1);
Cost cost2 = new Cost("点卡充值", "2020-05-28", 15);
data.add(cost2);
Cost cost3 = new Cost("支付宝充值", "2020-05-28", 200);
data.add(cost3);
Cost cost4 = new Cost("微信充值", "2020-5-28", 300);
data.add(cost4);
Cost cost5 = new Cost("话费充值", "2020-05-28", 50);
data.add(cost5);
Cost cost6 = new Cost("支付宝充值", "2020-05-28", 200);
data.add(cost6);
Cost cost7 = new Cost("微信充值", "2020-5-28", 300);
data.add(cost7);
Cost cost8 = new Cost("话费充值", "2020-05-28", 50);
data.add(cost8);
Cost cost9 = new Cost("话费充值", "2020-05-28", 50);
data.add(cost9);
//初始化ListView
ListView listView = findViewById(R.id.listView);
final CostAdapter costAdapter = new CostAdapter(data, this);
listView.setAdapter(costAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//点击提示信息
Cost selectedCost = data.get(position);
String message = selectedCost.getType() + "花费" + selectedCost.getMoney();
Toast.makeText(ListViewDemoActivity.this, message, Toast.LENGTH_SHORT).show();
}
});
//动态添加数据
findViewById(R.id.title).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Cost cost10 = new Cost("动态添加测试", "2020-05-27", 100);
data.add(cost10);
costAdapter.notifyDataSetChanged();
}
});
}
}
效果图:
点击花费充值
点击列表演示
part2:
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//跳转ListView演示界面
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ListViewDemoActivity.class);
startActivity(intent);
}
});
//跳转GridView演示界面
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, GridViewDemoActivity.class);
startActivity(intent);
}
});
}
/**
* 按钮点击事件
* @param view
*/
//必须这么写,与xml中定义的保持一致--button1Click
// public void button1Click(View view) {
// Toast.makeText(this, "按钮被点击了", Toast.LENGTH_SHORT).show();
// }
}
activity_grid_view_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示GridView"
android:gravity="center"
android:textSize="30sp"/>
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title"
android:numColumns="2"
android:columnWidth="180dp"
android:stretchMode="spacingWidthUniform"
android:verticalSpacing="10dp"/>
</RelativeLayout>
效果图:
Goods.java
/**
* 食品实例
*/
public class Goods {
// 图片
private int image;
// 名称
private String name;
// 价格
private double price;
/**
* 构造方法
* @param image
* @param name
* @param price
*/
public Goods(int image, String name, double price) {
this.image = image;
this.name = name;
this.price = price;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
goods_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:color="#A5A5A5" android:width="1dp"></stroke>
<corners android:radius="10dp"></corners>
</shape>
效果图:
goods_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="180dp" android:layout_height="230dp"
android:minWidth="180dp" android:minHeight="230dp"
android:background="@drawable/goods_shape"
android:descendantFocusability="blocksDescendants">
<ImageView
android:id="@+id/iv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/apple"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="好吃的大苹果"
android:layout_below="@id/iv_image"
android:layout_alignLeft="@id/iv_image"
android:layout_marginTop="10dp"
android:textSize="16sp"
android:textColor="#000000"/>
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥20/箱"
android:layout_below="@id/tv_name"
android:layout_alignLeft="@id/tv_name"
android:layout_marginTop="10dp"
android:textSize="12sp"
android:textColor="#CE5F41"/>
<ImageButton
android:id="@+id/cartButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cart"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="15dp"
android:layout_marginBottom="25dp"
android:background="@null"/>
</RelativeLayout>
效果图:
apple.png
banana.png
melon.png
peach.png
pear.png
cart.png
GoodsAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
/**
* 商品的Adapter
*/
public class GoodsAdapter extends BaseAdapter {
// 数据
private List<Goods> data;
// 上下文,用于生成View
private Context context;
/**
* 构造方法
* @param data
* @param context
*/
public GoodsAdapter(List<Goods> data, Context context) {
this.data = data;
this.context = context;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
// 1.创建视图
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.goods_item, null);
viewHolder = new ViewHolder();
viewHolder.image = convertView.findViewById(R.id.iv_image);
viewHolder.name = convertView.findViewById(R.id.tv_name);
viewHolder.price = convertView.findViewById(R.id.tv_price);
viewHolder.cartButton = convertView.findViewById(R.id.cartButton);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// 2.给视图进行数据赋值
ImageView image = viewHolder.image;
TextView name = viewHolder.name;
TextView price = viewHolder.price;
final Goods goods = data.get(position);
image.setImageResource(goods.getImage());
name.setText(goods.getName());
String priceString = "¥" + goods.getPrice() + "/箱";
price.setText(priceString);
// 3.给按钮绑定点击事件
viewHolder.cartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1.获取点击的商品的名称
String message = goods.getName() + "已加入购物车!";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
});
// 返回View
return convertView;
}
class ViewHolder {
public ImageView image;
public TextView name;
private TextView price;
private ImageButton cartButton;
}
}
GridViewDemoActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class GridViewDemoActivity extends AppCompatActivity {
// 商品列表
private List<Goods> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view_demo);
data = new ArrayList<>();
Goods goods = new Goods(R.drawable.apple, "红红的大苹果", 20);
data.add(goods);
Goods goods1 = new Goods(R.drawable.banana, "芝麻大香蕉", 30);
data.add(goods1);
Goods goods2 = new Goods(R.drawable.melon, "沙瓤大西瓜", 10);
data.add(goods2);
Goods goods3 = new Goods(R.drawable.peach, "好吃的水蜜桃", 10);
data.add(goods3);
Goods goods4 = new Goods(R.drawable.pear, "好吃的大黄梨", 20);
data.add(goods4);
Goods goods5 = new Goods(R.drawable.apple, "红红的大苹果", 20);
data.add(goods5);
Goods goods6 = new Goods(R.drawable.melon, "沙瓤大西瓜", 20);
data.add(goods6);
Goods goods7 = new Goods(R.drawable.peach, "好吃的水蜜桃", 20);
data.add(goods7);
// 初始化GridView
GridView gridView = findViewById(R.id.gridView);
final GoodsAdapter goodsAdapter = new GoodsAdapter(data, this);
gridView.setAdapter(goodsAdapter);
// 给GridView绑定点击事件
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(GridViewDemoActivity.this, "商品被点击了", Toast.LENGTH_SHORT).show();
}
});
// 演示动态添加数据
findViewById(R.id.title).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Goods goods8 = new Goods(R.drawable.money, "钱钱钱钱钱钱", 20);
data.add(goods8);
goodsAdapter.notifyDataSetChanged();
}
});
}
}