Android开发学习笔记整理(9)-Adapter、ListView和GridView

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

}

效果图:

点击某商品

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值