Fragment和viewpager结合去网络获取图片

里面主要能用到FragmentPagerAdapter和viewPager、Fragment、联网去图片、异步加载、lruCache内存缓存这些知识、其实还可以加上自定义接口回调的,但是我直接把显示图片的ImageView传进去了就没用回调的方法了,首先我们要清楚的是,每次滑动时更换只是图片,而不是我们的Fragment所以,每次滑动时,我们只需要去更换图片的地址异步加载就可以了,

主界面里面布局就一个ViewPager就行,由于是V4包的,所以需要提前导包啊什么的,就是写包名麻烦点:

布局如下:

<?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" >

    <android.support.v4.view.ViewPager
        android:id="@+id/fragment_viewpager_http"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


然后是我的主界面:

<pre class="html" name="code">public class ImgViewpagerFragment extends FragmentActivity {
	private ViewPager mViewPager;
	//String数组里面放的都是图片的地址
	private String[] str = {
	};
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.fragmentviewpager_http_img_layout);
		
		mViewPager = (ViewPager) findViewById(R.id.fragment_viewpager_http);
		
		//FragmentPagerAdapter适配器
		MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
		mViewPager.setAdapter(adapter);
		adapter.setData(str);
		
	}

 

图片的地址可以百度搜索很多。直接COPY添加就行,主类里面很简单,没什么复杂的东西,

下面就是我们的适配器:

	public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
		private String[] imgUrl = new String[] {};

		public MyFragmentPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		public void setData(String[] imgUrls) {
			imgUrl = imgUrls;
			notifyDataSetChanged();
		}

		public int getCount() {
			return imgUrl.length;
		}

		public Fragment getItem(int arg0) {
			return ImgHttpFramentActivity.newFragment(imgUrl[arg0]);
		}

	}


适配器采用内部类的写法去实现的,里面和上一篇主要变化时,我把Fragment写死了,因为之前说了,变的是图片,所以只需要更换图片的地址显示在我们的Fragment上面就可以,而不是变Fragment。

下面是Fragment的类:

public class ImgHttpFramentActivity extends Fragment {
	private ImageView mImageView;
	private static String IMG_KEY = "IMG_URL";
	
	/**
	 * 传入图片的地址
	 * @param imgString
	 * @return
	 */
	public static ImgHttpFramentActivity newFragment(String imgString) {
		ImgHttpFramentActivity mImgHttpFramentActivity = new ImgHttpFramentActivity();
		Bundle bund = new Bundle();
		bund.putString(IMG_KEY, imgString);

		mImgHttpFramentActivity.setArguments(bund);
		return mImgHttpFramentActivity;
	}
	/**
	 * 加载我们的布局
	 */
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		return inflater.inflate(R.layout.img_http_fragment_pageradapter_layout,
				container, false);
	}
	/**
	 * 实例化控件、取获取图片的地址操作
	 */
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		mImageView = (ImageView) getView().findViewById(
				R.id.http_img_fragment_viewpager);
		
		Bundle bund = getArguments();
		String url = bund.getString(IMG_KEY);		
		new HttpImg(url,mImageView);
	}

}


相信这里面都能看懂,也没什么难度的;下面解释这一行代码:new HttpImg(url,mImageView);,这是我自己封装的一个类,里面主要进行联网去图片、异步加载、LruCache内存缓存图片,都很简单,下面是里面的代码:

public class HttpImg {
	private String mUrlImg;
	private LruCache<String, Bitmap> mLruCache;
	ImageView mImageView;
	/**
	 * 主要进行实例化LruCache和地址的传递
	 * @param urlImg
	 * @param imageView
	 */
	public HttpImg(String urlImg, ImageView imageView) {
		mUrlImg = urlImg;
		mImageView = imageView;
		
		saveImgStorage();
	}

	/**
	 * 获取内存空间给下载好的图片
	 */
	public void saveImgStorage() {
		//获取当前外部可用内存的大小
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		//去当前内存大小的8分之1来缓存我们的内存
		int useSize = maxMemory / 8;
		mLruCache = new LruCache<String, Bitmap>(useSize) {
			@Override
			protected int sizeOf(String key, Bitmap value) {
				return value.getByteCount();
			}
		};
                 //实例化完LruCache就调用我们的开启异步任务方法
		startAsynctaskGetImg(mUrlImg);
	}

	/**
	 * 添加图片到缓存
	 * 
	 * @param mapKey
	 * @param bitmap
	 */
	public void addBitmapToLrucache(String mapKey, Bitmap bitmap) {
		//先根据地址判断我们的存储空间是否有这张图片,有就不会返回空,就不添加
		if (getBitmapForLruCache(mapKey) == null) {
			mLruCache.put(mapKey, bitmap);
		}
	}

	/**
	 * 从缓存去图片
	 * 
	 * @param mapurl
	 * @return
	 */
	public Bitmap getBitmapForLruCache(String mapurl) {
		return mLruCache.get(mapurl);

	}
	/**
	 * 加载我们的图片,先去内存缓存里卖弄判断是否有这张图片,没有再去开启异步任务获取图片
	 * @param urls
	 */
	public void startAsynctaskGetImg(String urls) {
	
		Bitmap bitmapss = getBitmapForLruCache(urls);
		if (bitmapss != null) {
			mImageView.setImageBitmap(bitmapss);

			return;
		} else {

			new AsyncTask<String, Void, Bitmap>() {

				protected Bitmap doInBackground(String... params) {
					Bitmap bitmap = getHttpGetImg(params[0]);
					return bitmap;
				}

				protected void onPostExecute(Bitmap result) {
					super.onPostExecute(result);
					//显示在我们传进来的imageview控件上
					mImageView.setImageBitmap(result);
					//将图片加入到我们的缓存处
					addBitmapToLrucache(mUrlImg, result);
				}
			}.execute(urls);
		}
	}
	/**
	 * 联网获取图片
	 * @param urls
	 * @return
	 */
	public Bitmap getHttpGetImg(String urls) {
		InputStream input = null;
		try {
			URL url = new URL(urls);
			input = url.openStream();
			Bitmap bitmap = BitmapFactory.decodeStream(input);
			return bitmap;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
}

我没有加文件缓存,有想法可以加一下,这个类先实例化LruCache:最近最少使用,在程序内存达到设定值时会将最少最近使用的图片移除掉。主要就是判断图片是否已经存在,没有的话我们再去加载网络图片,来一张效果图:


 

如果你想加个progressBar就要采用接口的回调方法,这里我就没写了,很简单的一个写法,就是自己定义一个接口,但是不实现这个接口,只是调用它的方法,然后用Fragment去实现那个接口,然后在接口的方法里面去隐藏或显示你的progressBar,当然一个是开始网络去图片前用一个接口方法,取完再用一个接口方法就OK了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值