里面主要能用到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了。