GridView的三级缓存

1.三级缓存的代码。
public class PhotoWallAdapter extends BaseAdapter implements OnScrollListener {

	private List<Costume> listCostumes;
	private Activity mActivity;
	private String path;
	/**
	 * 记录所有正在下载或等待下载的任务。
	 */
	private Set<BitmapWorkerTask> taskCollection;

	/**
	 * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。
	 */
	private LruCache<String, Bitmap> mMemoryCache;

	/**
	 * GridView的实例
	 */
	private GridView mPhotoWall;

	/**
	 * 第一张可见图片的下标
	 */
	private int mFirstVisibleItem;

	/**
	 * 一屏有多少张图片可见
	 */
	private int mVisibleItemCount;

	/**
	 * 记录是否刚打开程序,用于解决进入程序不滚动屏幕,不会下载图片的问题。
	 */
	private boolean isFirstEnter = true;

	@SuppressLint("NewApi")
	public PhotoWallAdapter(Activity mActivity,List<Costume> listCostume,String path,
			GridView photoWall) {
		this.mActivity=mActivity;
		this.mPhotoWall = photoWall;
		this.listCostumes=listCostume;
		this.path=path;
		taskCollection = new HashSet<BitmapWorkerTask>();
		// 获取应用程序最大可用内存
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 8;
		// 设置图片缓存大小为程序最大可用内存的1/8
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@SuppressLint("NewApi")
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}
		};
		this.mPhotoWall.setOnScrollListener(this);
	}
	public void initData(List<Costume> listCostume){
		this.listCostumes=listCostume;
	}
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder=null;
		if(convertView==null){
		 viewHolder=new ViewHolder();
		 convertView=LayoutInflater.from(mActivity).inflate(R.layout.item,null);
		 viewHolder.detail=(TextView) convertView.findViewById(R.id.grid_tv_detail);
		 viewHolder.dollar=(TextView) convertView.findViewById(R.id.grid_tv_dollar);
		 viewHolder.iv=(ImageView) convertView.findViewById(R.id.iv_gridId);
		 convertView.setTag(viewHolder);
		}else{
		 viewHolder=(ViewHolder) convertView.getTag();	
		}
		viewHolder.detail.setText("【超值惠】"+listCostumes.get(position).getDetail());
		viewHolder.dollar.setText("$"+listCostumes.get(position).getPrice());
		String imagePath=listCostumes.get(position).getImageUrl();
		viewHolder.iv.setImageResource(R.drawable.ic_launcher);
		// 给ImageView设置一个Tag,保证异步加载图片时不会乱序
		viewHolder.iv.setTag(imagePath);
		setImageView(imagePath,viewHolder.iv);
		return convertView;
	}

	/**
	 * 给ImageView设置图片。首先从LruCache中取出图片的缓存,设置到ImageView上。如果LruCache中没有该图片的缓存,
	 * 就给ImageView设置一张默认图片。
	 * 
	 * @param imageUrl
	 *            图片的URL地址,用于作为LruCache的键。
	 * @param imageView
	 *            用于显示图片的控件。
	 */
	private void setImageView(String imageUrl, ImageView imageView) {
		Bitmap bitmapCache = getBitmapFromMemoryCache(imageUrl);
		if (bitmapCache != null) {
			imageView.setImageBitmap(bitmapCache);
		}else {
			imageView.setImageResource(R.drawable.empty_photo);
		}
	}

	/**
	 * 将一张图片存储到LruCache中。
	 * 
	 * @param key
	 *            LruCache的键,这里传入图片的URL地址。
	 * @param bitmap
	 *            LruCache的键,这里传入从网络上下载的Bitmap对象。
	 */
	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemoryCache(key) == null) {
			mMemoryCache.put(key, bitmap);
		}
	}

	/**
	 * 从LruCache中获取一张图片,如果不存在就返回null。
	 * 
	 * @param key
	 *            LruCache的键,这里传入图片的URL地址。
	 * @return 对应传入键的Bitmap对象,或者null。
	 */
	public Bitmap getBitmapFromMemoryCache(String key) {
		return mMemoryCache.get(key);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// 仅当GridView静止时才去下载图片,GridView滑动时取消所有正在下载的任务
		if (scrollState == SCROLL_STATE_IDLE) {
			loadBitmaps(mFirstVisibleItem, mVisibleItemCount);
		} else {
			cancelAllTasks();
		}
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
			int totalItemCount) {
		mFirstVisibleItem = firstVisibleItem;
		mVisibleItemCount = visibleItemCount;
		// 下载的任务应该由onScrollStateChanged里调用,但首次进入程序时onScrollStateChanged并不会调用,
		// 因此在这里为首次进入程序开启下载任务。
		if (isFirstEnter && visibleItemCount > 0) {
			loadBitmaps(firstVisibleItem, visibleItemCount);
			isFirstEnter = false;
		}
	}

	/**
	 * 加载Bitmap对象。此方法会在LruCache中检查所有屏幕中可见的ImageView的Bitmap对象,
	 * 如果发现任何一个ImageView的Bitmap对象不在缓存中,就会开启异步线程去下载图片。
	 * 
	 * @param firstVisibleItem
	 *            第一个可见的ImageView的下标
	 * @param visibleItemCount
	 *            屏幕中总共可见的元素数
	 */
	private void loadBitmaps(int firstVisibleItem, int visibleItemCount) {
		try {
			for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) {
				String imageUrl =listCostumes.get(i).getImageUrl();
				Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
				ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl);
				if (bitmap == null) {
					String imageName = "";
					if (imageUrl != null) {
						imageName = Util.getInstance().getImageName(imageUrl);
					}
				  if(imageView != null && imageUrl.equals(imageView.getTag())) {
					Bitmap bitmapfile = getBitmapFromFile(mActivity, imageName, path);
					if (bitmapfile != null) {
						imageView.setImageBitmap(bitmapfile);
					}else{
					 BitmapWorkerTask task = new BitmapWorkerTask();
					 taskCollection.add(task);
					 task.execute(imageUrl);						
					}
				  }
				} else {
					if (imageView != null && bitmap != null) {
						imageView.setImageBitmap(bitmap);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 取消所有正在下载或等待下载的任务。
	 */
	public void cancelAllTasks() {
		if (taskCollection != null) {
			for (BitmapWorkerTask task : taskCollection) {
				task.cancel(false);
			}
		}
	}

	/**
	 * 异步下载图片的任务。
	 * 
	 * @author guolin
	 */
	class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

		/**
		 * 图片的URL地址
		 */
		private String imageUrl;

		@Override
		protected Bitmap doInBackground(String... params) {
			imageUrl = params[0];
			// 在后台开始下载图片
			Bitmap bitmap = downloadBitmap(params[0]);
			if (bitmap != null) {
				String imageName = Util.getInstance().getImageName(imageUrl);  
				if(!setBitmapToFile(path,mActivity,imageName,bitmap)){
					removeBitmapFromFile(imageName, mActivity, imageName);
				}
				// 图片下载完成后缓存到LrcCache中
				addBitmapToMemoryCache(params[0], bitmap);
			}
			return bitmap;
		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			super.onPostExecute(bitmap);
			// 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
			ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl);
			if (imageView != null && bitmap != null) {
				imageView.setImageBitmap(bitmap);
			}
			taskCollection.remove(this);
		}

		/**
		 * 建立HTTP请求,并获取Bitmap对象。
		 * 
		 * @param imageUrl
		 *            图片的URL地址
		 * @return 解析后的Bitmap对象
		 */
		private Bitmap downloadBitmap(String imageUrl) {
			Bitmap bitmap = null;
			HttpURLConnection con = null;
			try {
				URL c_url = new URL(imageUrl);
				InputStream bitmap_data = c_url.openStream();
				bitmap = BitmapFactory.decodeStream(bitmap_data);				
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (con != null) {
					con.disconnect();
				}
			}
			return bitmap;
		}

	}
	 public class ViewHolder{
		    ImageView iv;
			TextView detail;
			TextView dollar;
	   }
	@Override
	public int getCount() {
		return listCostumes.size();
	}
	@Override
	public Object getItem(int arg0) {
		return listCostumes.get(arg0);
	}
	@Override
	public long getItemId(int arg0) {
		return arg0;
	}
	/** 
     * 从文件中拿图片 
     * @param mActivity  
     * @param imageName 图片名字 
     * @param path 图片路径 
     * @return 
     */  
    private Bitmap getBitmapFromFile(Activity mActivity,String imageName,String path){  
        Bitmap bitmap = null;  
        if(imageName != null){  
            File file = null;  
            String real_path = "";  
            try {  
                if(Util.getInstance().hasSDCard()){  
                    real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);  
                }else{  
                    real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);  
                }  
                file = new File(real_path, imageName);  
                if(file.exists())  
                bitmap = BitmapFactory.decodeStream(new FileInputStream(file));  
            } catch (Exception e) {  
                e.printStackTrace();  
                bitmap = null;  
            }  
        }  
        return bitmap;  
    } 
    /** 
     * 将下载好的图片存放到文件中 
     * @param path 图片路径 
     * @param mActivity 
     * @param imageName 图片名字 
     * @param bitmap 图片 
     * @return 
     */  
    private boolean setBitmapToFile(String path,Activity mActivity,String imageName,Bitmap bitmap){  
        File file = null;  
        String real_path = "";  
        try {  
            if(Util.getInstance().hasSDCard()){  
                real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);  
            }else{  
                real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);  
            }  
            file = new File(real_path, imageName);  
            if(!file.exists()){  
                File file2 = new File(real_path + "/");  
                file2.mkdirs();  
            }  
            file.createNewFile();  
            FileOutputStream fos = null;  
            if(Util.getInstance().hasSDCard()){  
                fos = new FileOutputStream(file);
            }else{  
                fos = mActivity.openFileOutput(imageName, Context.MODE_PRIVATE);  
            }  
              
            if (imageName != null && (imageName.contains(".png") || imageName.contains(".PNG"))){  
                bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);  
            }  
            else{  
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);  
            }  
            fos.flush();  
            if(fos != null){  
                fos.close();  
            }  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
    /** 
     * 辅助方法,一般不调用 
     * @param path 
     * @param mActivity 
     * @param imageName 
     */  
    private void removeBitmapFromFile(String path,Activity mActivity,String imageName){  
        File file = null;  
        String real_path = "";  
        try {  
            if(Util.getInstance().hasSDCard()){  
                real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);  
            }else{  
                real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);  
            }  
            file = new File(real_path, imageName);  
            if(file != null)  
            file.delete();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}
