初学Android项目:开发电子市场<第二天>下

来源:互联网 发布:百度开放大数据 编辑:程序博客网 时间:2024/06/03 09:43

哟哟哟....

项目开发第二天,这里我完成了类似“电子市场”种应用的框架的整体搭建,已经完成了,以后的开发就按照这种方法去实现。

不断地抽取,将所有的公有部分抽取出来,这样编写的代码,就很简洁,清晰,明了。

感谢传智播客提供的教学视频,让我不断学习,不断完善自己。


下午,主要完成以下功能:

1.抽取MyBaseAdapter

2.写加载更多的Holder。MoreHolder

3.模拟加载更多地数据,测试。

运行效果图:


语言是苍白的,代码是真实的。

MyBaseAdapter.java

package com.example.adapter;import java.util.List;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import com.example.holder.BaseHolder;import com.example.holder.MoreHolder;import com.example.manage.ThreadManager;import com.example.utils.UIUtils;/** * 将所有的adapter里面的holder和填充的数据抽取到MyBaseAdapter * @author bitaotao * @param <T> 需要填充的数据 */public abstract class MyBaseAdapter<T> extends BaseAdapter {private List<T> mDatas ;private BaseHolder<T> holder;public MyBaseAdapter(List<T> mDatas) {//在构造方法里面,就将数据设置进去setDatas(mDatas);}public List<T> getDatas() {return mDatas;}public void setDatas(List<T> mDatas) {this.mDatas = mDatas;}@Overridepublic int getCount() {return mDatas.size() + 1;//加 1 是为了最后加载更多的布局}@Overridepublic Object getItem(int position) {return mDatas.get(position);}@Overridepublic long getItemId(int position) {return position;}private final int MORE_VIEW_TYPE = 0; private final int ITEM_VIEW_TYPE = 1;private MoreHolder moreHolder; //根据position位置返回那种item展示类型@Overridepublic int getItemViewType(int position) {if(position == getCount() - 1){return MORE_VIEW_TYPE;//加载更多地布局}else{return getItemViewTypeInner(position);}}private int getItemViewTypeInner(int position) {return ITEM_VIEW_TYPE;//普通的item的布局}//获取item有几种类型,默认是一种类型, 这里再加1是为了做加载更多@Overridepublic int getViewTypeCount() {return super.getViewTypeCount() + 1;//加 1 是为了最后加载更多的布局}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if(null != convertView){holder = (BaseHolder<T>) convertView.getTag();}else{if(MORE_VIEW_TYPE == getItemViewType(position)){holder = getMoreHolder();}else{holder = getHolder();}if(ITEM_VIEW_TYPE == getItemViewType(position)){holder.setData(getDatas().get(position));}}return holder.getRootView();}private BaseHolder getMoreHolder() {if(null == moreHolder){moreHolder = new MoreHolder(this,hasMore());}return moreHolder;}/** * 是否有更多数据 * @return */public boolean hasMore() {return true;}public abstract BaseHolder<T> getHolder();private boolean is_loading = false;/** * 加载更多数据 */public void loadMore() {//防止重复加载if(!is_loading){is_loading = true;ThreadManager.getLongPool().execute(new Runnable() {@Overridepublic void run() {final List list = onLoadMore();UIUtils.runInMainThread(new Runnable() {@Overridepublic void run() {if(null == list){getMoreHolder().setData(MoreHolder.ERROR);}else if(list.size() < 20){getMoreHolder().setData(MoreHolder.NO_MORE);}else{getMoreHolder().setData(MoreHolder.HAS_MORE);}if(null != list){if(null != mDatas){mDatas.addAll(list);}else{setDatas(list);}}notifyDataSetChanged();is_loading = false;}});}});}}public abstract List onLoadMore();}

MoreHolder.java

package com.example.holder;import com.example.R;import com.example.adapter.MyBaseAdapter;import com.example.utils.UIUtils;import android.view.View;import android.widget.RelativeLayout;public class MoreHolder extends BaseHolder<Integer> {// 表示跟服务器交互成功,没有更多数据类型public static final int NO_MORE = 0;// 没有数据// 表示跟服务器交互成功,有更多数据类型public static final int HAS_MORE = 1;//有数据// 表示跟服器交互失败public static final int ERROR = 2;//错误private MyBaseAdapter adapter;private RelativeLayout rl_more_loading,rl_more_error;public MoreHolder(MyBaseAdapter adapter, boolean hasMore) {this.adapter = adapter;setData(hasMore ? HAS_MORE : NO_MORE);}@Overridepublic View getRootView() {if(getData() == HAS_MORE){//有更多数据,调用加载更多方法loadMore();}return super.getRootView();}private void loadMore() {adapter.loadMore();}@Overridepublic void refershView() {Integer data = getData();rl_more_loading.setVisibility(data == HAS_MORE ? View.VISIBLE : View.GONE);rl_more_error.setVisibility(data ==ERROR ? View.VISIBLE : View.GONE);}@Overridepublic View initView() {View view = UIUtils.inflate(R.layout.list_more_loading);rl_more_loading = (RelativeLayout) view.findViewById(R.id.rl_more_loading);rl_more_error = (RelativeLayout) view.findViewById(R.id.rl_more_error);return view;}}

HomeFragment.java

package com.example.fragment;import java.util.ArrayList;import java.util.List;import android.view.View;import android.widget.ListView;import android.widget.TextView;import com.btt.ui.widget.LoadingPager.LoadResult;import com.example.adapter.MyBaseAdapter;import com.example.holder.BaseHolder;import com.example.utils.UIUtils;public class HomeFragment extends BaseFragment {private List<String> mDatas;@Overrideprotected View createSuccessView() {ListView mListView = new ListView(UIUtils.getContext());MyBaseAdapter adapter = new HomeAdapter(mDatas);mListView.setAdapter(adapter);return mListView;}@Overrideprotected LoadResult load() {//模拟一些假数据mDatas = new ArrayList<String>();for (int i = 0; i < 30; i++) {mDatas.add("我是菜鸟"+i+"号");}return check(mDatas);}private class HomeAdapter<T> extends MyBaseAdapter{public HomeAdapter(List<T> mDatas) {super(mDatas);}@Overridepublic BaseHolder getHolder() {return new ViewHolder();}@Overridepublic List onLoadMore() {//模拟一些要加载的假数据List<String> moreData = new ArrayList<String>();for (int i = 0; i < 30; i++) {moreData.add("我是更多数据"+i);}return moreData;}}/** * 这里我们新增了一个内部类ViewHolder,用于对控件的实例进行缓存。当convertView为空的时候,创建一个ViewHolder对象, * 并将控件的实例存放在ViewHolder里,然后调用View的setTag()方法,将ViewHolder对象存储在View中。 * 当convertView不为空的时候则调用View的getTag()方法,把ViewHolder重新取出。这样所有控件的实例都缓存在了ViewHolder里 * @author bitaotao */private class ViewHolder extends BaseHolder<String>{TextView tv;@Overridepublic void refershView() {tv.setText(getData());//将获得的数据,设置给TextView}@Overridepublic View initView() {tv  = new TextView(UIUtils.getContext());return tv;}}}


学习总结:


上午没有总结,下午就总结在这里:

1.ListView的优化
在HomeFragment类新增一个内部类ViewHolder,用于对控件的实例进行缓存。
当convertView为空的时候,创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用View的setTag()方法。
将ViewHolder的对象存储在View中。
当convertView不为空的时候则调用View的getTag()方法。把ViewHolder重新取出。这样所有控件的实例都缓存在了ViewHolder里,
就没有必要每次都通过findViewById()方法来获取控件实例了。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
//档convertView为空时
convertView = new TextView(UIUtils.getContext());//控件的实例,这里也可以加载布局,布局中就有控件
holder = new ViewHolder();//创建ViewHolder对象,用于缓存控件
holder.tv = (TextView) convertView;//将控件或者布局的实例都存放在ViewHolder里
convertView.setTag(holder);//将ViewHolder的对象存储在View中
}else{
//convertView不为空,把ViewHolder重新取出
holder = (ViewHolder) convertView.getTag();
}
//设置数据
holder.tv.setText(mDatas.get(position));
return convertView;
}

}
public class ViewHolder{
TextView tv;
}

2.抽取BaseHolder类,采用面向holder编程。
面向ListView编程时,在使用holder优化时,就相当于我们面向holder编程了。在使用ListView编写布局时,
需要填充数据,当我们抽取holder的时候,可以将布局和数据都抽取出来,因为每个ListView都有布局和填充的数据,
这些都是共性。
public abstract class BaseHolder<T> {
private View view;
private T data;
public BaseHolder(){
view = initView();//初始化view
view.setTag(this);//将holder对象存储在view中

}
...
}
3.抽取MyBaseAdapter类,将所有的adapter里面的holder和填充的数据抽取到MyBaseAdapter
public class MyBaseAdapter<T> extends BaseAdapter {
private List<T> mDatas;
private BaseHolder<T> holder;
public MyBaseAdapter(List<T> mDatas) {
//在构造方法里面,就将数据设置进去
setmDatas(mDatas);
}
...
}
4.写MoreHolder类,用于缓存加载更多的布局和数据
这里要显示加载更多地布局,就得覆写父类中的这两个方法:
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return super.getItemViewType(position);
}




@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return super.getViewTypeCount();
}
具体详细实现请看MyBaseAdapter类和MoreHandler类


1 0
原创粉丝点击