浅析android适配器adapter中的那些坑

做项目中遇到的,折磨了我将近两天,今天把经验分享出来。让大家以后少走点弯路,好了。简单来说一下什么是android的适配器,怎样定义。怎样添加适配器的重用性。怎样去减少程序的耦合性

适配器顾名思义是用来做适配的,可是他是怎样做适配的。机制是什么。作用是什么,好,相信写java的都是知道什么是面向对象编程吧,这里用面向对象来解释非常好理解。事实上适配器是把每一个对象放在其空间上然后在andorid页面显示,如今再来理解,对象事实上就是数据的抽象体吧,而页面显示通常是xml也就是视图吧,那么数据以视图的形式来显示,那么这就是adapter起的作用,并且他能够让其依照对应的顺序显示,能够依据对应的操作来进行数据或者页面的操作,那么来看一下我的适配器,上代码

这个是bean实体

package com.example.fanyafeng.laugh.bean;

import com.example.fanyafeng.laugh.util.S;

/**
 * Created by fanyafeng on 2015/6/30.
 */
public class IndexListViewBean extends BaseBean {
    private String Title;
    private String LeftTopImg;
    private String LeftTopTitle;
    private String LeftTopTimes;
    private String LeftTopUrl;
    private String RightTopImg;
    private String RightTopTitle;
    private String RightTopTimes;
    private String RightTopUrl;
    private String LeftBottomImg;
    private String LeftBottomTitle;
    private String LeftBottomTimes;
    private String LeftBottonUrl;
    private String RightBottomImg;
    private String RightBottomTitle;
    private String RightBottomTimes;
    private String RightBottonUrl;

