博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10. 面向holder编程、自动轮询
阅读量:5144 次
发布时间:2019-06-13

本文共 14859 字,大约阅读时间需要 49 分钟。

没有看过上一篇文章的话,建议先去阅读GooglePlay:9.代码抽取(adapter)
项目框架的搭建:
以后每个view都是holder

BaseHolder 

  1. public abstract class BaseHolder  {//写data和t一样	private View contentView;	private Data data;	protected BitmapUtils bitmapUtils;	public BaseHolder(){		bitmapUtils = BitmapHelper.getBitmapUtils();		contentView=initView();		contentView.setTag(this);	}	/** 创建界面*/	public  abstract View initView();	public View getContentView() {		return contentView;	}	public void setData(Data data){		this.data=data;		refreshView(data);	}	/** 根据数据刷新界面*/	public abstract void refreshView(Data data);}
MoreHolder 
  1. public class MoreHolder extends BaseHolder
    { 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; /**当Holder显示的时候 显示什么样子*/ @Override public View initView() { View view=UiUtils.inflate(R.layout.load_more); 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 MoreHolder(DefaultAdapter adapter) { super(); this.adapter=adapter; } @Override public View getContentView() { 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 :
 多种不同类型条目的ListView 
  1. public abstract class DefaultAdapter extends BaseAdapter {	protected List datas;	private static final int DEFAULT_ITEM = 0;	private static final int MORE_ITEM = 1;	public List getDatas() {		return datas;	}	public void setDatas(List datas) {		this.datas = datas;	}	public DefaultAdapter(List datas) {		this.datas = datas;	}	@Override	public int getCount() {		return datas.size() + 1; // 最后的一个条目 就是加载更多的条目	}	@Override	public Object getItem(int position) {		return datas.get(position);	}	/** 根据位置 判断当前条目是什么类型 */	@Override	public int getItemViewType(int position) {  //20     		if (position == datas.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 long getItemId(int position) {		return position;	}	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 < datas.size()) {				holder.setData(datas.get(position));			}			break;		}		return holder.getContentView();  //  如果当前Holder 恰好是MoreHolder  证明MoreHOlder已经显示	}	private MoreHolder holder;	private BaseHolder getMoreHolder() {		if(holder!=null){			return holder;		}else{			holder=new MoreHolder(this);			return holder;		}	}	protected abstract BaseHolder getHolder(); /** * 当加载更多条目显示的时候 调用该方法 */ public void loadMore() { ThreadManager.getInstance().createLongPool().execute(new Runnable() { @Override public void run() { // 在子线程中加载更多 final List 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 onload();}
 
修改8的代码
SubjectFragment
  1. public class SubjectFragment extends BaseFragment {	private List
    datas; @Override public View createSuccessView() { BaseListView listView=new BaseListView (UiUtils.getContext()); listView.setAdapter(new SubjectAdapter(datas)); return listView; } private class SubjectAdapter extends DefaultAdapter
    { public SubjectAdapter(List
    datas) { super(datas); } @Override protected BaseHolder
    getHolder() { return new SubjectHolder(); } @Override protected List
    onload() { SubjectProtocol protocol=new SubjectProtocol(); List
    load = protocol.load(0); datas.addAll(load); return load; } } class SubjectHolder extends BaseHolder
    { ImageView item_icon; TextView item_txt; @Override public 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 public void refreshView(SubjectInfo data) { this.item_txt.setText(data.getDes()); bitmapUtils.display(this.item_icon, HttpHelper.URL+"image?name="+data.getUrl()); } } @Override protected LoadResult load() { SubjectProtocol protocol=new SubjectProtocol(); datas = protocol.load(0); return checkData(datas); }}
都是首页、APP、游戏页面很相似,所有又可以抽取
ListBaseHolder 
public class ListBaseHolder extends BaseHolder
{ ImageView item_icon; TextView item_title,item_size,item_bottom; RatingBar item_rating; public void refreshView(AppInfo data){ this.item_title.setText(data.getName());// 设置应用程序的名字 String size=Formatter.formatFileSize(UiUtils.getContext(), data.getSize()); this.item_size.setText(size); this.item_bottom.setText(data.getDes()); float stars = data.getStars(); this.item_rating.setRating(stars); // 设置ratingBar的值 String iconUrl = data.getIconUrl(); //http://127.0.0.1:8090/image?name=app/com.youyuan.yyhl/icon.jpg // 显示图片的控件 bitmapUtils.display(this.item_icon, HttpHelper.URL+"image?name="+iconUrl); } @Override public View initView() { View contentView=View.inflate(UiUtils.getContext(), R.layout.item_app, null); this.item_icon=(ImageView) contentView.findViewById(R.id.item_icon); this.item_title=(TextView) contentView.findViewById(R.id.item_title); this.item_size=(TextView) contentView.findViewById(R.id.item_size); this.item_bottom=(TextView) contentView.findViewById(R.id.item_bottom); this.item_rating=(RatingBar) contentView.findViewById(R.id.item_rating); return contentView; }}
ListBaseAdapter 
  1. public abstract class ListBaseAdapter extends DefaultAdapter
    { public ListBaseAdapter(List
    datas) { super(datas); } @Override protected BaseHolder
    getHolder() { return new ListBaseHolder(); } @Override protected abstract List
    onload(); }
GameFragment 
public class GameFragment extends BaseFragment {	private List
datas; /** * 加载成功的界面 */ @Override public View createSuccessView() { BaseListView listView=new BaseListView(UiUtils.getContext()); listView.setAdapter(new ListBaseAdapter(datas){ @Override protected List
onload() { GameProtocol protocol=new GameProtocol(); List
load = protocol.load(datas.size()); // datas.addAll(load); return load; } }); return listView; } /** * 请求服务器加载数据 */ @Override protected LoadResult load() { GameProtocol protocol=new GameProtocol(); datas = protocol.load(0); return checkData(datas); }}
AppFragment 
public class AppFragment extends BaseFragment {	private List
datas; /** * 当加载成功的时候 显示的界面 */ @Override public View createSuccessView() { BaseListView listView=new BaseListView(UiUtils.getContext()); listView.setAdapter(new ListBaseAdapter(datas){ @Override protected List
onload() { AppProtocol protocol=new AppProtocol(); List
load = protocol.load(0); datas.addAll(load); return load; } }); return listView; } /** * 请求服务器 获取服务器的数据 */ protected LoadResult load() { AppProtocol protocol=new AppProtocol(); datas = protocol.load(0); return checkData(datas); // 检查数据 有三种结果 成功, 错误,空 }}

  

首页有个几张图片的展示栏,所以又是一个holder
HomePictureHolder (自动轮询)
public class HomePictureHolder extends BaseHolder
> { /* 当new HomePictureHolder()就会调用该方法 */ private ViewPager viewPager; private List
datas; @Override public View initView() { viewPager = new ViewPager(UiUtils.getContext()); viewPager.setLayoutParams(new AbsListView.LayoutParams( LayoutParams.MATCH_PARENT, UiUtils .getDimens(R.dimen.home_picture_height)));//转换成dp return viewPager; } /* 当 holder.setData 才会调用 */ @Override public void refreshView(List
datas) { this.datas = datas; viewPager.setAdapter(new HomeAdapter()); viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置 Integer.Max_Vlue/2,这样开始位置也能向后划了 viewPager.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: runTask.stop(); break;// 事件的取消,有可能按下viewpager滑动到listview上停止就不轮播了 case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: runTask.start(); break; } return false; // viewPager 触摸事件 返回值要是false } }); runTask = new AuToRunTask(); runTask.start(); } boolean flag; private AuToRunTask runTask;//Runnable并不是开启子线程,所以可以在主线程运行,thread才是开启线程 public class AuToRunTask implements Runnable{ @Override public void run() { if(flag){ UiUtils.cancel(this); // 取消之前 int currentItem = viewPager.getCurrentItem(); currentItem++; viewPager.setCurrentItem(currentItem); // 延迟执行当前的任务 UiUtils.postDelayed(this, 2000);// 递归调用 } } public void start(){ if(!flag){ UiUtils.cancel(this); // 取消之前 flag=true; UiUtils.postDelayed(this, 2000);// 递归调用 } } public void stop(){ if(flag){ flag=false; UiUtils.cancel(this); } } } class HomeAdapter extends PagerAdapter { // 当前viewPager里面有多少个条目 LinkedList
convertView=new LinkedList
(); // ArrayList @Override public int getCount() { return Integer.MAX_VALUE;//这样写条目就能一直划了 } /* 判断返回的对象和 加载view对象的关系 */ @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ImageView view=(ImageView) object; convertView.add(view);// 把移除的对象 添加到缓存集合中 container.removeView(view); } @Override public Object instantiateItem(ViewGroup container, int position) { int index=position%datas.size();//访问网络需要这个参数 ImageView view; if(convertView.size()>0){ view=convertView.remove(0); }else{ view= new ImageView(UiUtils.getContext()); } bitmapUtils.display(view, HttpHelper.URL + "image?name=" + datas.get(index)); container.addView(view); // 加载的view对象 return view; // 返回的对象 } }}
 
UiUtils 添加这三个方法 
  1. /**	 * 延迟执行 任务	 * @param run   任务	 * @param time  延迟的时间	 */	public static void postDelayed(Runnable run, int time) {		BaseApplication.getHandler().postDelayed(run, time); // 调用Runable里面的run方法	}	/**	 * 取消任务	 * @param auToRunTask	 */	public static void cancel(Runnable auToRunTask) {		BaseApplication.getHandler().removeCallbacks(auToRunTask);	}	}这样写获取到图片高的dp 
    134dp
    public static int getDimens(int homePictureHeight) { return (int) getResource().getDimension(homePictureHeight); }
 
HomeFragment 
public class HomeFragment extends BaseFragment {	private List
datas; private List
pictures; // 顶部ViewPager 显示界面的数据 // 当Fragment挂载的activity创建的时候调用 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); show(); } public View createSuccessView() { BaseListView listView=new BaseListView(UiUtils.getContext()); HomePictureHolder holder=new HomePictureHolder(); holder.setData(pictures); View contentView = holder.getContentView(); // 得到holder里面管理的view对象 //contentView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT)); listView.addHeaderView(contentView); // 把holder里的view对象 添加到listView的上面 listView.setAdapter(new ListBaseAdapter(datas,listView){ @Override protected List
onload() { HomeProtocol protocol=new HomeProtocol(); List
load = protocol.load(datas.size()); datas.addAll(load); return load; } @Override public void onInnerItemClick(int position) { super.onInnerItemClick(position); Toast.makeText(getActivity(), "position:"+position, 0).show(); AppInfo appInfo = datas.get(position); Intent intent=new Intent(UiUtils.getContext(), DetailActivity.class); intent.putExtra("packageName", appInfo.getPackageName());//将包名传到详情页,详情页访问网络用包名 startActivity(intent); } }); // 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载 // 第三个参数 飞速滑动的时候是否加载图片 true 不加载 listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils, false, true)); bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片 bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片 return listView; } public LoadResult load() { HomeProtocol protocol=new HomeProtocol(); datas = protocol.load(0); // load index 从哪个位置开始获取数据 0 20 40 60 pictures = protocol.getPictures(); return checkData(datas); }}
 
修改
DefaultAdapter,这样传调到详情页面的时候position
已经是修改过的了,我们并不希望去点首页的图片展示
  1. public DefaultAdapter(List 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) { }
 
面向holder编程
  1. public View createSuccessView() {			BaseListView listView=new BaseListView(UiUtils.getContext());			HomePictureHolder holder=new HomePictureHolder();			holder.setData(pictures);			View contentView = holder.getContentView(); // 得到holder里面管理的view对象			contentView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));			listView.addHeaderView(contentView); // 把holder里的view对象 添加到listView的上面

转载于:https://www.cnblogs.com/sixrain/p/4972607.html

你可能感兴趣的文章
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
gzip
查看>>
转负二进制(个人模版)
查看>>
LintCode-Backpack
查看>>
查询数据库锁
查看>>
我对于脚本程序的理解——百度轻应用有感
查看>>
面试时被问到的问题
查看>>
当前记录已被另一个用户锁定
查看>>
Node.js 连接 MySQL
查看>>
那些年,那些书
查看>>
注解小结
查看>>
java代码编译与C/C++代码编译的区别
查看>>
Bitmap 算法
查看>>
转载 C#文件中GetCommandLineArgs()
查看>>
list control控件的一些操作
查看>>