2.自定义的PagerAdapter的
public class FragmentViewPagerAdapter extends PagerAdapter implements
		OnPageChangeListener {
  
	private List<Fragment> listFragments;
	private FragmentManager fragmentmanager;
	private ViewPager viewPagr;
	private int currentIndex=0;
	private OnExtraPageChangeListener mOnExtraPageChangeListener;
	public FragmentViewPagerAdapter(FragmentManager fragmentmanager,List<Fragment> listFragments,ViewPager viewpager){
	    this.fragmentmanager=fragmentmanager;
		this.listFragments=listFragments;
		this.viewPagr=viewpager;
		this.viewPagr.setAdapter(this);
		this.viewPagr.setOffscreenPageLimit(0);
		this.viewPagr.setOnPageChangeListener(this);
	}
	
	
	@Override
	public void onPageScrollStateChanged(int state) {


	}


	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {


	}


	@Override
	public void onPageSelected(int pageindex) {
     listFragments.get(currentIndex).onPause();
     if(listFragments.get(pageindex).isAdded()){
    	 listFragments.get(pageindex).onResume();
     }
     currentIndex=pageindex;
     if(null!=mOnExtraPageChangeListener){
    	 mOnExtraPageChangeListener.onExtraPageSelected(pageindex);
     }
	}


	@Override
	public int getCount() {
		return listFragments.size();
	}


	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0==arg1;
	 }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
    	container.removeView(listFragments.get(position).getView());
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    	Fragment fg=listFragments.get(position);
    	if(!fg.isAdded()){
    		android.support.v4.app.FragmentTransaction ft=fragmentmanager.beginTransaction();
    		ft.add(fg,ft.getClass().getSimpleName());
    		ft.commit();
    		fragmentmanager.executePendingTransactions();
    	}
    	if(fg.getView().getParent()==null){
    		container.addView(fg.getView());
    	}
    	return fg.getView();
    }
    public interface  OnExtraPageChangeListener{
        public void onExtraPageScrolled(int i, float v, int i2);
        public void onExtraPageSelected(int i);
        public void onExtraPageScrollStateChanged(int i);
    }
	public OnExtraPageChangeListener getmOnExtraPageChangeListener() {
		return mOnExtraPageChangeListener;
	}




	public void setmOnExtraPageChangeListener(
			OnExtraPageChangeListener mOnExtraPageChangeListener) {
		this.mOnExtraPageChangeListener = mOnExtraPageChangeListener;
	}
    
}
3.这是一个FragmentHot
public class FragmentHot extends Fragment {


