博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
连接AdapterView视图和数据源的桥梁:Adapter适配器(3)
阅读量:6604 次
发布时间:2019-06-24

本文共 6688 字,大约阅读时间需要 22 分钟。

BaseAdapter是一种使用频率较高的适配器,因为它可以通过自定义最大程度扩展满足各种情景下的使用。我们不仅需要知道适配器的使用,进一步我们也需要了解适配器的原理。

问题是最好的学习方式,下面主要讨论这么几个问题:

Q1.ListView中每个Item的创建

Q2.ListView中Item的复用

Q3.ListView中屏幕显示的Item与复用生成Item之间的关系

  首先写一个简单的demo.

1 package com.aellenlei.baseadapterdemo; 2  3 import android.support.v7.app.AppCompatActivity; 4 import android.os.Bundle; 5 import android.widget.ListView; 6  7 import java.util.ArrayList; 8 import java.util.List; 9 10 public class MainActivity extends AppCompatActivity {11 12     @Override13     protected void onCreate(Bundle savedInstanceState) {14         super.onCreate(savedInstanceState);15         setContentView(R.layout.activity_main);16 17         //1.findViewById18         ListView listView = (ListView) findViewById(R.id.listView);19 20         //2.初始化数据源21         List
list = new ArrayList<>();22 for (int i = 0; i < 5; i++) {23 ItemBean itemBean = new ItemBean();24 itemBean.postion = i;25 itemBean.title = "title " + i;26 itemBean.content = "content " + i;27 list.add(itemBean);28 }29 30 //3.初始化适配器31 ItemBeanAdapter itemBeanAdapter = new ItemBeanAdapter(list, getApplicationContext());32 33 //4.ListView绑定适配器34 listView.setAdapter(itemBeanAdapter);35 }36 }
MainActivity.java
1 package com.aellenlei.baseadapterdemo; 2  3 import android.content.Context; 4 import android.util.Log; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.BaseAdapter; 9 import android.widget.CheckBox;10 import android.widget.ImageView;11 import android.widget.TextView;12 13 import java.util.List;14 15 /**16  * User AellenLei17  * NAME ItemBeanAdapter18  * DATE 2016/3/719  */20 public class ItemBeanAdapter extends BaseAdapter {21 22     private List
mData;23 private Context mContext;24 25 public ItemBeanAdapter(List
mData, Context mContext) {26 this.mData = mData;27 this.mContext = mContext;28 }29 30 @Override31 public int getCount() {32 return mData == null ? 0 : mData.size();33 }34 35 @Override36 public ItemBean getItem(int position) {37 return mData.get(position);38 }39 40 @Override41 public long getItemId(int position) {42 return position;43 }44 45 @Override46 public View getView(int position, View convertView, ViewGroup parent) {47 48 Log.d("msg", position + "," + getItem(position).postion + "," + getItem(position).title + ". "49 + ((convertView == null) ? ("covertView = null") :50 (((TextView) convertView.findViewById(R.id.item_title)).getText().toString()))51 );52 53 54 View ret;55 56 if (convertView != null) {57 ret = convertView;58 } else {59 ret = LayoutInflater.from(mContext).inflate(R.layout.item, null);60 ViewHolder holder = new ViewHolder();61 holder.itemIcon = (ImageView) ret.findViewById(R.id.item_icon);62 holder.itemTitle = (TextView) ret.findViewById(R.id.item_title);63 holder.itemContent = (TextView) ret.findViewById(R.id.item_content);64 holder.itemDate = (TextView) ret.findViewById(R.id.item_date);65 holder.itemChecked = (CheckBox) ret.findViewById(R.id.item_check);66 ret.setTag(holder);67 }68 69 ViewHolder viewHolder = (ViewHolder) ret.getTag();70 71 ItemBean itemBean = getItem(position);72 73 viewHolder.itemIcon.setImageResource(R.mipmap.ic_launcher);74 viewHolder.itemTitle.setText(itemBean.title);75 viewHolder.itemContent.setText(itemBean.content);76 viewHolder.itemDate.setText("yyyy-MM-dd");77 viewHolder.itemChecked.setChecked(itemBean.check);78 79 return ret;80 }81 82 private static class ViewHolder {83 private ImageView itemIcon;84 private TextView itemTitle;85 private TextView itemContent;86 private TextView itemDate;87 private CheckBox itemChecked;88 }89 }
ItemBeanAdapter
1 package com.aellenlei.baseadapterdemo; 2  3 /** 4  * User AellenLei 5  * NAME ItemBean 6  * DATE 2016/3/7 7  */ 8 public class ItemBean { 9     public int postion;10     public String url;11     public String title;12     public String content;13     public String date;14     public boolean check;15 }
ItemBean
1 
2
11 12
16
activity_main.xml
1 
2
6 7
13 14
22
30 31
38
47
item.xml

 由于该Demo比较简单,不需多讲相信都可以看懂。

 ItemBeanAdapter.java的getView方法中有这么一句:

  

  分别打印的是ListView中每一个Item在ListView中的位置(默认从0开始,下同),该Item显示的数据源中指定位置数据的poistion和title,convertView是否为空若不为空打印convertView之前显示的title.

 当数据源中的数据条数为5时,Logcat的日志:

  

  UI:

  

 

 当数据源中的数据条数为10是,Logcat的日志:

  

  UI:

  

  

  根据这两种情况的测试,可以大概回答第一个问题:

Q1.ListView中每个Item的创建

A1.Adapter第一次创建的Items的数量是由手机屏幕的大小(可测试)和数据源数据的条数来决定的,也就是屏幕实际显示多少个Item就创建几个item的,不多创建新的item也不少创建新的item,items数量是屏幕实际显示数目的取整。将下面的完整结合来看,第一次创建的Item是最基本的Item,它的数量是确定的,以后新的item无论是向上滑动出现还是向下滑动出现都是复用第一次创建的items中的某个item。

 

Q2.ListView中Item的复用

A2:最核心的代码就是Adapter中的getView方法,它返回的是一个已经绑定好数据的view,而系统仅仅只是将这个view在屏幕的指定位置绘制出来。

  

  代码不是固定死的,当然你可以有自己的写法,但是原理总是相同的:

    A2:当ListView第一次创建一屏幕的items时,covertView始终为null(代码测试很容易得出),所以当covertView为空时,就需要将第一次创建一屏幕的items的每个item“初始化”,这里的“初始化”是将covertView和ViewHolder绑定起来,注意不论是将covertView和ViewHolder绑定起来还是ret和ViewHolder绑定起来,它们的本质是一样的,最后返回值是已经与ViewHolder绑定的View视图,当掌握了covertView的复用写法,可以说是基本上item的复用的写法也掌握了。

 

    注意下面一种情况,当ListView向上滑动,且item0完全不见,item7和item8出现(下图item8已经出现,只是没有完全显示)的情况:

    

    此时Logcat打印的日志:

      

    根据之前的第一次创建items打印的日志比较:item7仍然是新创建的,但是item8却是复用的,item8复用的是item0(完全根据日志得出的)。(PS 可能此处有疑问,下面会分析)

    A2:当listView向上滑动或者是向下滑动的时候,此时可能会出现item复用的情况(注意此时可能会出现复用的情况,不一定或出现哦)。若covertView不为空,就可以之前在该covertView初始化或复用中通过getTag方法,取出与之绑定的ViewHolder,从而实现减少findViewById的时间,findViewById是需要耗费时间的,当listView显示大量的数据,此时的findViewByid可以极大的提高效率。

 

    最后分析总结前面的,可以回答第三个问题:

Q3.ListView中屏幕显示的Item与复用生成Item之间的关系

A3:ListView实际创建item的数量是由手机屏幕的大小和数据源的数据数量来决定的,准确的将这是不准确的或是错误的。

   ListView在整个复用过程中本质上实际创建item的数量(这里所指的全部是最原始最本质的item)是由手机屏幕的大小、数据源的数据数量和每个item实际的大小来决定的(当然这里不考虑其他更为负责的情况,而是假定每个item的大小相同)。

   用可以唯一衡量确定的话说是:本质上items的数量是当第一个item完全消失后,此时Adapter总共创建的items数量,从本质上来说,这就是ListView在整个复用过程中复用的item的数量。假如从0,1,...,n-1(n为最原始的item数量)来看,当ListView向上滑动时,复用tem的顺序是按顺序复用0,1,...,n-1,每次复用一个;当ListView向下滑动时,复用的顺序是按照逆序的,从n-1,n-2,..,0,也是一个一个复用的。

  当然还有更为复杂的情况或者说从更为本质也就是源码的角度分析,这里暂不考虑,而是从一种最为表象或者最最最基本最最简单来分析ListView与Adapter。

 

 

转载于:https://www.cnblogs.com/enjoy-coding/p/5252452.html

你可能感兴趣的文章
Chrome: 完全移除对WoSign和StartCom证书的信任
查看>>
RecyclerView侧滑删除功能
查看>>
记一个hystrix异常
查看>>
9.02-Spring IOC 容器中Bean的生命周期
查看>>
6.6 tar打包
查看>>
微信自动抢红包的实现(Demo已增加查看TopActivity功能)
查看>>
Spring MVC核心技术
查看>>
TCP协议如何保证传输的可靠性
查看>>
Spring Cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
查看>>
建站心得之discuz门户程序相比ZBLOG具有哪些优势[图]
查看>>
编程之美 测试赛 石头剪刀布
查看>>
签名问题
查看>>
软件开发各阶段交付物列表
查看>>
2018-05-24 Linux学习
查看>>
ntp服务器的搭建
查看>>
我的友情链接
查看>>
sysstat 安装
查看>>
《你必须知道的.NET》 - 书摘精要
查看>>
六、nginx搭建织梦DedeCms网站
查看>>
Tair学习小记
查看>>