添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

上面就是Adapter以及继承结构图了,接着我们介绍一下实际开发中还用到的几个Adapter吧!

  • BaseAdapter :抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter!
  • ArrayAdapter :支持泛型操作,最简单的一个Adapter,只能展现一行文字~
  • SimpleAdapter :同样具有良好扩展性的一个Adapter,可以自定义多种效果!
  • SimpleCursorAdapter :用于显示简单文本类型的listView,一般在数据库那里会用到,不过有点过时, 不推荐使用!

其实一个BaseAdapter就够玩的了,至于其他的,实际开发中用得不多

二、ListView

自定义BaseAdapter,然后绑定ListView的最简单例子

先看看我们要实现的效果图:

关键代码:

Animal.java :

public class Animal {
    private String aName;
    private String aSpeak;
    private int aIcon;
    public Animal() {
    public Animal(String aName, String aSpeak, int aIcon) {
        this.aName = aName;
        this.aSpeak = aSpeak;
        this.aIcon = aIcon;
    public String getaName() {
        return aName;
    public String getaSpeak() {
        return aSpeak;
    public int getaIcon() {
        return aIcon;
    public void setaName(String aName) {
        this.aName = aName;
    public void setaSpeak(String aSpeak) {
        this.aSpeak = aSpeak;
    public void setaIcon(int aIcon) {
        this.aIcon = aIcon;
 

AnimalAdapter.java:自定义的BaseAdapter:

public class AnimalAdapter extends BaseAdapter {
    private LinkedList<Animal> mData;
    private Context mContext;
    public AnimalAdapter(LinkedList<Animal> mData, Context mContext) {
        this.mData = mData;
        this.mContext = mContext;
    @Override
    public int getCount() {
        return mData.size();
    @Override
    public Object getItem(int position) {
        return null;
    @Override
    public long getItemId(int position) {
        return position;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
        ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
        TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
        TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
        img_icon.setBackgroundResource(mData.get(position).getaIcon());
        txt_aName.setText(mData.get(position).getaName());
        txt_aSpeak.setText(mData.get(position).getaSpeak());
        return convertView;
 

最后是MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private List<Animal> mData = null;
    private Context mContext;
    private AnimalAdapter mAdapter = null;
    private ListView list_animal;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        list_animal = (ListView) findViewById(R.id.list_animal);
        mData = new LinkedList<Animal>();
        mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
        mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
        mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
        mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
        mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
        mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
        list_animal.setAdapter(mAdapter);
 

自定义BaseAdapter以及完成数据绑定就是这么简单~

我们从代码 中可以看出比较重要的两个方法:getCount()和getView(),界面上有多少列就会调用多少次getView, 这个时候可能看出一些端倪,每次都是新inflate一个View,都要进行这个XML的解析,这样会 很浪费资源,当然,几十列或者几百列的列表并不能体现什么问题,但假如更多或者布局更加复杂? 所以学习ListView的优化很重要,而本节针对的是BaseAdapter的优化,优化的两点有,复用convertView 以及使用ViewHolder重用组件,不用每次都findViewById。

上面也说了,界面上有多少个Item,那么getView方法就会被调用多少次! 我们来看看上一节我们写的getView()部分的代码:

<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
    convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
    ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
    TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
    TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
    img_icon.setBackgroundResource(mData.get(position).getaIcon());
    txt_aName.setText(mData.get(position).getaName());
    txt_aSpeak.setText(mData.get(position).getaSpeak());
    return convertView;
}</span>

是吧,inflate()每次都要加载一次xml,其实这个convertView是系统提供给我们的可供服用的View 的缓存对象,那就坐下判断咯,修改下,优化后的代码:

<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null){
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
    ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
    TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
    TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
    img_icon.setBackgroundResource(mData.get(position).getaIcon());
    txt_aName.setText(mData.get(position).getaName());
    txt_aSpeak.setText(mData.get(position).getaSpeak());
    return convertView;
}</span>

2.ViewHolder重用组件

嘿嘿,getView()会被调用多次,那么findViewById不一样得调用多次,而我们的ListView的Item 一般都是一样的布局,我们可以对这里在优化下,我们可以自己定义一个ViewHolder类来对这一部分 进行性能优化!修改后的代码如下:

<span style="font-size:14px;">@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    if(convertView == null){
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
        holder = new ViewHolder();
        holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
        holder.txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
        holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
        convertView.setTag(holder);   //将Holder存储到convertView中
    }else{
        holder = (ViewHolder) convertView.getTag();
    holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
    holder.txt_aName.setText(mData.get(position).getaName());
    holder.txt_aSpeak.setText(mData.get(position).getaSpeak());
    return convertView;
static class ViewHolder{
    ImageView img_icon;
    TextView txt_aName;
    TextView txt_aSpeak;
}</span>

3.分批加载,滑动的时候不加载图片

上面的两个例子中ListView都是显示的本地的List集合中的内容,List的长度也只有100个,我们可以毫不费力一次性加载完这100个数据;但是实际应用中,我们往往会需要使用Listview来显示网络上的内容,比如说我们拿使用ListView显示新闻为例:

其一:假如网络情况很好,我们使用的手机也许能够一下子加载完所有新闻数据,然后显示在ListView中,用户可能感觉还好,假如说在网络不太顺畅的情况下,用户加载完所有网络的数据,可能这个list是1000条新闻,那么用户可能需要面对一个空白的Activity好几分钟,这个显然是不合适的

其二:我们知道Android虚拟机给每个应用分配的运行时内存是一定的,一般性能不太好的机器只有16M,好一点的可能也就是64M的样子,假如说我们现在要浏览的新闻总数为一万条,即便是网络很好的情况下,我们可以很快的加载完毕,但是多数情况下也会出现内存溢出从而导致应用崩溃的情况。

那么为了解决上面的两个问题,我们需要进行分批加载,比如说1000条新闻的List集合,我们一次加载20条,等到用户翻页到底部的时候,我们再添加下面的20条到List中,再使用Adapter刷新ListView,这样用户一次只需要等待20条数据的传输时间,不需要一次等待好几分钟把数据都加载完再在ListView上显示。其次这样也可以缓解很多条新闻一次加载进行产生OOM应用崩溃的情况。

实际上,分批加载也不能完全解决问题,因为虽然我们在分批中一次只增加20条数据到List集合中,然后再刷新到ListView中去,假如有10万条数据,如果我们顺利读到最后这个List集合中还是会累积海量条数的数据,还是可能会造成OOM的情况,这时候我们就需要用到分页,比如说我们将这10万条数据分为1000页,每一页100条数据,每一页加载时都覆盖掉上一页中List集合中的内容,然后每一页内再使用分批加载,这样用户的体验就会相对好一些。

一、Adapter首先我们来看看他的继承结构图:上面就是Adapter以及继承结构图了,接着我们介绍一下实际开发中还用到的几个Adapter吧!BaseAdapter:抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter!ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~SimpleAdapter:
ArrayAdapter<T> 适合非常简单的数据显示,很方便,很简单。 SimpleAdapter 可以自定义Item布局,用于显示交简单的布局及控件,但布局内的控件如按钮等无法获取到焦点,当然也就无法获取到他们的点击事件。 SimpleCursorAdapter 与SimpleAdapter相似,只是他的数据源是Cursor类型而已。 BaseAdpter子类 最常用的ListView数据适配器,通过继承BaseAdpter可以较灵活的实现数据的绑定,同时通过使用View
AndroidListView(列表视图)和Adapter(是配器)实例 Android中有些控件或者View需要用Adapter(适配器)来显示到具体的activity;Adapter是用来帮助填充数据的中间桥梁,另外Adapter需要结合ListView,GridView来使用。这里我们以ListView作为示范。 Adapter作为所有适配器类的父类,下面我就找两个我比较常用的Adapter子类介绍一下吧。 1、 ArrayAdapter 这是最简单的一种Adapter,支持泛型操作,只能展现一行文
android ListView组件使用实在是太频繁了,因此特意制作了Android ListView的详细使用教程,还有和listview配套使用的BaseAdapter以及ArrayAdapter都会在文章后面有讲到,非常的实用。 为了便于理解下面listview的使用方法,我想先让你看下本人的android项目的目录结构是很有必要的,如图。 案例一:首先我们用ListView
ListViewAdapter优化在安卓开发中ListView的使用频率可谓非常之高,差不多所有的数组,集合类的数据展示都会使用到ListView,对于现在的大数据时代,展示的数据很庞大,所以对Adapter优化显得尤为重要简介有这么一句话,“世上本没有所谓的优化,只有时空变化” 时间换空间 时间换时间 空间换时间 控件换空间 在我们的算法中就经常遇见这种情况,如果降低算法的时间复杂度,那势必会
PS:listview中有一些简单使用的适配器,如:SimpleAdapter:构造方法SimpleAdapter(Context context,List data,reString [] from,int [] to),但这种适配器过于单调,往往不能达到用户想要的效果,想要随心所欲,就用到了BaseAdapter,自定义适配器。 1、首先写布局文件 activity_layout.xml <?xml version=1.0 encoding=utf-8?> <LinearLayout xmlns:android=http://sch
v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v; [/code] 从上面的源码可以看到,在执行 CAS 之前先获取 offset 位置的值 多线程死锁的产生以及如何避免死锁 Jaf932074323: 感觉上,保证加锁顺序是最好的,如果难以判断顺序的话,说明程序逻辑有问题。 延时退出的话,第一感不太好。有些锁是调用方加锁的,被调用的函数无法控制,如何释放所有锁就太麻烦了。 死锁检测的话,适合记录成日志,让程序员去调试bug。 Java中CAS详解 qq_34251598: https://www.iteye.com/blog/zl198751-1848575