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