zoukankan      html  css  js  c++  java
  • 10. 面向holder编程、自动轮询

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

    BaseHolder 

    1. public abstract class BaseHolder<Data>  {//写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<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;
      	
      	/**当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<Data> extends BaseAdapter {
      	protected List<Data> datas;
      	private static final int DEFAULT_ITEM = 0;
      	private static final int MORE_ITEM = 1;
      	public List<Data> getDatas() {
      		return datas;
      	}
      	public void setDatas(List<Data> datas) {
      		this.datas = datas;
      	}
      	public DefaultAdapter(List<Data> 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<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();
      }
     
    修改8的代码SubjectFragment
    1. public class SubjectFragment extends BaseFragment {
      	private List<SubjectInfo> datas;
      	@Override
      	public View createSuccessView() {
      		BaseListView  listView=new BaseListView  (UiUtils.getContext());
      		listView.setAdapter(new SubjectAdapter(datas));
      		return listView;
      	}
      	private class SubjectAdapter extends DefaultAdapter<SubjectInfo>{
      		public SubjectAdapter(List<SubjectInfo> datas) {
      			super(datas);
      		}
      		@Override
      		protected BaseHolder<SubjectInfo> getHolder() {
      			return new SubjectHolder();
      		}
      		@Override
      		protected List<SubjectInfo> onload() {
      			SubjectProtocol protocol=new SubjectProtocol();
      			List<SubjectInfo> load = protocol.load(0);
      			datas.addAll(load);
      			return load;
      		}
      	}
      	class SubjectHolder extends BaseHolder<SubjectInfo>{
      		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<AppInfo> {
    	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<AppInfo> {
      	public ListBaseAdapter(List<AppInfo> datas) {
      		super(datas);
      	}
      	@Override
      	protected BaseHolder<AppInfo> getHolder() {
      		return new ListBaseHolder();
      	}
      	@Override
      	protected abstract List<AppInfo> onload();
      	
      }
    GameFragment 
    public class GameFragment extends BaseFragment {
    	private List<AppInfo> datas;
    	/**
    	 * 加载成功的界面
    	 */
    	@Override
    	public View createSuccessView() {
    		BaseListView  listView=new BaseListView(UiUtils.getContext());
    		listView.setAdapter(new ListBaseAdapter(datas){
    			@Override
    			protected List<AppInfo> onload() {
    				GameProtocol protocol=new GameProtocol();
    				List<AppInfo> 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<AppInfo> datas;
    	/**
    	 * 当加载成功的时候 显示的界面
    	 */
    	@Override
    	public View createSuccessView() {
    		BaseListView  listView=new BaseListView(UiUtils.getContext());
    		listView.setAdapter(new ListBaseAdapter(datas){
    			@Override
    			protected List<AppInfo> onload() {
    				AppProtocol protocol=new AppProtocol();
    				List<AppInfo> 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<List<String>> {
    	/* 当new HomePictureHolder()就会调用该方法 */
    	private ViewPager viewPager;
    	private List<String> 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<String> 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<ImageView> convertView=new LinkedList<ImageView>();
    		// 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
       <dimen name="home_picture_height">134dp</dimen>	
      public static int getDimens(int homePictureHeight) {
      		return (int) getResource().getDimension(homePictureHeight);
      	}
     
    HomeFragment 
    public class HomeFragment extends BaseFragment {
    	private List<AppInfo> datas;
    	private List<String> 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<AppInfo> onload() {
    				HomeProtocol protocol=new HomeProtocol();
    				List<AppInfo> 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<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) {
      		
      	}
     
    面向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的上面



  • 相关阅读:
    table变宽格式
    IE11兼容性设定
    Spring AOP注解失效的坑及JDK动态代理
    关于何时执行shiro AuthorizingRealm 里的 doGetAuthenticationInfo与doGetAuthorizationInfo
    后端接收json数据交互
    关于JavaDate数据返回到前端变数字的问题(并引申到前后端时间的传输)
    git 列出两个分支 或者两个提交版本之间不同的文件名字
    map put相同的key
    MyBatis 中如何调用 Java 的 enum (枚举) 字段
    @ResponseBody 和 @RequestBody 的作用
  • 原文地址:https://www.cnblogs.com/sixrain/p/4972607.html
Copyright © 2011-2022 走看看