一、抽取DefaultAdapter & BaseHolder
1 、抽取Adapter 共性的方法 。
2、 把getView方法里 和holder相关的逻辑 摘取到Holder代码中 。
3、 把Holder 相关的代码 抽取到BaseHolder中。
4、 把adapter 中getVIew 方法 抽取到了DefaultAdpater中, 其中每个子类getView方法中holder不太一样,所以定义了抽象方法getHolder 要求子类去实现holder。
DefaultAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.xbmu.google.holder.BaseHolder;
public abstract class DefaultAdapter<Data> extends BaseAdapter {
private List<Data> mDatas;
public DefaultAdapter(List<Data> mDatas){
this.mDatas = mDatas;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder<Data> holder;
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder<Data>) convertView.getTag();
}
holder.setData(mDatas.get(position));
return holder.getContentView();
}
protected abstract BaseHolder<Data> getHolder();
}
BaseHolder.java
package com.xbmu.google.holder;
import android.view.View;
import com.lidroid.xutils.BitmapUtils;
import com.xbmu.google.tools.BitmapHelp;
public abstract class BaseHolder<Data> {
private View contentView;
protected Data data;
protected BitmapUtils bitmapUtils;
public BaseHolder(){
bitmapUtils = BitmapHelp.getBitmapUtils();
contentView = initView();
contentView.setTag(this);
}
public void setData(Data data) {
this.data = data;
refreshView(data);
}
/**
* 初始化View对象及其控件
* @return
*/
protected abstract View initView();
/**
* 当setData调用的时候 会调用该方法 根据数据 显示界面
* @param data
*/
protected abstract void refreshView(Data data);
/**
* 当Holder中的view对象显示到界面上的时候调用
* @return
*/
public View getContentView() {
return contentView;
}
}
HomeFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.protocol.HomeProtocol;
import com.xbmu.google.tools.BitmapHelp;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class HomeFragment extends BaseFragment {
private List<AppInfo> mDatas;
private BitmapUtils bitmapUtils;
// 当Fragment挂载的activity创建的时候调用
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
show();
}
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new HomeAdapter(mDatas));
bitmapUtils = BitmapHelp.getBitmapUtils();
// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,
false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
private class HomeAdapter extends DefaultAdapter<AppInfo> {
public HomeAdapter(List<AppInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<AppInfo> getHolder() {
return new HomeHolder();
}
}
class HomeHolder extends BaseHolder<AppInfo> {
ImageView item_icon;
TextView item_title, item_size, item_bottom;
RatingBar item_rating;
@Override
protected View initView() {
View contentView = UiUtils.inflate(R.layout.item_app);
this.item_icon = (ImageView) contentView
.findViewById(R.id.item_icon);
this.item_title = (TextView) contentView
.findViewById(R.id.item_title);
this.item_rating = (RatingBar) contentView
.findViewById(R.id.item_rating);
this.item_size = (TextView) contentView
.findViewById(R.id.item_size);
this.item_bottom = (TextView) contentView
.findViewById(R.id.item_bottom);
return contentView;
}
@Override
protected void refreshView(AppInfo data) {
// 显示图片
bitmapUtils.display(this.item_icon, HttpHelper.URL + "image?name="
+ data.getIconUrl());
this.item_title.setText(data.getName());
this.item_rating.setRating(data.getStars());
this.item_size.setText(String.valueOf(data.getSize()));
this.item_bottom.setText(data.getDes());
}
}
@Override
protected LoadResult load() {
HomeProtocol protocol = new HomeProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);
}
}
SubjectFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.domain.SubjectInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.protocol.SubjectProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class SubjectFragment extends BaseFragment {
private List<SubjectInfo> mDatas;
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new SubjectAdapter(mDatas));
return listView;
}
private class SubjectAdapter extends DefaultAdapter<SubjectInfo>{
public SubjectAdapter(List<SubjectInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<SubjectInfo> getHolder() {
return new SubjectHolder();
}
}
class SubjectHolder extends BaseHolder<SubjectInfo>{
ImageView item_icon;
TextView item_txt;
@Override
protected View initView() {
View contentView = UiUtils.inflate(R.layout.item_subject);
this.item_icon = (ImageView) contentView.findViewById(R.id.item_icon);
this.item_txt = (TextView) contentView.findViewById(R.id.item_txt);
return contentView;
}
@Override
protected void refreshView(SubjectInfo data) {
bitmapUtils.display(this.item_icon,HttpHelper.URL+"image?name="+data.getUrl());
this.item_txt.setText(data.getDes());
}
}
@Override
protected LoadResult load() {
SubjectProtocol protocol = new SubjectProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);
}
}
二、应用 & 游戏界面
ListBaseHolder.java
package com.xbmu.google.holder;
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;
public class ListBaseHolder extends BaseHolder<AppInfo> {
ImageView item_icon;
TextView item_title, item_size, item_bottom;
RatingBar item_rating;
@Override
protected View initView() {
View contentView = UiUtils.inflate(R.layout.item_app);
this.item_icon = (ImageView) contentView
.findViewById(R.id.item_icon);
this.item_title = (TextView) contentView
.findViewById(R.id.item_title);
this.item_rating = (RatingBar) contentView
.findViewById(R.id.item_rating);
this.item_size = (TextView) contentView
.findViewById(R.id.item_size);
this.item_bottom = (TextView) contentView
.findViewById(R.id.item_bottom);
return contentView;
}
@Override
protected void refreshView(AppInfo data) {
// 显示图片
bitmapUtils.display(this.item_icon, HttpHelper.URL + "image?name="
+ data.getIconUrl());
this.item_title.setText(data.getName());
this.item_rating.setRating(data.getStars());
this.item_size.setText(String.valueOf(data.getSize()));
this.item_bottom.setText(data.getDes());
}
}
ListBaseAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.ListBaseHolder;
public class ListBaseAdapter extends DefaultAdapter<AppInfo> {
public ListBaseAdapter(List<AppInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<AppInfo> getHolder() {
return new ListBaseHolder();
}
}
BaseFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.lidroid.xutils.BitmapUtils;
import com.xbmu.google.tools.BitmapHelp;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.tools.ViewUtils;
import com.xbmu.google.view.LoadingPage;
import com.xbmu.google.view.LoadingPage.LoadResult;
public abstract class BaseFragment extends Fragment {
protected BitmapUtils bitmapUtils;
private LoadingPage loadingPage;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
bitmapUtils = BitmapHelp.getBitmapUtils();
if(loadingPage == null){//之前的frameLayout已经记录了一个爹了 爹是之前的ViewPager
loadingPage = new LoadingPage(UiUtils.getContext()) {
@Override
protected LoadResult load() {
return BaseFragment.this.load();
}
@Override
protected View createSuccessView() {
return BaseFragment.this.createSuccessView();
}
};
}else{
ViewUtils.removeParent(loadingPage);//移除frameLayout之前的爹
}
return loadingPage;// 拿到当前viewPager 添加这个framelayout
}
//....
}
AppFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.view.View;
import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.ListBaseAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.protocol.AppProtocol;
import com.xbmu.google.tools.BitmapHelp;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class AppFragment extends BaseFragment {
private List<AppInfo> mDatas;
/**
* 当加载成功的时候 显示的界面
*/
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new ListBaseAdapter(mDatas));
//ListView有三种滑动状态:静止,慢慢滑动,飞速滑动
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,
false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
/**
* 请求服务器获取服务器的数据
*/
@Override
protected LoadResult load() {
AppProtocol protocol = new AppProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);//检查数据有三种结果:成功,错误,空
}
}
AppProtocol.java
package com.xbmu.google.protocol;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.google.domain.AppInfo;
public class AppProtocol extends BaseProtocol<List<AppInfo>> {
@Override
protected List<AppInfo> parseJson(String json) {
List<AppInfo> appInfos = new ArrayList<AppInfo>();
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Long id = jsonObject.getLong("id");
String name = jsonObject.getString("name");
String packageName = jsonObject.getString("packageName");
String iconUrl = jsonObject.getString("iconUrl");
float stars = Float.parseFloat(jsonObject.getString("stars"));
Long size = jsonObject.getLong("size");
String downloadUrl = jsonObject.getString("downloadUrl");
String des = jsonObject.getString("des");
AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl, stars, size, downloadUrl, des);
appInfos.add(appInfo);
}
return appInfos;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
protected String getKey() {
return "app";
}
}
HomeFragment.java、AppFragment.java、GameFragment.java
HomeProtocol.java、AppProtocol.java、GameProtocol.java
代码大致一样。
SubjectFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.domain.SubjectInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.protocol.SubjectProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class SubjectFragment extends BaseFragment {
private List<SubjectInfo> mDatas;
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new SubjectAdapter(mDatas));
// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,
false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
private class SubjectAdapter extends DefaultAdapter<SubjectInfo> {
public SubjectAdapter(List<SubjectInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<SubjectInfo> getHolder() {
return new SubjectHolder();
}
}
class SubjectHolder extends BaseHolder<SubjectInfo> {
ImageView item_icon;
TextView item_txt;
@Override
protected View initView() {
View contentView = UiUtils.inflate(R.layout.item_subject);
this.item_icon = (ImageView) contentView
.findViewById(R.id.item_icon);
this.item_txt = (TextView) contentView.findViewById(R.id.item_txt);
return contentView;
}
@Override
protected void refreshView(SubjectInfo data) {
bitmapUtils.display(this.item_icon, HttpHelper.URL + "image?name="
+ data.getUrl());
this.item_txt.setText(data.getDes());
}
}
@Override
protected LoadResult load() {
SubjectProtocol protocol = new SubjectProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);
}
}
SubjectProtocol.java
package com.xbmu.google.protocol;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.google.domain.SubjectInfo;
public class SubjectProtocol extends BaseProtocol<List<SubjectInfo>>{
@Override
protected List<SubjectInfo> parseJson(String json) {
List<SubjectInfo> subjectInfos = new ArrayList<SubjectInfo>();
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject =jsonArray.getJSONObject(i);
String des = jsonObject.getString("des");
String url = jsonObject.getString("url");
SubjectInfo subjectInfo = new SubjectInfo(des, url);
subjectInfos.add(subjectInfo);
}
return subjectInfos;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
protected String getKey() {
return "subject";
}
}
运行效果:
面向holder编程,现在把listview中的每一个条目当作一个holder。
三、MoreHolder
load_more.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:id="@+id/rl_more_loading"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_loadmore_height"
android:layout_marginLeft="@dimen/list_item_margin"
android:layout_marginRight="@dimen/list_item_margin"
android:background="@drawable/list_item_bg_normal"
android:gravity="center" >
<ProgressBar
android:id="@+id/loading_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/loading_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/loading_pb"
android:ellipsize="end"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="@string/load_more"
android:textColor="#ff717171"
android:textSize="14dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_more_error"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_loadmore_height"
android:layout_marginLeft="@dimen/list_item_margin"
android:layout_marginRight="@dimen/list_item_margin"
android:background="@drawable/list_item_bg"
android:gravity="center"
android:visibility="invisible" >
<TextView
android:id="@+id/loading_error_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:ellipsize="end"
android:gravity="center"
android:padding="5dp"
android:singleLine="true"
android:text="@string/load_error"
android:textColor="#ff717171"
android:textSize="14dp" />
</RelativeLayout>
</FrameLayout>
MoreHoder.java
package com.xbmu.google.holder;
import com.xbmu.google.R;
import com.xbmu.google.tools.UiUtils;
import android.view.View;
public class MoreHoder extends BaseHolder<Integer> {
protected static final int ERROR = 0;//加载失败
protected static final int HAS_MORE = 1;//加载成功,没有额外数据
protected static final int NO_MORE = 2;//加载成功,有额外数据
@Override
protected View initView() {
View view = View.inflate(UiUtils.getContext(), R.layout.load_more, null);
return view;
}
@Override
protected void refreshView(Integer data) {
}
}
DefaultAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.MoreHoder;
public abstract class DefaultAdapter<Data> extends BaseAdapter {
private List<Data> mDatas;
private static final int DEFAULT_ITEM = 0;
private static final int MORE_ITEM = 1;
public DefaultAdapter(List<Data> mDatas) {
this.mDatas = mDatas;
}
public List<Data> getmDatas() {
return mDatas;
}
public void setmDatas(List<Data> mDatas) {
this.mDatas = mDatas;
}
@Override
public int getCount() {
return mDatas.size() + 1;// 最后的一个条目就是加载更多的条目
}
@Override
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/** 根据位置 判断当前条目是什么类型 */
@Override
public int getItemViewType(int position) {
if (position == mDatas.size()) { // 当前是最后一个条目
return MORE_ITEM;
}
return getInnerItemViewType(position);// 如果不是最后一个条目 返回默认类型
}
private int getInnerItemViewType(int position) {
return DEFAULT_ITEM;
}
/** 当前ListView有几种不同的条目类型 */
@Override
public int getViewTypeCount() {
return super.getViewTypeCount() + 1; // 2 有两种不同的类型
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
if(position == mDatas.size()){//如果位置为最后一个位置 就显示MoreHolder
holder = getMoreHolder();
return holder.getContentView();
}
if(convertView==null){
holder = getHolder();//普通条目的holder
}else{
holder = (BaseHolder) convertView.getTag();//复用
}
holder.setData(mDatas.get(position));
return holder.getContentView();
}
private BaseHolder getMoreHolder() {
return new MoreHoder();
}
protected abstract BaseHolder<Data> getHolder();
}
四、ListView多类型复用
DefaultAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.MoreHoder;
public abstract class DefaultAdapter<Data> extends BaseAdapter {
private List<Data> mDatas;
private static final int DEFAULT_ITEM = 0;
private static final int MORE_ITEM = 1;
public DefaultAdapter(List<Data> mDatas) {
this.mDatas = mDatas;
}
public List<Data> getmDatas() {
return mDatas;
}
public void setmDatas(List<Data> mDatas) {
this.mDatas = mDatas;
}
@Override
public int getCount() {
return mDatas.size() + 1;// 最后的一个条目就是加载更多的条目
}
@Override
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/** 根据位置 判断当前条目是什么类型 */
@Override
public int getItemViewType(int position) {
if (position == mDatas.size()) { // 当前是最后一个条目
return MORE_ITEM;
}
return getInnerItemViewType(position);// 如果不是最后一个条目 返回默认类型
}
private int getInnerItemViewType(int position) {
return DEFAULT_ITEM;
}
/** 当前ListView有几种不同的条目类型 */
@Override
public int getViewTypeCount() {
return super.getViewTypeCount() + 1; // 2 有两种不同的类型
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
// if (convertView == null) {
// if (getInnerItemViewType(position) == MORE_ITEM) {
// holder = getMoreHolder();
// } else {
// holder = getHolder();// 普通条目的holder
// }
// } else {
// if (getItemViewType(position) == DEFAULT_ITEM) {
// holder = (BaseHolder) convertView.getTag();// 复用
// } else {
// // 不是普通的holder,我们在这里直接创建,不用复用也可以
// holder = getMoreHolder();
// }
// }
// if (getItemViewType(position) == DEFAULT_ITEM) {
// holder.setData(mDatas.get(position));
// }
switch (getItemViewType(position)) {// 判断当前条目是什么类型
case MORE_ITEM:
if (convertView == null) {
holder = getMoreHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
break;
case DEFAULT_ITEM:
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
if (position < mDatas.size()) {
holder.setData(mDatas.get(position));
}
break;
}
return holder.getContentView();// 如果当前Holder恰好是MoreHolder 证明MoreHolder已经显示
}
private BaseHolder getMoreHolder() {
return new MoreHoder();
}
protected abstract BaseHolder<Data> getHolder();
}
五、加载更多业务逻辑
MoreHolder.java
package com.xbmu.google.holder;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.tools.UiUtils;
import android.view.View;
public class MoreHoder extends BaseHolder<Integer> {
protected static final int ERROR = 0;//加载失败
protected static final int HAS_MORE = 1;//加载成功,没有额外数据
protected static final int NO_MORE = 2;//加载成功,有额外数据
@Override
protected View initView() {
View view = View.inflate(UiUtils.getContext(), R.layout.load_more, null);
return view;
}
private DefaultAdapter adapter;
public MoreHoder(DefaultAdapter adapter) {
super();
this.adapter = adapter;
}
@Override
public View getContentView() {
loadMore();
return super.getContentView();
}
private void loadMore() {
// 请求服务器 加载下一批数据
// 交给Adapter 让Adapter 加载更多数据
adapter.loadMore();
}
@Override
protected void refreshView(Integer data) {
// TODO Auto-generated method stub
}
}
DefaultAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.MoreHoder;
import com.xbmu.google.manager.ThreadManager;
import com.xbmu.google.tools.UiUtils;
public abstract class DefaultAdapter<Data> extends BaseAdapter {
private List<Data> mDatas;
private static final int DEFAULT_ITEM = 0;
private static final int MORE_ITEM = 1;
public DefaultAdapter(List<Data> mDatas) {
this.mDatas = mDatas;
}
public List<Data> getmDatas() {
return mDatas;
}
public void setmDatas(List<Data> mDatas) {
this.mDatas = mDatas;
}
@Override
public int getCount() {
return mDatas.size() + 1;// 最后的一个条目就是加载更多的条目
}
@Override
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/** 根据位置 判断当前条目是什么类型 */
@Override
public int getItemViewType(int position) {
if (position == mDatas.size()) { // 当前是最后一个条目
return MORE_ITEM;
}
return getInnerItemViewType(position);// 如果不是最后一个条目 返回默认类型
}
private int getInnerItemViewType(int position) {
return DEFAULT_ITEM;
}
/** 当前ListView有几种不同的条目类型 */
@Override
public int getViewTypeCount() {
return super.getViewTypeCount() + 1; // 2 有两种不同的类型
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
switch (getItemViewType(position)) {// 判断当前条目是什么类型
case MORE_ITEM:
if (convertView == null) {
holder = getMoreHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
break;
case DEFAULT_ITEM:
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
if (position < mDatas.size()) {
holder.setData(mDatas.get(position));
}
break;
}
return holder.getContentView();// 如果当前Holder恰好是MoreHolder 证明MoreHolder已经显示
}
private MoreHoder moreHolder;
private BaseHolder getMoreHolder() {
if(moreHolder!=null){
return moreHolder;
}else{
moreHolder = new MoreHoder(this);
return moreHolder;
}
}
protected abstract BaseHolder<Data> getHolder();
/**
* 当加载更多条目显示的时候 调用该方法
*/
public void loadMore() {
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
// 在子线程中加载更多
final List<Data> newData = onload();
UiUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if(newData==null){
// TODO 链接服务器失败
}else if(newData.size()==0){
//TODO 服务器已经没有额外数据了
}else{
//成功了
mDatas.addAll(newData);//给ListView之前的集合添加一个新集合
notifyDataSetChanged();//刷新界面
}
}
});
}
});
}
protected abstract List<Data> onload();
}
六、加载更多
MoreHolder.java
package com.xbmu.google.holder;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.tools.UiUtils;
import android.view.View;
import android.widget.RelativeLayout;
public class MoreHoder extends BaseHolder<Integer> {
public static final int ERROR = 0;//加载失败
public static final int HAS_MORE = 1;//加载成功,没有额外数据
public static final int NO_MORE = 2;//加载成功,有额外数据
private RelativeLayout rl_more_loading,rl_more_error;
/**当Holder显示的时候 显示什么样子*/
@Override
protected View initView() {
View view = View.inflate(UiUtils.getContext(), R.layout.load_more, null);
rl_more_loading = (RelativeLayout) view.findViewById(R.id.rl_more_loading);
rl_more_error = (RelativeLayout) view.findViewById(R.id.rl_more_error);
return view;
}
private DefaultAdapter adapter;
public MoreHoder(DefaultAdapter adapter) {
super();
this.adapter = adapter;
}
@Override
public View getContentView() {
loadMoew();
return super.getContentView();
}
private void loadMoew() {
// 请求服务器 加载下一批数据
// 交给Adapter 让Adapter 加载更多数据
adapter.loadMore();
}
/**根据数据做界面的修改*/
@Override
protected void refreshView(Integer data) {
rl_more_error.setVisibility(data==ERROR ? View.VISIBLE : View.GONE);
rl_more_loading.setVisibility(data==HAS_MORE ? View.VISIBLE : View.GONE);
}
}
DefaultAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.MoreHoder;
import com.xbmu.google.manager.ThreadManager;
import com.xbmu.google.tools.UiUtils;
public abstract class DefaultAdapter<Data> extends BaseAdapter {
//.....
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
switch (getItemViewType(position)) {// 判断当前条目是什么类型
case MORE_ITEM:
if (convertView == null) {
holder = getMoreHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
break;
case DEFAULT_ITEM:
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
if (position < mDatas.size()) {
holder.setData(mDatas.get(position));
}
break;
}
return holder.getContentView();// 如果当前Holder恰好是MoreHolder 证明MoreHolder已经显示
}
private MoreHoder moreHolder;
private BaseHolder getMoreHolder() {
if(moreHolder!=null){
return moreHolder;
}else{
moreHolder = new MoreHoder(this);
return moreHolder;
}
}
protected abstract BaseHolder<Data> getHolder();
/**
* 当加载更多条目示的时候 调用该方法
*/
public void loadMore() {
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
// 在子线程中加载更多
final List<Data> newData = onload();
UiUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if(newData==null){
//链接服务器失败
moreHolder.setData(MoreHoder.ERROR);
}else if(newData.size()==0){
//服务器已经没有额外数据了
moreHolder.setData(MoreHoder.NO_MORE);
}else{
//成功了
moreHolder.setData(MoreHoder.HAS_MORE);
mDatas.addAll(newData);//给ListView之前的集合添加一个新集合
notifyDataSetChanged();//刷新界面
}
}
});
}
});
}
protected abstract List<Data> onload();
}
ListBaseAdapter.java
package com.xbmu.google.adapter;
import java.util.List;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.ListBaseHolder;
public abstract class ListBaseAdapter extends DefaultAdapter<AppInfo> {
public ListBaseAdapter(List<AppInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<AppInfo> getHolder() {
return new ListBaseHolder();
}
@Override
protected abstract List<AppInfo> onload();
}
AppFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.view.View;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.ListBaseAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.protocol.AppProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class AppFragment extends BaseFragment {
private List<AppInfo> mDatas;
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new ListBaseAdapter(mDatas){
@Override
protected List<AppInfo> onload() {
AppProtocol protocol = new AppProtocol();
List<AppInfo> load = protocol.load(mDatas.size());
mDatas.addAll(load);
return load;
}
});
// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,
false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
@Override
protected LoadResult load() {
AppProtocol protocol = new AppProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);
}
}
HomeFragment.java、GameFragment.java和AppFragment.java代码修改类似
SubjectFragment.java
package com.xbmu.google.fragment;
import java.util.List;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.domain.SubjectInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.protocol.SubjectProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;
public class SubjectFragment extends BaseFragment {
private List<SubjectInfo> mDatas;
@Override
protected View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new SubjectAdapter(mDatas));
// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,
false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
private class SubjectAdapter extends DefaultAdapter<SubjectInfo> {
public SubjectAdapter(List<SubjectInfo> mDatas) {
super(mDatas);
}
@Override
protected BaseHolder<SubjectInfo> getHolder() {
return new SubjectHolder();
}
@Override
protected List<SubjectInfo> onload() {
SubjectProtocol protocol = new SubjectProtocol();
List<SubjectInfo> load= protocol.load(mDatas.size());
mDatas.addAll(load);
return load;
}
}
class SubjectHolder extends BaseHolder<SubjectInfo> {
ImageView item_icon;
TextView item_txt;
@Override
protected View initView() {
View contentView = UiUtils.inflate(R.layout.item_subject);
this.item_icon = (ImageView) contentView
.findViewById(R.id.item_icon);
this.item_txt = (TextView) contentView.findViewById(R.id.item_txt);
return contentView;
}
@Override
protected void refreshView(SubjectInfo data) {
bitmapUtils.display(this.item_icon, HttpHelper.URL + "image?name="
+ data.getUrl());
this.item_txt.setText(data.getDes());
}
}
@Override
protected LoadResult load() {
SubjectProtocol protocol = new SubjectProtocol();
mDatas = protocol.load(0);
return checkData(mDatas);
}
}
DefaultAdapter.java和MoeHolder.java之间实现“加载更多”功能方法之间的调用图:
运行效果图:
全部代码