浅析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 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 mLruCache = new LruCache(
            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 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零散知识学习)