打造Android中万能BaseAdapter

如题

作为一个懒人,在用了几次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{
            //正在滑动 停止加载

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值