打造Android中万能BaseAdapter

来源:互联网 发布:用c语言制作病毒 编辑:程序博客网 时间:2024/05/21 02:53

如题

作为一个懒人,在用了几次BaseAdapter加ViewHolder之后早已经厌倦了做同样的工作,仔细观察下我们的实现,其实有一些共处是一直有的,在BaseAdapter上再封装一次不就完事了,省了很多力气,直接上代码吧,原理其实很简单

说明:
1. 一些jar需要添加,如JSON的jar
2. MediaLoader很简单,随便写一个就行了
3. 一些后续的优化,如实现个滑动监听器,当停止滑动再加载啊,滑动就停止加载啊(注意AsyncTask的cancel()方法,不会立即停止线程的,实现原理也是线程池,也可以自己写一个玩玩,对线程的停止方法,有另一篇介绍),也可以对内容进行缓存,看自己需求吧

1。通用的ViewHolder

package util;import android.content.Context;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;public class ViewHolder{    private final SparseArray<View> mViews;    private int mPosition;    private View mConvertView;    private int myLayoutId;    private ViewHolder(Context context, ViewGroup parent, int layoutId,                       int position)    {        this.mPosition = position;        this.mViews = new SparseArray<View>();        this.myLayoutId = layoutId;        //System.out.println("position is "+mPosition+"  初始化时的layoutID is"+myLayoutId);        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,                false);        // setTag        mConvertView.setTag(this);        //System.out.println(position+"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");    }    public int getMyLayoutId(){        //System.out.println("position is "+mPosition+"   getLayoutId时的layoutID is"+myLayoutId);        return this.myLayoutId;    }    public int getmPosition() {        return mPosition;    }    public static ViewHolder get(Context context, View convertView,                                 ViewGroup parent, int layoutId, int position)    {        //System.out.println("position is "+position+"   getViewHolder时传入的layoutID is"+layoutId);        if (convertView == null || position != ((ViewHolder) convertView.getTag()).getmPosition()) {            //System.out.println("new ViewHolder 之前 position is "+position+"   getViewHolder时的layoutID is"+layoutId);            return new ViewHolder(context, parent, layoutId, position);        }        //System.out.println("不用new的时候getViewHolder  position is "+position+"   getViewHolder时的layoutID is"+layoutId);        return (ViewHolder) convertView.getTag();    }    public View getConvertView()    {        return mConvertView;    }    public <T extends View> T getView(int viewId)    {        View view = mViews.get(viewId);        if (view == null)        {            view = mConvertView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T) view;    }}

2.通用的Adapter

package util;import android.content.Context;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.BaseAdapter;import java.util.List;/** * Created by Coder on 2017/1/1. */public abstract class CommonAdapter<T> extends BaseAdapter implements AbsListView.OnScrollListener{    protected LayoutInflater mInflater;    protected Context mContext;    protected List<T> beanList;    protected SparseArray<Integer> mItemLayoutIds;    public CommonAdapter(Context context, List<T> beanList, SparseArray<Integer> mItemLayoutIds)    {        this.mContext = context;        this.mInflater = LayoutInflater.from(mContext);        this.beanList = beanList;        this.mItemLayoutIds = mItemLayoutIds;    }    public Context getContext(){        return mContext;    }    @Override    public int getCount()    {        return beanList.size();    }    @Override    public T getItem(int position)    {        return beanList.get(position);    }    @Override    public long getItemId(int position)    {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent)    {        ViewHolder viewHolder = getViewHolder(position, convertView,                parent);        convert(viewHolder, getItem(position));        return viewHolder.getConvertView();    }    public abstract void convert(ViewHolder holder, T t);    private ViewHolder getViewHolder(int position, View convertView, ViewGroup parent)    {        //System.out.println("position is "+position+"  传入的 layoutid is"+mItemLayoutIds.get(position));        return ViewHolder.get(mContext, convertView, parent, mItemLayoutIds.get(position),                position);    }}

3.使用示例
先搞个activity

package zzu.com.news;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.ListView;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.List;import Adapter.NewsAdapter;import Adapter.TestAdapter;import bean.News;import util.DataHandler;import util.MyAsyncTask;public class NewsActivity extends Activity {    private Context context;    private ListView listVIew;    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.test_adapter);        context = this;        listVIew = (ListView)findViewById(R.id.lv_main);        new MyAsyncTask(context, listVIew).execute("http://192.168.1.107:8080/news/ShowNewsService?currentPage=5","newsList");    }}

再把要显示的JSON数据从服务器获取下来,把数据和布局文件打包链表扔进NewsAdapter里,NewsAdapter是根据CommonAdapter重写的,下面有代码

package util;/** * Created by Coder on 2017/1/5. */import android.content.Context;import android.os.AsyncTask;import android.util.SparseArray;import android.widget.BaseAdapter;import android.widget.ListView;import com.google.gson.Gson;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.List;import Adapter.NewsAdapter;import Adapter.TestAdapter;import bean.ShowNewsBean;import zzu.com.news.R;/** * Created by Coder on 2017/1/5. */public class MyAsyncTask extends AsyncTask<String, Void, JSONArray> {    private Context context;    private ListView view;    public MyAsyncTask(Context context, ListView view){        this.context = context;        this.view = view;    }    @Override    protected JSONArray doInBackground(String... params) {        return DataHandler.getJsonArray(params[0], params[1]);    }    @Override    protected void onPostExecute(JSONArray jsonArray) {        super.onPostExecute(jsonArray);        SparseArray<Integer> mItemLayoutIds = new SparseArray<Integer>();        List<ShowNewsBean> newsList = new ArrayList<>();        try {            JSONObject jsonObject = null;            for(int i=0; i<jsonArray.length(); i++){                jsonObject = jsonArray.getJSONObject(i);                System.out.println(jsonObject.toString());                //对JSON-》Bean                Gson gson = new Gson();                ShowNewsBean news = gson.fromJson(jsonObject.toString(), ShowNewsBean.class);                System.out.println(news.toString());                newsList.add(news);                //将布局传入                if(news.getNewsType() == 1){                   mItemLayoutIds.put(i, R.layout.listview_demo3);                }else if(news.getNewsType() == 2){                   mItemLayoutIds.put(i, R.layout.listview_demo2);                }else if(news.getNewsType() == 3){                     mItemLayoutIds.put(i, R.layout.listview_demo);                }else{                   mItemLayoutIds.put(i, R.layout.video_item_layout);                }            }        } catch (JSONException e) {            e.printStackTrace();        }        NewsAdapter myAdapter = new NewsAdapter(context, newsList, mItemLayoutIds);        view.setAdapter(myAdapter);    }}

最后重写下CommonAdapter就行了

package Adapter;import android.content.Context;import android.os.Handler;import android.os.Message;import android.util.Log;import android.util.SparseArray;import android.view.View;import android.widget.AbsListView;import android.widget.Button;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.MediaController;import android.widget.TextView;import android.widget.VideoView;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.List;import java.util.Map;import bean.Media;import bean.ShowNewsBean;import util.CommonAdapter;import util.ImageLoader;import util.MediaLoader;import util.VideoLoader;import util.ViewHolder;import zzu.com.news.R;import com.google.gson.Gson;/** * Created by Coder on 2017/1/5. */public class NewsAdapter extends CommonAdapter<Object> {    private MediaLoader mediaLoader;    protected List beanList;    protected List<Object> taskList;    public NewsAdapter(Context context, List beanList, SparseArray<Integer> mItemLayoutIds) {        super(context, beanList, mItemLayoutIds);        this.beanList = beanList;        taskList = new ArrayList<>();        mediaLoader = new MediaLoader();    }    @Override    public void convert(ViewHolder holder, Object object) {        final ShowNewsBean news = (ShowNewsBean)object;        //把bean中的数据塞到view中        if(news.getNewsType() == 1){            ((TextView) holder.getView(R.id.thirdtitle)).setText(news.getTitle());            System.out.println("1");        }else if(news.getNewsType() == 2){            System.out.println(" getMyLayoutId is ="+holder.getMyLayoutId()+" R.layout.listview_demo2 is "+R.layout.listview_demo2+" ~!!!!!!!!!!!!!!");            ((TextView) holder.getView(R.id.nexttitle)).setText(news.getTitle());            List<Media> mediaList = news.getMediaList();            ImageView imageView = holder.getView(R.id.nextpicture);            //设置url作为tag防止重复加载            imageView.setTag(mediaList.get(0).getMediaUrl());            System.out.println("url is "+mediaList.get(0).getMediaUrl());            //imageLoader.showImageByAnsycTask(imageView, mediaList.get(0).getMediaUrl());            mediaLoader.show(imageView, mediaList.get(0).getMediaUrl());        }else if(news.getNewsType() == 3){            //设置url作为tag防止重复加载            ((TextView) holder.getView(R.id.title)).setText(news.getTitle());            List<Media> mediaList = news.getMediaList();            ImageView imageView = holder.getView(R.id.picture1);            imageView.setTag(mediaList.get(0).getMediaUrl());            mediaLoader.show(imageView, mediaList.get(0).getMediaUrl());            imageView = holder.getView(R.id.picture2);            imageView.setTag(mediaList.get(1).getMediaUrl());            mediaLoader.show(imageView, mediaList.get(1).getMediaUrl());            imageView = holder.getView(R.id.picture3);            imageView.setTag(mediaList.get(2).getMediaUrl());            mediaLoader.show(imageView, mediaList.get(2).getMediaUrl());        }else{            ((TextView)holder.getView(R.id.video_name_text)).setText(news.getTitle());            final Context context = getContext();            final VideoView videoView = holder.getView(R.id.videoview);            final ImageButton play = holder.getView(R.id.video_play_btn);            play.setOnClickListener(new View.OnClickListener() {                private boolean flag = false;                @Override                public void onClick(View v) {                    if(flag == false){                        play.setVisibility(ImageButton.INVISIBLE);                        System.out.println(news.getMediaList().get(0).getMediaUrl()+"!!!!!!!!!!!!!!!");                        MediaLoader mediaLoader = new MediaLoader();                        mediaLoader.show(videoView, news.getMediaList().get(0).getMediaUrl());                        MediaController myController = new MediaController(context);                        videoView.setVisibility(View.VISIBLE);                        myController.setAnchorView(videoView);                        myController.setMediaPlayer(videoView);                        videoView.setMediaController(myController);                        videoView.requestFocus();                        flag = true;                    }else{                        videoView.pause();                        flag = false;                    }                }            });        }    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {//        start = firstVisibleItem;//        end = firstVisibleItem + visibleItemCount;        Log.i("TAG", "firstVisibleItem "+firstVisibleItem);        Log.i("TAG", "visibleItemCount "+visibleItemCount);        Log.i("TAG", "totalItemCount "+totalItemCount);    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        if(scrollState == SCROLL_STATE_IDLE){            //停止滑动 开始加载        }else{            //正在滑动 停止加载        }    }}
0 0
原创粉丝点击