ListView中getView中很冗余同时很多不好用的方法,我们需要复写BaseAdapter
-----他配合BaseHolder使用
-----该基类有为可以多提供一个item既Load_more
-----
暴露protected abstract BaseHolder<T> getItemHolder(int position);
让使用者根据postion使用不同的Item
------
/**
* 如果孩子有item的点击事件,复写此方法即可
*/
protected void onNoramlItemClick(AdapterView<?> parent, View view, int position, long id)
{
}
-----
使用--------------------------------------------------------------------------------
=
class HomeAdapter extends AppListAdapter
{
public HomeAdapter(AbsListView listView, List<AppInfoBean> datas) {
super(listView, datas);
// TODO Auto-generated constructor stub
}
@Override
protected List<AppInfoBean> onLoadMoreData() throws Exception
{
return loadMoreData(mDatas.size());
}
}
------------------------------------------------------------------------------------
======================================================
public class AppListAdapter extends SuperBaseAdapter<AppInfoBean> {
private List<AppInfoBean> mDatas;
public AppListAdapter(AbsListView listView, List<AppInfoBean> datas) {
super(listView, datas);
this.mDatas = datas;
}
@Override
protected BaseHolder<AppInfoBean> getItemHolder(int position) {
return new AppItemHolder();
}
/**
* adapter中每个 item的点击事件
*/
@Override
protected void onNoramlItemClick(AdapterView<?> parent, View view,
int position, long id) {
// 跳转到应用详情页面
Context context = UIUtils.getContext();
Intent intent = new Intent(context, AppDetailActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AppDetailActivity.KEY_PACKAGENAME,
mDatas.get(position).packageName);
context.startActivity(intent);
}
}
-----------------------------------------------------------------------------------
=====================================================
public class AppItemHolder extends BaseHolder<AppInfoBean>
{
// T ---> item 对应的数据
// private TextView tv1;
// private TextView tv2;
@ViewInject(R.id.item_appinfo_iv_icon)
private ImageView mIvIcon;
@ViewInject(R.id.item_appinfo_rb_stars)
private RatingBar mRbStar;
@ViewInject(R.id.item_appinfo_tv_des)
private TextView mTvDes;
@ViewInject(R.id.item_appinfo_tv_size)
private TextView mTvSize;
@ViewInject(R.id.item_appinfo_tv_title)
private TextView mTvTitle;
@Override
protected View initView()
{
View view = View.inflate(UIUtils.getContext(), R.layout.item_app_info, null);
// 初始化View
// tv1 = (TextView) view.findViewById(R.id.tmp_tv_1);
// tv2 = (TextView) view.findViewById(R.id.tmp_tv_2);
// 注入
ViewUtils.inject(this, view);
return view;
}
@Override
protected void refreshUI(AppInfoBean data)
{
// 给View设置数据
// tv1.setText("头-" + data);
// tv2.setText("内容-" + data);
// 给View设置数据
mTvDes.setText(data.des);
mTvSize.setText(StringUtils.formatFileSize(data.size));
mTvTitle.setText(data.name);
mRbStar.setRating(data.stars);
mIvIcon.setImageResource(R.drawable.ic_default);// 设置默认值
// 需要去网络获取
String uri = Constans.IMAGE_BASE_URL + data.iconUrl;
BitmapHelper.display(mIvIcon, uri);
}
}
===================================================================
public class HomeFragment extends BaseFragment
{
private List<AppInfoBean> mDatas; // listView对应的数据
private List<String> mPictures; // 轮播图对应的数据
private HomeProtocol mProtocol;
@Override
protected View onLoadSuccessView()
{
// TextView tv = new TextView(UIUtils.getContext());
// tv.setText("首页");
// return tv;
ListView listView = ListViewFactory.getListView();
// 创建轮播的holder
HomePictureHolder holder = new HomePictureHolder();
// 给listView添加头
listView.addHeaderView(holder.getRootView());
// 给holder设置数据
holder.setData(mPictures);
// 设置数据 -->adapter ---> list
listView.setAdapter(new HomeAdapter(listView, mDatas));
return listView;
}
// 此方法实在子线程中执行的
@Override
protected LoadedResult onLoadingData()
{
// ## 1. 随机数的模拟
// LoadedResult[] results = new LoadedResult[] {
// LoadedResult.ERROR, LoadedResult.SUCCESS
// };
// Random rdm = new Random();
//
// try
// {
// Thread.sleep(1000);
// }
// catch (InterruptedException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// return results[rdm.nextInt(results.length)];
// // ## 2.模拟假数据
// mDatas = new ArrayList<String>();
//
// for (int i = 0; i < 50; i++)
// {
// mDatas.add(i + "");
// }
// return LoadedResult.SUCCESS;
// ## 3.去网络加载数据
// try
// {
// HttpUtils utils = new HttpUtils();
// // method,url,header,params
// String url = " http://10.0.2.2:8080/GooglePlayServer/home";
// RequestParams params = new RequestParams();
//
// params.addQueryStringParameter("index", 0 + "");
// ResponseStream stream = utils.sendSync(HttpMethod.GET, url, params);
//
// // 响应码
// int statusCode = stream.getStatusCode();
// if (200 == statusCode)
// {
// // 访问接口成功
// // 获取json字符
// String json = stream.readString();
// // 解析json字符
// Gson gson = new Gson();
// HomeBean bean = gson.fromJson(json, HomeBean.class);
//
// // 判断bean是否为空
// LoadedResult result = checkData(bean);
// if (result != LoadedResult.SUCCESS) { return result; }
//
// result = checkData(bean.list);
// if (result != LoadedResult.SUCCESS) { return result; }
//
// mDatas = bean.list;
// mPictures = bean.picture;
//
// return result;
// }
// else
// {
// // 访问接口失败
//
// return LoadedResult.ERROR;
// }
//
// }
// catch (Exception e)
// {
// e.printStackTrace();
// // 联网失败
// return LoadedResult.ERROR;
// }
// ## 4.网络操作的简单抽取
mProtocol = new HomeProtocol();
try
{
HomeBean bean = mProtocol.loadData(0);
// 判断bean是否为空
LoadedResult result = checkData(bean);
if (result != LoadedResult.SUCCESS) { return result; }
result = checkData(bean.list);
if (result != LoadedResult.SUCCESS) { return result; }
mDatas = bean.list;
mPictures = bean.picture;
return result;
}
catch (Exception e)
{
e.printStackTrace();
return LoadedResult.ERROR;
}
}
class HomeAdapter extends AppListAdapter
{
public HomeAdapter(AbsListView listView, List<AppInfoBean> datas) {
super(listView, datas);
// TODO Auto-generated constructor stub
}
@Override
protected List<AppInfoBean> onLoadMoreData() throws Exception
{
return loadMoreData(mDatas.size());
}
}
private List<AppInfoBean> loadMoreData(int index) throws Exception
{
// HttpUtils utils = new HttpUtils();
// // method,url,header,params
// String url = " http://10.0.2.2:8080/GooglePlayServer/home";
// RequestParams params = new RequestParams();
//
// params.addQueryStringParameter("index", index + "");
// ResponseStream stream = utils.sendSync(HttpMethod.GET, url, params);
//
// // 响应码
// int statusCode = stream.getStatusCode();
// if (200 == statusCode)
// {
// // 访问接口成功
// // 获取json字符
// String json = stream.readString();
// // 解析json字符
// Gson gson = new Gson();
// HomeBean bean = gson.fromJson(json, HomeBean.class);
//
// if (bean == null) { return null; }
// return bean.list;
// }
// return null;
HomeBean bean = mProtocol.loadData(index);
if (bean == null) { return null; }
return bean.list;
}
}
1.SuperBaseAdapter
public abstract class SuperBaseAdapter<T> extends BaseAdapter implements OnItemClickListener
{
private final static int TYPE_LOAD_MORE = 0;
private final static int TYPE_NORMAL_ITEM = 1;
private List<T> mDatas;
private LoadMoreHolder mLoadMoreHolder;
private LoadMoreTask mLoadMoreTask;
private AbsListView mListView;
public SuperBaseAdapter(AbsListView listView, List<T> datas) {
this.mDatas = datas;
this.mListView = listView;
mListView.setOnItemClickListener(this);
}
@Override
public int getCount()
{
if (mDatas != null) { return mDatas.size() + 1; }// 添加加载更多的item
return 0;
}
@Override
public Object getItem(int position)
{
if (mDatas != null) { return mDatas.get(position); }
return null;
}
@Override
public long getItemId(int position)
{
return position;
}
// adapter对应的item view的类型个数
@Override
public int getViewTypeCount()
{
return super.getViewTypeCount() + 1;// 添加加载更多的样式
}
// 当前position是什么type类型,返回的类型必须从0开始,而且需要累加
@Override
public int getItemViewType(int position)
{
if ((getCount() - 1) == position)
{
// 加载更多
return TYPE_LOAD_MORE;
}
return getNormalItemViewType(position);
}
/**
* 父类默认额外的item就只有一种,如果孩子需要多种,那么复写此方法
*
* @param position
* @return
*/
protected int getNormalItemViewType(int position)
{
return TYPE_NORMAL_ITEM;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
BaseHolder holder = null;
// ############### 1. 初始化item View #############################
if (convertView == null)
{
if (getItemViewType(position) == TYPE_LOAD_MORE)
{
// 加载更多的holder
holder = getLoadMoreHolder();
}
else
{
// 普通的holder
// 没有复用
// 1. 新建holder
holder = getItemHolder(position);// 太具体化
// 2. 加载视图
// convertView = View.inflate(UIUtils.getContext(),
// R.layout.item_tmp, null);// 太具体化
// 通过holder 来提供 视图
}
convertView = holder.getRootView();
// // 3.设置标记
// convertView.setTag(holder);
// // 4. 给holder初始化view
// holder.tv1 = (TextView) convertView.findViewById(R.id.tmp_tv_1);
// holder.tv2 = (TextView) convertView.findViewById(R.id.tmp_tv_2);
}
else
{
// 有复用
holder = (BaseHolder) convertView.getTag();
}
// #########################################################
// ############ 2. 给View设置数据 #############################
// String data = mDatas.get(position);
// // 给holder中的view设置数据
// holder.tv1.setText("头-" + data);
// holder.tv2.setText("内容-" + data);
if (getItemViewType(position) == TYPE_LOAD_MORE)
{
// 给加载更多的holder添加数据
if (hasLoadMore())
{
// 有加载更多的功能
// 去网络加载数据,加载到 mDatas
performLoadMoreData();
}
else
{
// 没有加载更多
mLoadMoreHolder.setData(LoadMoreHolder.STATE_EMPTY);
}
}
else
{
// 给普通holder添加数据
T data = mDatas.get(position);
// 给holder中的view设置数据
holder.setData(data);
}
// #########################################################
return convertView;
}
private void performLoadMoreData()
{
// 去网络加载数据,加载到 mDatas
// 只允许一个加载更多的线程
if (mLoadMoreTask != null)
{
// 正在加载
return;
}
System.out.println("加载中......");
// 设置状态为加载更多
mLoadMoreHolder.setData(LoadMoreHolder.STATE_LOADING);
mLoadMoreTask = new LoadMoreTask();
ThreadManager.getLongPool().execute(mLoadMoreTask);
}
/**
* 默认adapter具备加载更多的功能,如果子类不希望有,就复写此方法
*
* @return
*/
protected boolean hasLoadMore()
{
return true;
}
private LoadMoreHolder getLoadMoreHolder()
{
if (mLoadMoreHolder == null)
{
mLoadMoreHolder = new LoadMoreHolder();
}
return mLoadMoreHolder;
}
protected abstract BaseHolder<T> getItemHolder(int position);
/**
* 当加载更多时的回调,如果孩子有加载更多的功能,必须实现此方法
*
* @return
*/
protected List<T> onLoadMoreData() throws Exception
{
return null;
}
class LoadMoreTask implements Runnable
{
@Override
public void run()
{
// 去网络加载数据,加载到 mDatas,UI更新
List<T> mMoreDatas = null;
int state = LoadMoreHolder.STATE_LOADING;
try
{
mMoreDatas = onLoadMoreData();
Thread.sleep(500);
// 如果数据为空--> 服务器已经没数据了
if (mMoreDatas == null || mMoreDatas.size() == 0)
{
state = LoadMoreHolder.STATE_EMPTY;
return;
}
int size = mMoreDatas.size();
// 如果数据不为空--> 小于一页的数据量,服务器已经没数据
if (size < Constans.PAGER_SIZE)
{
state = LoadMoreHolder.STATE_EMPTY;
}
else
{
// 如果数据不为空 -->等于一页的数据量,服务器有可能有更多的数据
state = LoadMoreHolder.STATE_LOADING;
}
}
catch (Exception e)
{
e.printStackTrace();
state = LoadMoreHolder.STATE_ERROR;
}
final int currentState = state;
final List<T> loadMoreDatas = mMoreDatas;
UIUtils.post(new Runnable() {
@Override
public void run()
{
// UI更新
// 更新加载更多
mLoadMoreHolder.setData(currentState);
if (currentState == LoadMoreHolder.STATE_ERROR)
{
// 如果产生异常
Toast.makeText(UIUtils.getContext(), "服务器异常", Toast.LENGTH_SHORT).show();
}
if (loadMoreDatas != null)
{
// 更新adapter
mDatas.addAll(loadMoreDatas);
// adapter更新
notifyDataSetChanged();
}
}
});
// 执行完成
mLoadMoreTask = null;
}
}
/**
* 如果孩子有item的点击事件,复写此方法即可
*
* @param parent
* @param view
* @param position
* @param id
*/
protected void onNoramlItemClick(AdapterView<?> parent, View view, int position, long id)
{
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// position 指的是listView的position(含头),不是adapter的position
if (mListView instanceof ListView)
{
int count = ((ListView) mListView).getHeaderViewsCount();
position = position - count;
}
if (getItemViewType(position) == TYPE_LOAD_MORE)
{
// 点击的是加载更多
int currentState = mLoadMoreHolder.getCurrentState();
if (currentState == LoadMoreHolder.STATE_ERROR)
{
// 去加载更多
performLoadMoreData();
}
}
else
{
// 点击的是普通的item
onNoramlItemClick(parent, view, position, id);
}
}
}