    public IndexListViewBean(String title, String leftTopImg, String leftTopTitle, String leftTopTimes, String leftTopUrl, String rightTopImg, String rightTopTitle, String rightTopTimes, String rightTopUrl, String leftBottomImg, String leftBottomTitle, String leftBottomTimes, String leftBottonUrl, String rightBottomImg, String rightBottomTitle, String rightBottomTimes, String rightBottonUrl) {
        Title = title;
        LeftTopImg = leftTopImg;
        LeftTopTitle = leftTopTitle;
        LeftTopTimes = leftTopTimes;
        LeftTopUrl = leftTopUrl;
        RightTopImg = rightTopImg;
        RightTopTitle = rightTopTitle;
        RightTopTimes = rightTopTimes;
        RightTopUrl = rightTopUrl;
        LeftBottomImg = leftBottomImg;
        LeftBottomTitle = leftBottomTitle;
        LeftBottomTimes = leftBottomTimes;
        LeftBottonUrl = leftBottonUrl;
        RightBottomImg = rightBottomImg;
        RightBottomTitle = rightBottomTitle;
        RightBottomTimes = rightBottomTimes;
        RightBottonUrl = rightBottonUrl;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getLeftTopImg() {
        return LeftTopImg;
    }

    public void setLeftTopImg(String leftTopImg) {
        LeftTopImg = leftTopImg;
    }

    public String getLeftTopTitle() {
        return LeftTopTitle;
    }

    public void setLeftTopTitle(String leftTopTitle) {
        LeftTopTitle = leftTopTitle;
    }

    public String getLeftTopTimes() {
        return LeftTopTimes;
    }

    public void setLeftTopTimes(String leftTopTimes) {
        LeftTopTimes = leftTopTimes;
    }

    public String getLeftTopUrl() {
        return LeftTopUrl;
    }

    public void setLeftTopUrl(String leftTopUrl) {
        LeftTopUrl = leftTopUrl;
    }

    public String getRightTopImg() {
        return RightTopImg;
    }

    public void setRightTopImg(String rightTopImg) {
        RightTopImg = rightTopImg;
    }

    public String getRightTopTitle() {
        return RightTopTitle;
    }

    public void setRightTopTitle(String rightTopTitle) {
        RightTopTitle = rightTopTitle;
    }

    public String getRightTopTimes() {
        return RightTopTimes;
    }

    public void setRightTopTimes(String rightTopTimes) {
        RightTopTimes = rightTopTimes;
    }

    public String getRightTopUrl() {
        return RightTopUrl;
    }

    public void setRightTopUrl(String rightTopUrl) {
        RightTopUrl = rightTopUrl;
    }

    public String getLeftBottomImg() {
        return LeftBottomImg;
    }

    public void setLeftBottomImg(String leftBottomImg) {
        LeftBottomImg = leftBottomImg;
    }

    public String getLeftBottomTitle() {
        return LeftBottomTitle;
    }

    public void setLeftBottomTitle(String leftBottomTitle) {
        LeftBottomTitle = leftBottomTitle;
    }

    public String getLeftBottomTimes() {
        return LeftBottomTimes;
    }

    public void setLeftBottomTimes(String leftBottomTimes) {
        LeftBottomTimes = leftBottomTimes;
    }

    public String getLeftBottonUrl() {
        return LeftBottonUrl;
    }

    public void setLeftBottonUrl(String leftBottonUrl) {
        LeftBottonUrl = leftBottonUrl;
    }

    public String getRightBottomImg() {
        return RightBottomImg;
    }

    public void setRightBottomImg(String rightBottomImg) {
        RightBottomImg = rightBottomImg;
    }

    public String getRightBottomTitle() {
        return RightBottomTitle;
    }

    public void setRightBottomTitle(String rightBottomTitle) {
        RightBottomTitle = rightBottomTitle;
    }

    public String getRightBottomTimes() {
        return RightBottomTimes;
    }

    public void setRightBottomTimes(String rightBottomTimes) {
        RightBottomTimes = rightBottomTimes;
    }

    public String getRightBottonUrl() {
        return RightBottonUrl;
    }

    public void setRightBottonUrl(String rightBottonUrl) {
        RightBottonUrl = rightBottonUrl;
    }

    @Override
    public String toString() {
        return "IndexListViewBean{" +
                "Title='" + Title + '\'' +
                ", LeftTopImg='" + LeftTopImg + '\'' +
                ", LeftTopTitle='" + LeftTopTitle + '\'' +
                ", LeftTopTimes='" + LeftTopTimes + '\'' +
                ", LeftTopUrl='" + LeftTopUrl + '\'' +
                ", RightTopImg='" + RightTopImg + '\'' +
                ", RightTopTitle='" + RightTopTitle + '\'' +
                ", RightTopTimes='" + RightTopTimes + '\'' +
                ", RightTopUrl='" + RightTopUrl + '\'' +
                ", LeftBottomImg='" + LeftBottomImg + '\'' +
                ", LeftBottomTitle='" + LeftBottomTitle + '\'' +
                ", LeftBottomTimes='" + LeftBottomTimes + '\'' +
                ", LeftBottonUrl='" + LeftBottonUrl + '\'' +
                ", RightBottomImg='" + RightBottomImg + '\'' +
                ", RightBottomTitle='" + RightBottomTitle + '\'' +
                ", RightBottomTimes='" + RightBottomTimes + '\'' +
                ", RightBottonUrl='" + RightBottonUrl + '\'' +
                '}';
    }
}

这个是适配器

package com.example.fanyafeng.laugh.adapter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v4.util.LruCache;
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.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.fanyafeng.laugh.R;
import com.example.fanyafeng.laugh.activity.VideoDisplayActivity;
import com.example.fanyafeng.laugh.activity.VideoListActivity;
import com.example.fanyafeng.laugh.activity.VideoViewPlayingActivity;
import com.example.fanyafeng.laugh.bean.IndexListViewBean;
import com.example.fanyafeng.laugh.bean.IndexUrlBean;
import com.example.fanyafeng.laugh.util.ImageLoaderCache;
import com.example.fanyafeng.laugh.util.L;
import com.example.fanyafeng.laugh.util.ListViewImageTaskUtil;
import com.example.fanyafeng.laugh.util.StringTools;
import com.example.fanyafeng.laugh.util.SyncImageLoader;

import java.util.List;

/**
 * Created by fanyafeng on 2015/7/1.
 */
public class IndexListViewAdapter extends BaseAdapter {

    private Context context;
    private List<IndexListViewBean> indexListViewBeans;
    private ListView listView;

    //缓存到本地sd卡,并且能够更新ListView图片
    private ImageLoaderCache mImageLoader;

    // 获取当前应用程序所分配的最大内存
    private final int maxMemory = (int) Runtime.getRuntime().maxMemory();
    // 只用五分之中的一个用来做图片缓存
    private final int cacheSize = maxMemory / 5;

