Android适配器

安卓的适配器在我看来是一个非常重要的知识点,面对形式相同但数据源较多的情况时,适配器是一个比较好的解决方法。数据适配器是建立了数据源与控件之间的适配关系,将数据源转换为控件能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性。
这篇文章就说一下如何实现适配器。

首先说一下ListView的显示和缓存机制

ListView、GridView等控件可以展示大量的数据信息,假如下图中的ListView可以展示100条信息,但是屏幕的尺寸是有限的,一屏幕只能显示下图中的4条。当向上滑动ListView的时候,T1被滑出了屏幕区域,那么系统就会将T1回收到Recycler中,即View缓冲池中,而将要显示的T5则会从缓存池中取出布局文件,并重新设置好T5需要显示的数据,并放入需要显示的位置。这就是ListView的缓冲机制,总结起来就是一句话:需要时才显示,显示完就被会收到缓存。ListView,GridView等数据显示控件通过这种缓存机制可以极大的节省系统资源。

然后来看一下实现方法

效果图

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <ListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
/> </LinearLayout>

item_lv.xml (ListView中每条信息的显示布局)

 <?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/iv_image"
android:src="@mipmap/ic_launcher"
android:layout_width="60dp"
android:layout_height="60dp"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_toEndOf="@id/iv_image"
android:text="Title"
android:gravity="center"
android:textSize="25sp"/> <TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/iv_image"
android:layout_below="@id/tv_title"
android:text="Content"
android:gravity="center"
android:textSize="20sp"/> </RelativeLayout>

ItemBean.java(数据源)

 public class ItemBean {

     public int itemImageResId;  //图像资源ID
public String itemTitle; //标题
public String itemContent; //内容 public ItemBean(int itemImageResId, String itemTitle, String itemContent) {
this.itemImageResId = itemImageResId;
this.itemTitle = itemTitle;
this.itemContent = itemContent;
} }

MainActivity.java

 public class MainActivity extends Activity {

     ListView mListView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); List<ItemBean> itemBeanList = new ArrayList<>();
for (int i = 0;i < 20; i ++){
itemBeanList.add(new ItemBean(R.mipmap.ic_launcher, "标题" + i, "内容" + i));
}
mListView = (ListView) findViewById(R.id.lv_main);
//设置ListView的数据适配器
mListView.setAdapter(new MyAdapter(this,itemBeanList));
} }
MyAdapter.java
此方式不仅利用了ListView的缓存机制,而且使用ViewHolder类来实现显示数据视图的缓存,避免多次调用findViewById来寻找控件,以达到优化程序的目的。
所以,大家在平时的开发中应当尽量使用这种方式进行getView的实现。
 public class MyAdapter extends BaseAdapter {

     private List<ItemBean> mList;//数据源
private LayoutInflater mInflater;//布局装载器对象 // 通过构造方法将数据源与数据适配器关联起来
// context:要使用当前的Adapter的界面对象
public MyAdapter(Context context, List<ItemBean> list) {
mList = list;
mInflater = LayoutInflater.from(context);
} @Override
//ListView需要显示的数据数量
public int getCount() {
return mList.size();
} @Override
//指定的索引对应的数据项
public Object getItem(int position) {
return mList.get(position);
} @Override
//指定的索引对应的数据项ID
public long getItemId(int position) {
return position;
} @Override
//返回每一项的显示内容
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
//如果view未被实例化过,缓存池中没有对应的缓存
if (convertView == null) {
viewHolder = new ViewHolder();
// 由于我们只需要将XML转化为View,并不涉及到具体的布局,所以第二个参数通常设置为null
convertView = mInflater.inflate(R.layout.item_lv, null); //对viewHolder的属性进行赋值
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);
viewHolder.title = (TextView) convertView.findViewById(R.id.tv_title);
viewHolder.content = (TextView) convertView.findViewById(R.id.tv_content); //通过setTag将convertView与viewHolder关联
convertView.setTag(viewHolder);
}else{//如果缓存池中有对应的view缓存,则直接通过getTag取出viewHolder
viewHolder = (ViewHolder) convertView.getTag();
}
// 取出bean对象
ItemBean bean = mList.get(position); // 设置控件的数据
viewHolder.imageView.setImageResource(bean.itemImageResId);
viewHolder.title.setText(bean.itemTitle);
viewHolder.content.setText(bean.itemContent); return convertView;
}
// ViewHolder用于缓存控件,三个属性分别对应item布局文件的三个控件
class ViewHolder{
public ImageView imageView;
public TextView title;
public TextView content;
} }

ViewHolder优化BaseAdapter的整体步骤:

  1. 创建bean对象,用于封装数据。
  2. 在构造方法中初始化的数据List。
  3. 创建ViewHolder类,创建布局映射关系。
  4. 判断convertView,为空则创建,并设置tag,不为空则通过tag取出ViewHolder。
  5. 给ViewHolder的控件设置数据。

