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

Posted blfbuaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析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结构体里面,事件处理也是一样,放在外面单独处理

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




以上是关于浅析android适配器adapter中的那些坑的主要内容,如果未能解决你的问题,请参考以下文章

android中Adapter有啥作用?常见的Adapter都有哪些?

android recyclerview的浅析。

设计模式-适配器模式(Adapter Pattern)

Android框架设计模式——Adapter Method

适配器模式(Adapter模式)

RecyclerView扩展(一)ViewPager2使用与原理浅析