Android之BaseAdapter

一、前面章节简单介绍了 ArrayAdapter 和 SimpleAdapter 。

其中,ArrayAdapter 可以显示简单的文本信息,SimpleAdapter 功能丰富一些,可以显示文本和图片的组合,Android 将这两个 Adapter 的结构封装的很好,可以直接拿过来使用。

但有时,我们需要更加灵活的布局,这就用到了 BaseAdapter ,通过一个小例子来看具体代码,如下图:


这里写图片描述


二、项目结构图,用到了三个类、两个布局文件:

三个类:

  • MainActivity : 继承 Activity
  • MyBaseAdapter : 继承 MyBaseAdapter
  • People : 实体类

两个布局文件:

  • activity_mian.xml
  • list_item.xml

这里写图片描述


三、具体代码:

1.0 list_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="match_parent">

    <ImageView
        android:id="@+id/icon2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"/>
    <TextView
        android:id="@+id/nameEN"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/icon2"/>
    <TextView
        android:id="@+id/nameCN"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/icon2"
        android:layout_below="@id/nameEN"/>
    <Button
        android:id="@+id/btn_estimate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="@string/estimate"/>
    <TextView
        android:id="@+id/estimate_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/btn_estimate"/>

</RelativeLayout>

2.0 activity_mian.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">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

3.0 People:

package com.lgl.helloworld;

import android.graphics.Bitmap;

/**
 * Created by lgl on 2015/11/3.
 */
public class People {

    //头像、中文名、英文名、评价数量
    private Bitmap icon;
    private String nameEN;
    private String nameCN;
    private int estimateNum;

    //有参构造方法
    public People(Bitmap icon, String nameEN, String nameCN, int estimateNum) {
        this.icon = icon;
        this.nameEN = nameEN;
        this.nameCN = nameCN;
        this.estimateNum = estimateNum;
    }

    //get 和 set 方法
    public Bitmap getIcon() {
        return icon;
    }
    public void setIcon(Bitmap icon) {
        this.icon = icon;
    }
    public String getNameEN() {
        return nameEN;
    }
    public void setNameEN(String nameEN) {
        this.nameEN = nameEN;
    }
    public String getNameCN() {
        return nameCN;
    }
    public void setNameCN(String nameCN) {
        this.nameCN = nameCN;
    }
    public int getEstimateNum() {
        return estimateNum;
    }
    public void setEstimateNum(int estimateNum) {
        this.estimateNum = estimateNum;
    }

}

4.0 MyBaseAdapter:

package com.lgl.helloworld;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by lgl on 2015/11/3.
 */
public class MyBaseAdapter extends BaseAdapter {

    private Context context;    //上下文
    private List<People> list;  //数据
    private LayoutInflater inflater;

    public MyBaseAdapter(Context context) {
        this.context = context;
    }

    /**
     * 取得从MainActivity传递过来的list
     */
    public void setData(List<People> list) {
        this.list = list;
    }

    /**
     * 获取显示的条数
     */
    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    /**
     * 获取当前的item
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        //判断当前的item是否为空
        if(convertView == null) {
            holder = new ViewHolder();
            inflater = LayoutInflater.from(context);
            //将list_item文件转换成一个view
            convertView = inflater.inflate(R.layout.list_item, null);
            //将这些view封装到ViewHolder类里
            holder.icon = (ImageView) convertView.findViewById(R.id.icon2);
            holder.nameEN = (TextView) convertView.findViewById(R.id.nameEN);
            holder.nameCN = (TextView) convertView.findViewById(R.id.nameCN);
            holder.estimateNum = (TextView) convertView.findViewById(R.id.estimate_num);
            holder.btn_estimate = (Button) convertView.findViewById(R.id.btn_estimate);
            //将这些view缓存起来,供下次调用
            convertView.setTag(holder);
        } else {    //复用了回收的view 只需要直接作内容填充的修改就好了
            holder = (ViewHolder) convertView.getTag();
        }
        People people = list.get(position);
        holder.icon.setImageBitmap(people.getIcon());
        holder.nameEN.setText(people.getNameEN());
        holder.nameCN.setText(people.getNameCN());
        holder.estimateNum.setText(people.getEstimateNum() + "");
        return convertView;
    }

    /**
     * 将需要缓存的那些view封装好
     */
    class ViewHolder {
        private ImageView icon;
        private TextView nameEN;
        private TextView nameCN;
        private TextView estimateNum;
        private Button btn_estimate;
    }

}

5.0 MainActivity:

package com.lgl.helloworld;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    private ListView listView;
    private List<People> list = new ArrayList<People>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //添加数据
        setPeople();
        listView = (ListView) findViewById(R.id.list_view);
        MyBaseAdapter adapter = new MyBaseAdapter(this);
        //将数据传递给adapter
        adapter.setData(list);
        listView.setAdapter(adapter);
    }

    /**
     * 添加几条数据
     */
    public void setPeople() {
        Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.f1);
        Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.f2);
        Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.f3);
        Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.f4);
        Bitmap bitmap5 = BitmapFactory.decodeResource(getResources(), R.drawable.f5);
        People people1 = new People(bitmap1, "huluwa", "葫芦娃", 0);
        People people2 = new People(bitmap2, "chaoren", "超人", 0);
        People people3 = new People(bitmap3, "aoteman", "奥特曼", 0);
        People people4 = new People(bitmap4, "gangtiexia", "钢铁侠", 0);
        People people5 = new People(bitmap5, "lvjuren", "绿巨人", 0);
        list.add(people1);
        list.add(people2);
        list.add(people3);
        list.add(people4);
        list.add(people5);
    }

}

总结: 总结一下 getView(int position, View convertView, ViewGroup parent) 方法吧

手机屏幕中的每一个 View 都对应 ListView 中的一个Item,ListView 每显示一个 Item 都需要 Adapter 调用一次 getView 方法,这个方法返回的参数 convertView 就是这个 Item 要显示的 View。

如果要显示一万条数据,那岂不是要调用一万次 getView 方法,为每一个 Item 都创建一个 View 对象?这势必将造成内存的极大浪费,增加时间开销,影响手机性能。

为此,Android 提供了一个Recycler(反复循环器)构件,当 ListView 中的 Item 从屏幕上方滑出视角之外时,对应的 Item 会被缓存到 Recycler(反复循环器)中,相应的会从下方生成一个 Item ,而此时调用的 getView 中的 convertView 参数就是从上方滑出屏幕的 Item 的 View。

复用了这个 convertView ,大大改善了性能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值