Android适配器的更多相关文章

  1. android 适配器simpleadapter和baseadapter区别

    android 适配器 simpleadapter 和 baseadapter 设计网络程序或者数据处理显示程序的时候,常常会使用 simpleadapter 和baseadapter 来实现. ad ...

  2. android 适配器 ArrayAdapter,SimpleAdapter的学习

    今天认真看了下android适配器,学习了下它的使用方法. 一,ArrayAdapter ArrayAdapter 比较简单,只可以存放一行文本信息.下面是简单的实现 private ListView ...

  3. android适配器及监听点击和滚动在ListView中的使用

    package com.example.demon08; import java.util.ArrayList;import java.util.HashMap;import java.util.Li ...

  4. Android适配器Adapter学习

    在开发中我们需要绑定一些数据展现到桌面上,这是就需要AdapterView.AdapterView是ViewGroup的子类,它决定了怎么展现视图通过Adapter来绑定特殊的数据类型. Adapte ...

  5. android 适配器 BaseAdapter 的学习

    昨天晚上看了下ArrayAdapter,和SimpleAdapter,今天早上起来看完了球赛,又继续要开始学习了,适配器除了前面的两种,还有一种常用的就是BaseAdapter,他是一个抽象类.事实上 ...

  6. android适配器Adapter

    一.什么是适配器,适配器有什么用? 适配器是AdapterView视图(如ListView - 列表视图控件.Gallery - 缩略图浏览器控件.GridView - 网格控件.Spinner - ...

  7. Android适配器Adapter的学习

    Android中有很多的适配器,首先看看这些适配器的继承结构 这些适配器中,BaseAdapter用的最多,也用的最熟,先放过他,从ArrayAdapter开始 一个listAdapter用来管理一个 ...

  8. Android 适配器 自定义

    前言:最近看了几个开源项目,发现适配器这东西用的很多,一开始觉得这东西高大上,其实呢,感觉就是一个中转站,或者说是一个接口工具,将数据填充到一个视图中,几乎任何项目都会涉及到.所以今天也简单看了一下, ...

  9. Android 适配器教程 (六)

    我们的适配器学习已经接近尾声了.尽管这不是一个大问题,可是确实是值得学习的一块知识,回忆一下之前五讲的知识.我们已经学到了非常多东西了. 在之前五讲中.我们已经由浅入深的认识了适配器,从最简单的Lis ...

随机推荐

  1. 对话|人工智能先驱Yoshua Bengio

    ​​ ​ Bengio"> 今年1月份,微软收购深度学习初创公司Maluuba时,Maluuba公司德高望重的顾问.深度学习先驱Yoshua Bengio也接手了微软的人工智能研究顾问 ...

  2. 【简单版】hexo博客搭建流程梳理

    前言 本文章会为你梳理一个搭建hexo博客的流程 相关网址: Docs: https://hexo.io/docs/ Themes: https://hexo.io/themes/ 安装hexo 准备 ...

  3. Java2变量和运算符

    课后作业:[必做题] 1√AB互换 已知a,b均是整型变量,写出将a,b两个变量中的值互换的程序.(知识点:变量和运算符综合应用) [必做题] package com.two; public clas ...

  4. python 实现各种进度条

    1. 时间进度条 class Tiao(object): def __init__(self): self.obj1 = datetime.timedelta(seconds=1) self.var ...

  5. iMX287A嵌入式Qt环境搭建

    目录 1.嵌入式Qt简介 2.查看开发板Qt库的版本 3.第一个嵌入式Qt程序--Hello World 4.Linux桌面版本Qt环境的搭建 5.注意 @ 1.嵌入式Qt简介 Qt 是一个跨平台的应 ...

  6. 从头认识js-函数表达式

    定义函数的方式有两种: 1.函数声明(特征:函数声明提升,在执行代码之前会先读取函数声明,这就意味着可以把函数声明放在调用它的语句之后) 2.函数表达式(函数表达式与其他表达式一样,使用之前必须先声明 ...

  7. 【转】css样式自动换行(强制换行)

    原文链接:http://blog.csdn.net/ye987987... 自动换行问题,正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大,挺让人头疼,下面介绍的是CSS如何实现换行的 ...

  8. bootstrapValidator验证的remote中data属性里获取select一直是默认值

    budgetEditionNo:{ message:'版本号输入不正确' , validators:{ notEmpty:{ message:'版本号不能为空,请填写' } , remote:{ ur ...

  9. 如何优雅的把后台数据(通常是JSON)轻松渲染到html页面

    如何优雅的把后台数据(通常是JSON)轻松渲染到html页面 在我们做前后端分离的时候,都有遇到过一些看起卡很简答,确无从下手的问题把.比方说后台给了前端一个list集合,集合里面有很多学生,我们现在 ...

  10. ASP.NET Core 快速入门(Razor Pages + Entity Framework Core)

    引子 自从 2009 年开始在博客园写文章,这是目前我写的最长的一篇文章了. 前前后后,我总共花了 5 天的时间,每天超过 3 小时不间断写作和代码调试.总共有 8 篇文章,每篇 5~6 个小结,总截 ...