分类界面现在有3个Holder,一个是Title,一个是图片的内容,还有一个是加载更多,加载更多不需要显示,因此
//获取到当前有几种类型的数据,默认是1种
// 又额外多了一种条目类型 现在又三种 1 标题 2 内容 3 加载更多(没有显示)
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return super.getViewTypeCount() + 1;
}
为了让加载更多不显示,需要在父类中对MoreHolder进行设置,携带上参数判断是否需要加载更多getMore(),这个是返回一个boolean类型的数据
DefaultAdapter.java中
private BaseHolder getMoreHolder() {
if(holder!=null){
return holder;
}else{
holder=new MoreHolder(this, hasMore());
return holder;
}
}
在MoreHolder.java的构造函数中进行判断参数
public MoreHolder(DefaultAdapter adapter, boolean hasMore) {
super();
this.adapter=adapter;
this.hasMore = hasMore;
//没有额外数据不刷新界面
if(!hasMore){
setData(0);
}
}
MoreHolder.java加载更多,当不需要加载更多的时候不掉用setData()
package com.ldw.market.holder;
import com.ldw.market.R;
import com.ldw.market.Adapter.DefaultAdapter;
import com.ldw.market.utils.UiUtils;
import android.view.View;
import android.widget.RelativeLayout;
/*
* 加载更多的实现,直接把它当成一个Holder
*/
public class MoreHolder extends BaseHolder<Integer>{
public static final int HAS_NO_MORE=0; // 没有额外数据了
public static final int LOAD_ERROR=1;// 加载失败
public static final int HAS_MORE=2;// 有额外数据
private RelativeLayout rl_more_loading,rl_more_error;
private boolean hasMore;//是否加载更多
//MoreHolder的显示
@Override
public 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;
//接受adapter
public MoreHolder(DefaultAdapter adapter, boolean hasMore) {
super();
this.adapter=adapter;
this.hasMore = hasMore;
//没有额外数据不刷新界面
if(!hasMore){
setData(0);
}
}
@Override
public View getContentView() {
//如果加载更多true,才加载更多
if(hasMore){
loadMore();
}
return super.getContentView();
}
private void loadMore() {
// 请求服务器 加载下一批数据
// 交给Adapter 让Adapter 加载更多数据
adapter.loadMore();
}
//刷新界面
@Override
public void refreshView(Integer data) {
rl_more_error.setVisibility(data==LOAD_ERROR?View.VISIBLE:View.GONE);
rl_more_loading.setVisibility(data==HAS_MORE?View.VISIBLE:View.GONE);
}
}
DefaultAdapter.java
package com.ldw.market.Adapter;
import java.util.List;
import com.ldw.market.domain.AppInfo;
import com.ldw.market.holder.BaseHolder;
import com.ldw.market.holder.MoreHolder;
import com.ldw.market.manager.ThreadManager;
import com.ldw.market.utils.UiUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.Toast;
/*
* BaseAdapter的共性方法的封装,使用泛型封装
*/
public abstract class DefaultAdapter<Data> extends BaseAdapter implements OnItemClickListener {
protected List<Data> datas;
private static final int DEFAULT_ITEM = 0;//普通的条目
private static final int MORE_ITEM = 1;//加载更多的条目
private ListView lv;
//get方法
public List<Data> getDatas() {
return datas;
}
//set方法
public void setDatas(List<Data> datas) {
this.datas = datas;
}
//构造函数,初始化数据
public DefaultAdapter(List<Data> datas, ListView lv) {
this.datas = datas;
//ListView添加条目点击事件
lv.setOnItemClickListener(this);
this.lv =lv;
}
// ListView 条目点击事件回调的方法
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
//Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();
position=position-lv.getHeaderViewsCount();// 获取到顶部条目的数量 位置去掉顶部view的数量
onInnerItemClick(position);
}
/**在该方法去处理条目的点击事件*/
public void onInnerItemClick(int position) {
}
//ListView条目事件的回调方法
@Override
public int getCount() {
// +1是尾部添加一个加载更多
return datas.size() + 1;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
}
/** 根据位置 判断当前条目是什么类型 */
@Override
public int getItemViewType(int position) {
if (position == datas.size()) { // 当前是最后一个条目,加载更多
return MORE_ITEM;
}
// 如果不是最后一个条目 返回默认类型
return getInnerItemViewType(position);
}
protected int getInnerItemViewType(int position) {
// 返回默认类型
return DEFAULT_ITEM;
}
/** 当前ListView 有几种不同的条目类型 ,默认只有一种Holder*/
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return super.getViewTypeCount()+ 1; // 2 有两种不同的类型
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//BaseHolder使用泛型以支持多种数据类型的Holder
BaseHolder holder = null;
//当前是最后的一个位置显示加载更多MoreHolder
switch (getItemViewType(position)) { // 判断当前条目时什么类型
case MORE_ITEM:
//从MoreHolder中获取Holder
if(convertView==null){
//加载更多
holder=getMoreHolder();
}else{
//缓冲中获取
holder=(BaseHolder) convertView.getTag();
}
break;
default:
//从默认中获取Holder
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
if (position < datas.size()) {
holder.setData(datas.get(position));
}
break;
}
// 如果当前Holder 恰好是MoreHolder 证明MoreHOlder已经显示
return holder.getContentView();
}
private MoreHolder holder;
private BaseHolder getMoreHolder() {
if(holder!=null){
return holder;
}else{
holder=new MoreHolder(this, hasMore());
return holder;
}
}
//默认有额外数据
protected boolean hasMore() {
return true;
}
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){
holder.setData(MoreHolder.LOAD_ERROR);
}else if(newData.size()==0){
//没有数据了
holder.setData(MoreHolder.HAS_NO_MORE);
}else{
// 成功了,加载更多数据
holder.setData(MoreHolder.HAS_MORE);
datas.addAll(newData);// 给listView之前的集合添加一个新的集合
notifyDataSetChanged();// 刷新界面
}
}
});
}
});
}
/**
* 加载更多数据
*/
protected abstract List<Data> onload();
}
显示的界面有Title和图片2个部分,2个不同的Holder,根据之前解析的数据,判断当前是不是Title,如果是title的数据就显示Title的Hooder,反之显示图片的Holder
CategoryFragment.java
package com.ldw.market.fragment;
import java.util.List;
import com.ldw.market.Adapter.DefaultAdapter;
import com.ldw.market.domain.CategoryInfo;
import com.ldw.market.holder.BaseHolder;
import com.ldw.market.holder.CategoryContentHolder;
import com.ldw.market.holder.CategoryTitleHolder;
import com.ldw.market.protocol.CategoryProtocol;
import com.ldw.market.utils.UiUtils;
import com.ldw.market.view.BaseListView;
import com.ldw.market.view.LoadingPage.LoadResult;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
public class CategoryFragment extends BaseFragment1 {
private List<CategoryInfo> datas;
public static int ITEM_TITLE =2;//标题类型的数据
//创建成功界面
@Override
public View createSuccessView() {
BaseListView listView = new BaseListView(UiUtils.getContext());
listView.setAdapter(new CategoryAdapter(datas, listView));
return listView;
}
private class CategoryAdapter extends DefaultAdapter<CategoryInfo>{
private int position;// 当前条目位置记录
public CategoryAdapter(List<CategoryInfo> datas, ListView lv) {
super(datas, lv);
// TODO Auto-generated constructor stub
}
//实现条目的界面
@Override
protected BaseHolder<CategoryInfo> getHolder() {
//根据返回的type类型来显示不同的类型
if (!datas.get(position).isTitle()) {
return new CategoryContentHolder();
}else{
return new CategoryTitleHolder();
}
}
//获取到position位置的条目
@Override
public View getView(int position, View convertView, ViewGroup parent) {
this.position = position;
return super.getView(position, convertView, parent);
}
//false,没有额外的数据,不会调用onload
@Override
protected boolean hasMore() {
// TODO Auto-generated method stub
return false;
}
//根据位置返回不同的类型
@Override
protected int getInnerItemViewType(int position) {
//如果是标题的时候
if (datas.get(position).isTitle()) {
return ITEM_TITLE;
} else {
return super.getInnerItemViewType(position);
}
}
//加载更多的holder,这里不会被调用
@Override
protected List<CategoryInfo> onload() {
// TODO Auto-generated method stub
return null;
}
//获取到当前有几种类型的数据,默认是1种
// 又额外多了一种条目类型 现在又三种 1 标题 2 内容 3 加载更多(没有显示)
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return super.getViewTypeCount() + 1;
}
}
//请求服务器数据
@Override
protected LoadResult load() {
CategoryProtocol protocol = new CategoryProtocol();
datas = protocol.load(0);
return checkData(datas);
}
}
CategoryTitleHolder.java标题的Holder
package com.ldw.market.holder;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import com.ldw.market.R;
import com.ldw.market.domain.CategoryInfo;
import com.ldw.market.utils.UiUtils;
public class CategoryTitleHolder extends BaseHolder<CategoryInfo> {
private TextView tv;
@Override
public View initView() {
tv = new TextView(UiUtils.getContext());
tv.setTextColor(Color.BLACK);
tv.setBackgroundDrawable(UiUtils.getDrawalbe(R.drawable.grid_item_bg));
return tv;
}
@Override
public void refreshView(CategoryInfo data) {
tv.setText(data.getTitle());
}
}
CategoryContentHolder.java内容图片的Holder
package com.ldw.market.holder;
import com.ldw.market.R;
import com.ldw.market.domain.CategoryInfo;
import com.ldw.market.http.HttpHelper;
import com.ldw.market.utils.UiUtils;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class CategoryContentHolder extends BaseHolder<CategoryInfo>{
ImageView [] ivs;
TextView [] tvs;
@Override
public View initView() {
View view=UiUtils.inflate(R.layout.item_category_content);
//默认的item是有3个imageView和3个textView
ivs=new ImageView[3];
ivs[0]=(ImageView) view.findViewById(R.id.iv_1);
ivs[1]=(ImageView) view.findViewById(R.id.iv_2);
ivs[2]=(ImageView) view.findViewById(R.id.iv_3);
tvs=new TextView[3];
tvs[0]=(TextView) view.findViewById(R.id.tv_1);
tvs[1]=(TextView) view.findViewById(R.id.tv_2);
tvs[2]=(TextView) view.findViewById(R.id.tv_3);
return view;
}
//注意有的item并不是一行有3个控件
@Override
public void refreshView(CategoryInfo data) {
// 图片的描述和图片的地址都不是空的时候,需要设置内容,不然就是一个空块
if(!TextUtils.isEmpty(data.getName1())&&!TextUtils.isEmpty(data.getUrl1())){
tvs[0].setText(data.getName1());
bitmapUtils.display(ivs[0], HttpHelper.URL+"image?name="+data.getUrl1());
tvs[0].setVisibility(View.VISIBLE);
ivs[0].setVisibility(View.VISIBLE);
}else{
tvs[0].setVisibility(View.INVISIBLE);
ivs[0].setVisibility(View.INVISIBLE);
}
// 第二块,第一块是空的后面就没有必要显示
if(!TextUtils.isEmpty(data.getName2())&&!TextUtils.isEmpty(data.getUrl2())){
tvs[1].setText(data.getName2());
bitmapUtils.display(ivs[1], HttpHelper.URL+"image?name="+data.getUrl2());
tvs[1].setVisibility(View.VISIBLE);
ivs[1].setVisibility(View.VISIBLE);
}else{
tvs[1].setVisibility(View.INVISIBLE);
ivs[1].setVisibility(View.INVISIBLE);
}
//第三块
if(!TextUtils.isEmpty(data.getName3())&&!TextUtils.isEmpty(data.getUrl3())){
tvs[2].setText(data.getName3());
bitmapUtils.display(ivs[2], HttpHelper.URL+"image?name="+data.getUrl3());
tvs[2].setVisibility(View.VISIBLE);
ivs[2].setVisibility(View.VISIBLE);
}else{
tvs[2].setVisibility(View.INVISIBLE);
ivs[2].setVisibility(View.INVISIBLE);
}
}
}
CategoryInfo的每个信息的bean文件
package com.ldw.market.domain;
/*
* 分类的bean
*/
public class CategoryInfo {
private String title;
private String url1;
private String url2;
private String url3;
private String name1;
private String name2;
private String name3;
private boolean isTitle;// 是否是标题
public boolean isTitle() {
return isTitle;
}
public void setIsTitle(boolean isTitle) {
this.isTitle = isTitle;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl1() {
return url1;
}
public void setUrl1(String url1) {
this.url1 = url1;
}
public String getUrl2() {
return url2;
}
public void setUrl2(String url2) {
this.url2 = url2;
}
public String getUrl3() {
return url3;
}
public void setUrl3(String url3) {
this.url3 = url3;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
public String getName3() {
return name3;
}
public void setName3(String name3) {
this.name3 = name3;
}
public CategoryInfo() {
super();
}
public CategoryInfo(String title, String url1, String url2, String url3,
String name1, String name2, String name3,boolean isTitle) {
super();
this.title = title;
this.url1 = url1;
this.url2 = url2;
this.url3 = url3;
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.isTitle=isTitle;
}
}
item的布局文件item_category_content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp" >
<!-- 分类中的每一个item,每3个一组 -->
<RelativeLayout
android:id="@+id/rl_1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/grid_item_bg"
android:clickable="true"
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<ImageView
android:id="@+id/iv_1"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@drawable/ic_default" />
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/iv_1"
android:layout_centerHorizontal="true"
android:textColor="#ff7a7a7a" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_2"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/grid_item_bg"
android:clickable="true"
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<ImageView
android:id="@+id/iv_2"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@drawable/ic_default" />
<TextView
android:id="@+id/tv_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/iv_2"
android:layout_centerHorizontal="true"
android:textColor="#ff7a7a7a" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_3"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/grid_item_bg"
android:clickable="true"
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<ImageView
android:id="@+id/iv_3"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@drawable/ic_default" />
<TextView
android:id="@+id/tv_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/iv_3"
android:layout_centerHorizontal="true"
android:textColor="#ff7a7a7a" />
</RelativeLayout>
</LinearLayout>