	private ProgressDialog progress;
	private List<Costume> list=new ArrayList<Costume>();
	private PullToRefreshGridView RefresGridView;
	private GridView mGridView;
	//private GridAdapter adapter=null;
	private PhotoWallAdapter mPhotoWallAdapter;
	private int pageindex=1;
	private Downinfo mDowninfo=null;
	@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
		Bundle savedInstanceState) {
	View view=inflater.inflate(R.layout.grid_item,container,false);
	RefresGridView=(PullToRefreshGridView) view.findViewById(R.id.grid_address);
	mGridView=RefresGridView.getRefreshableView();
	//adapter=new GridAdapter(list,getActivity(),mGridView,"textGridview");
	mPhotoWallAdapter=new PhotoWallAdapter(getActivity(),list,"textjjr",mGridView);
	progress=new ProgressDialog(getActivity());
	progress.setTitle("温馨提示");
	progress.setMessage("正在努力加载....");
	progress.show();
	mGridView.setAdapter(mPhotoWallAdapter);
	mDowninfo=new Downinfo();
	mDowninfo.start();
	RefresGridView.setOnRefreshListener(new OnRefreshListener2<GridView>() {


		@Override
		public void onPullDownToRefresh(PullToRefreshBase<GridView> refreshView) {
			RefresGridView.onRefreshComplete();
		}


		@Override
		public void onPullUpToRefresh(PullToRefreshBase<GridView> refreshView) {
		 pageindex++;
		 Downinfo f=new Downinfo();
		 f.start();
		}
	});
	return view;
}
public class Downinfo extends Thread{
	@Override
	public void run() {
	 String result=HttpUtils.getString(CommUtils.HOTPANT_PATH+pageindex);
	 list.addAll(HttpUtils.getData(result));
	 handler.post(new Runnable() {
		
		@Override
		public void run() {
		mPhotoWallAdapter.initData(list);
        mPhotoWallAdapter.notifyDataSetChanged();
		RefresGridView.onRefreshComplete();
		progress.dismiss();
		}
	});
	}
}
public Handler handler=new Handler(){
	public void handleMessage(android.os.Message msg) {
		
	};
};
@Override
public void onResume() {
	super.onResume();
}
@Override
public void onPause() {
	super.onPause();
	if(mDowninfo!=null){
		mDowninfo.interrupt();		
	}
}
}
4.MainActivity
public class MainActivity extends FragmentActivity {
    