    private LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(
            cacheSize) {

        // 重写sizeof()方法
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // TODO Auto-generated method stub
            // 这里用多少kb来计算
            return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
        }

    };

    public IndexListViewAdapter(Context context, List<IndexListViewBean> indexListViewBeans) {
        this.context = context;
        this.indexListViewBeans = indexListViewBeans;
        mImageLoader = new ImageLoaderCache(context);
    }

    public ImageLoaderCache getImagerLoader() {
        return mImageLoader;
    }

    public void update() {
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return indexListViewBeans.size();
    }

    @Override
    public Object getItem(int position) {
        return indexListViewBeans.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        View view = convertView;
        ViewHolder holder = null;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.item_fragment_homepage, null);
            holder = new ViewHolder();
            view.setTag(holder);
            holder.Title = (TextView) view.findViewById(R.id.index_title);
            holder.LeftTopImg = (ImageView) view.findViewById(R.id.index_left_up_iv);
            holder.LeftTopTitle = (TextView) view.findViewById(R.id.index_left_up_tv);
            holder.LeftTopTimes = (TextView) view.findViewById(R.id.index_left_up_time);
            holder.RightTopImg = (ImageView) view.findViewById(R.id.index_right_up_iv);
            holder.RightTopTitle = (TextView) view.findViewById(R.id.index_right_up_tv);
            holder.RightTopTimes = (TextView) view.findViewById(R.id.index_right_up_time);
            holder.LeftBottomImg = (ImageView) view.findViewById(R.id.index_left_down_iv);
            holder.LeftBottomTitle = (TextView) view.findViewById(R.id.index_left_down_tv);
            holder.LeftBottomTimes = (TextView) view.findViewById(R.id.index_left_down_time);
            holder.RightBottomImg = (ImageView) view.findViewById(R.id.index_right_down_iv);
            holder.RightBottomTitle = (TextView) view.findViewById(R.id.index_right_down_tv);
            holder.RightBottomTimes = (TextView) view.findViewById(R.id.index_right_down_time);

        } else {
            holder = (ViewHolder) view.getTag();
        }

        holder.LeftTopImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setClass(context, VideoViewPlayingActivity.class);
                intent.putExtra("url_info", indexListViewBeans.get(position).getLeftTopUrl());
                L.d("leftTopUrl", indexListViewBeans.get(position).getLeftTopUrl());
                L.d("点击获取的位置", position);
                context.startActivity(intent);
            }
        });
        holder.RightTopImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setClass(context, VideoViewPlayingActivity.class);
                intent.putExtra("url_info", indexListViewBeans.get(position).getRightTopUrl());
                context.startActivity(intent);
            }
        });
        holder.LeftBottomImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setClass(context, VideoViewPlayingActivity.class);
                intent.putExtra("url_info", indexListViewBeans.get(position).getLeftBottonUrl());
                context.startActivity(intent);
            }
        });
        holder.RightBottomImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_CALL);
                intent.setClass(context, VideoViewPlayingActivity.class);
                intent.putExtra("url_info", indexListViewBeans.get(position).getRightBottonUrl());
                context.startActivity(intent);
            }
        });
        holder.Title.setText(indexListViewBeans.get(position).getTitle());
        holder.LeftTopTitle.setText(indexListViewBeans.get(position).getLeftTopTitle());
        holder.LeftTopTimes.setText(indexListViewBeans.get(position).getLeftTopTimes());
        holder.RightTopTitle.setText(indexListViewBeans.get(position).getRightTopTitle());
        holder.RightTopTimes.setText(indexListViewBeans.get(position).getRightTopTimes());
        holder.LeftBottomTitle.setText(indexListViewBeans.get(position).getLeftBottomTitle());
        holder.LeftBottomTimes.setText(indexListViewBeans.get(position).getLeftBottomTimes());
        holder.RightBottomTitle.setText(indexListViewBeans.get(position).getRightBottomTitle());
        holder.RightBottomTimes.setText(indexListViewBeans.get(position).getRightBottomTimes());
        loadBitmap(indexListViewBeans.get(position).getLeftTopImg(), holder.LeftTopImg);
        loadBitmap(indexListViewBeans.get(position).getRightTopImg(), holder.RightTopImg);
        loadBitmap(indexListViewBeans.get(position).getLeftBottomImg(), holder.LeftBottomImg);
        loadBitmap(indexListViewBeans.get(position).getRightBottomImg(), holder.RightBottomImg);

        return view;
    }

    private void loadBitmap(String urlStr, ImageView image) {

        ListViewImageTaskUtil asyncLoader = new ListViewImageTaskUtil(image, mLruCache);// 一个异步图片载入对象
        Bitmap bitmap = asyncLoader.getBitmapFromMemoryCache(urlStr);// 首先从内存缓存中获取图片
        if (bitmap != null) {
            image.setImageBitmap(bitmap);// 假设缓存中存在这张图片则直接设置给ImageView
        } else {
            image.setImageResource(R.drawable.wait);// 否则先设置成默认的图片
            asyncLoader.execute(urlStr);// 然后运行异步任务AsycnTask 去网上载入图片
        }
    }

    static class ViewHolder {
        TextView Title;
        ImageView LeftTopImg;
        TextView LeftTopTitle;
        TextView LeftTopTimes;
        ImageView RightTopImg;
        TextView RightTopTitle;
        TextView RightTopTimes;
        ImageView LeftBottomImg;
        TextView LeftBottomTitle;
        TextView LeftBottomTimes;
        ImageView RightBottomImg;
        TextView RightBottomTitle;
        TextView RightBottomTimes;
    }
}