	private TextView tv1,tv2,tv3,tv4;
	private ViewPager viewPager;
	private List<Fragment> pageViews;
	private List<TextView> tvs=new ArrayList<TextView>();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		initWidget();
		FragmentViewPagerAdapter fviewPagerAdapter=new FragmentViewPagerAdapter(getSupportFragmentManager(),pageViews,viewPager);	   
	    fviewPagerAdapter.setmOnExtraPageChangeListener(new OnExtraPageChangeListener() {
			
			@Override
			public void onExtraPageSelected(int i) {
				if(i==1){
					FragmentJeans j=(FragmentJeans) pageViews.get(i);
					j.LoadData();
				}else if(i==2){
					FragmentLeggings l=(FragmentLeggings) pageViews.get(i);
					l.LoadData();
				}else if(i==3){
					FragmentRela r=(FragmentRela) pageViews.get(i);
					r.LoadData();
				}
			}
			
			@Override
			public void onExtraPageScrolled(int i, float v, int i2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onExtraPageScrollStateChanged(int i) {
				// TODO Auto-generated method stub
				
			}
		});
	}
	public void initWidget(){
		tv1=(TextView) findViewById(R.id.tv1_paint_title);
		tv2=(TextView) findViewById(R.id.tv2_paint_title);
		tv3=(TextView) findViewById(R.id.tv3_paint_title);
		tv4=(TextView) findViewById(R.id.tv4_paint_title);
		viewPager=(ViewPager) findViewById(R.id.vp_pant);
		pageViews=new ArrayList<Fragment>();
		FragmentHot fHot=new FragmentHot();
		FragmentJeans fJeans=new FragmentJeans();
		FragmentLeggings fLeggings=new FragmentLeggings();
		FragmentRela fRela=new FragmentRela();
		pageViews.add(fHot);
		pageViews.add(fJeans);
		pageViews.add(fLeggings);
		pageViews.add(fRela);
	}
}

5.布局文件中使用到第三方的类库(是GridView的下拉刷新)不再提供

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
<LinearLayout 
    android:id="@+id/linearTitle"
    android:layout_width="match_parent"
    android:layout_height="35dp"
    android:gravity="center"
    android:orientation="horizontal"
    >
 <TextView
     android:id="@+id/tv1_paint_title"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:background="#ee0e65"
     android:gravity="center"
     android:text="热裤"
     />
<TextView
     android:id="@+id/tv2_paint_title"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:gravity="center"
     android:text="打底裤"
     />
 <TextView
     android:id="@+id/tv3_paint_title"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:gravity="center"
     android:text="休闲裤"
     />
<TextView
     android:id="@+id/tv4_paint_title"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:gravity="center"
     android:text="牛仔裤"
     />
</LinearLayout>
<android.support.v4.view.ViewPager
    android:id="@+id/vp_pant"
    android:layout_below="@id/linearTitle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
</android.support.v4.view.ViewPager>
</RelativeLayout>

<?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:orientation="vertical" >
     <com.handmark.pulltorefresh.library.PullToRefreshGridView
        xmlns:ptr="http://schemas.android.com/apk/res-auto"
        android:id="@+id/grid_address"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:numColumns="2"
        android:verticalSpacing="1dp"
        android:horizontalSpacing="1dp"
        android:columnWidth="100dp"
        android:stretchMode="columnWidth"
        android:gravity="fill"
        ptr:ptrMode="both"
        ptr:ptrDrawable="@drawable/default_ptr_rotate" />
</LinearLayout>

<?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:orientation="vertical" >
  <ImageView
      android:id="@+id/iv_gridId"
      android:layout_width="100sp"
      android:layout_height="100sp"
      android:scaleType="fitXY"
      android:layout_marginLeft="10sp"
      android:src="@drawable/ic_launcher"
      />
  <TextView
      android:id="@+id/grid_tv_detail"
      android:layout_width="100sp"
      android:layout_height="wrap_content"
       android:textSize="12sp"
       android:text="超值惠"
      android:lines="2"
      android:ellipsize="end"
      />
  <TextView
      android:id="@+id/grid_tv_dollar"
      android:layout_width="100sp"
      android:layout_height="25sp"
      android:textColor="#fd6185"
      android:textSize="15sp"
      android:text="$ 298"      
      />


</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值