重点在实体的书写和适配器的书写,那么如今我实体的定义不不过用来去用数据来映射视图,另一个非常重要的是在对象上set数据,单个的item再去取,原来博主没有将每一个对象里面的四个链接相应的bean实体中,而是用的全局变量(把activity或者fragment和adapter写在一起,这样写不好。至于为什么我这里简单会所一下,详细的大家去体会,首先就是代码会非常乱,再有就是adapter的复用,还有就是全局变量多的话一个是不好维护一个是效率会低,剩下的真得自己去理解了)的list数据,想依据getview中的position去找相应的链接,可是通过抓position我发现,他不和onitemonclick(这里面的position是依次累加的。并且是唯一的)里的position一样。这里面我设置的是每次载入三个,然后上拉载入很多其它再载入三个。这种话,我打印出来的position是0到2的一直的死循环,这样问题就来了,得到的相应的链接肯定不正确。由于是依照getview的position来获取的,那么,咱再向深层次想一下。android的getview的机制是什么,为什么listview控件上的数据的相应关系并没有错,也没有乱,这个就涉及到面试官常常问的面试题了,有的会问listview怎样优化,看的一些资料说是settag。对。这是,并且是一般网络上的答案(可是这个我感觉回答优化不是非常好,是在adapter怎样进行处理事务,怎么去处理,这个方向才应该是对的)。可是这个settag恰恰是我们的问题所在,由于谷歌给的listview是假设这个view划出屏幕以后。那么谷歌会给你处理。这个存在的view假设再划回来。出如今屏幕上,那么这时候settag開始起作用了,换句话说就是if那。開始运行else了。

博主处理的时候刚開始用了一个全局的list,可是这样一个是不好,还有一个没有达到要的效果,然后博主又開始想还有一个方法就是java的面向对象里面设置bean,好,原来博主是在adapter又定义了全局的变量,在if else之外获取。可是onclickerlistener在if else之内,这种话,相当远博主上文说道的那个,运行那个的问题。这种话进行屏幕的滑动和刷新里面的全局的数据肯定会乱,一定会乱。这时候。再往深层次去挖,就到了上面说的那个了,就是要在绑定数据那里去进行事件的监听,并且去获取对应的数据,这种话就能够得到想要的效果。并且view的显示也都是这么做的。没有乱

这里说一下adapter是怎样将数据映射到xml,一般的话都是先去写一个holder。里面都是item的xml所须要的东西,然后再在这里面去找layout,然后再去找相应的id。然后再去和holder里面去相应(相应bean里面定义的。通常是须要进行页面显示的,而数据的后台操作是不用去相应相应的布局id), 还有这里着重强调一下adapter里面的一些坑

getview的position是固定的几个值,相对的,不要去当全局变量去使用

注意adapter开启一个activity等等

监听事件不要去写在ifelse结构体里面,事件处理也是一样,放在外面单独处理

注意耦合,否则代码会乱,依照道理说程序猿的逻辑思维应该是非常清晰的。总有一条思路可以让你去进行解耦。可是哪一条好。并且适合你的处理方式方法。这一点就须要程序猿的经验了,剩下的靠大家去体验了,这里仅仅是浅析

时间: 2024-10-05 02:50:16

浅析android适配器adapter中的那些坑的相关文章

Android 适配器(Adapter)、观察者(Observer) 模式

适配器(Adapter)详述:http://blog.csdn.net/jjwwmlp456/article/details/39893723 观察者(Observer)详述:http://blog.csdn.net/jjwwmlp456/article/details/39967021 AdapterView 体系 AdapterView中会使用Adapter Adapter 体系 BaseAdapter 实现了 SpinnerAdapter.ListAdapter 这样的形式,就是 适配器模

浅析Android 5.0中多媒体相关的新特性

本文来源于本人在所属公司内部分享的一次培训内容,由于100%是AOSP开源内容,所以应该可以分享出来给大家. Android L是在今年2014年6月的Google I/O开发者大会上正式推出的,其中包含了诸多改进,包括新的Material Design交互设计,卡片式风格的通知栏,对64位和ART的支持等等,本文则重点关注一些多媒体相关的新特性. 由于Android L发布的时间仅有半年,无论国内还是国外的相关资料比较匮乏,很多内容本人只能是在Android developer网站中对L版本的

Android ListView的适配器 Adapter 中GetView方法调用次数大于数据条数的问题

情况描述: 今天在写数据展示的时候,用了ListView,在它的适配器当中,发现getview方法执行的次数是数据条目的N倍(我这边显示的是4倍,这个倍数值不知道会不会变化),这显然是不科学的! 查阅资料,发现是ListView的布局问题.我把 android:layout_height="wrap_content"高度设置成了wrap_content.而wrap_content值使得ListView没有取到实际的高度,他还要根据计算才能确定,而每一次计算应该会触发listview的渲

android适配器Adapter

一.什么是适配器,适配器有什么用? 适配器是AdapterView视图(如ListView - 列表视图控件.Gallery - 缩略图浏览器控件.GridView - 网格控件.Spinner - 下拉列表控件.AutoCompleteTextView - 自动提示文本框.ExpandableListView - 支持展开/收缩功能的列表控件等)与数据之间的桥梁,用来处理数据并将数据绑定到AdapterView上.android提供多种适配器,开发时可以针对数据源的不同采用最方便的适配器,也可

浅析Android Camera开发中的三个尺寸和三种变形 (贡献一个自适配Picturesize和Previewsize的工具类)

转至 (http://blog.csdn.net/yanzi1225627/article/details/17652643) 经常听人问Camera开发中,各种变形问题,今天有空就在此梳理总结下. 三个尺寸: 1.Surfaceview的尺寸 Surfaceview是用来预览Camera的,当它全屏时就是Screen的大小. 2.Picturesize的尺寸 这是拍照后的PictureSize尺寸. 3.Previewsize的尺寸 这是预览时帧数据的尺寸. 三种变形: 1.预览画面的物体长宽

Android:Adapter中设置多种type的item的LayoutParams导致的convertView复用异常的问题

http://stackoverflow.com/questions/12018997/why-does-getview-return-wrong-convertview-objects-on-separatedlistadapter#comment35496677_12288051 The recycle bin technically stores the convert views based on the type that was initially read from getItem

Android中适配器Adapter的使用

安卓中最常使用的适配器Adapter有三种:1.ArrayAdapter 2.SimpleAdapter 3.BaseAdpter,此处我们用代码结合图文的方式理解.     首先需要在起始布局activity_main.xml文件中设置三个Button按钮,并分别设置点击事件,并与MainActivity相结合     一:ArrayAdapter:简单易用的Adapter,通常用于将数组或者List集合的多个值包装成多个列表项. 1.声明arrayadapter的第一步:创建activity

各司其职:在Android适配器中使用委托者模式

[这是一个线索]适配器君从不甘当线索,同样是设计模式,适配器模式不是今天的主题,今天的主题是在适配器中如何使用委托者模式以明确设计中的各元素的分工. 一个具有适配器View的界面,Activity作为MVC模式中的控制器,数据控制应当由它完成.那么,为了让Adapter只负责数据界面绑定,Activity负责控制数据的变动,委托者模式这个时候就应该勇敢地站出来,让Adapter中可能涉及到的控制委托给Activity去处理. 我又要举例子了,代码君憋不住了,它在下面↓↓↓↓↓↓ 1 packag

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr