在原来的基础上再优化一下,当加载完48张图(大部分720P以上的)片以后,我的机器是使用的31.923M的内存,
在这里请先看博客:http://blog.csdn.net/guolin_blog/article/details/9316683
那个博客上面的方法是很实用的,可以节省很多内存,因此在原来的基础上修改setImageVIew的方法:
修改
Activity的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageLoader = new ImageLoader();
initViews();
}
</pre><pre class="java" name="code"> mViewPager.setAdapter(new ViewPagerAdapter(MainActivity.this, mImageLoader));
ViewPagerAdapter的
public ViewPagerAdapter(Context context, ImageLoader imageLoader){
mContext = context;
mImageLoader = imageLoader;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
int index = position % DataConfig.ALL_IMAGE_IDS.length;
int id = DataConfig.ALL_IMAGE_IDS[index];
View view = null;
view = LayoutInflater.from(mContext).inflate(R.layout.details, null);
ImageView imageView = (ImageView)view.findViewById(R.id.image);
// imageView.setImageResource(id);
Bitmap bitmap = mImageLoader.decodeSampledBitmapFromResource(mContext.getResources(), id,
400, 300);
imageView.setImageBitmap(bitmap);
container.addView(view);
return view;
}
ImageLoader的源码:
public class ImageLoader {
public static ImageLoader mImageLoader = null;
private static LruCache<String , Bitmap> mMemCache;
public ImageLoader(){
int maxMemory = (int)Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
mMemCache = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
public static ImageLoader getInstance(){
if (null == mImageLoader){
mImageLoader = new ImageLoader();
}
return mImageLoader;
}
public Bitmap getBitmapFromMemoryCache(String key){
return mMemCache.get(key);
}
public void addBitmapFromMemoryCache(String key , Bitmap bitmap){
if (null == getBitmapFromMemoryCache(key)){
mMemCache.put(key, bitmap);
}
}
public Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/** 完成没有意义 options.inSampleSize = 1; 跟直接使用setImageBitmap 使用内存大少一样 */
public Bitmap decodeSampledBitmapFromResource(Resources res, int resId
) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = 1;
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 源图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String pathName,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth , reqHeight);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}
}
就只有现在我机器的使用内存为 11.141M,当然是我设置的太少了 Bitmap bitmap = mImageLoader.decodeSampledBitmapFromResource(mContext.getResources(), id,
400, 300); 这个因人而异,需求而定,我这里只是引导大家使用这个方法!
接下来给我们的图片翻页时加一点效果,就要使用到ViewPager.PageTransformer这个类:
加上代码// mViewPager.setPageTransformer(true, new ZoomOutPageTransformer()) ;
mViewPager.setPageTransformer(true, new DepthPageTransformer()) ;
DepthPageTransformer 跟 ZoomOuDepthPageTransformer 是官方提供的滑动效果:
先看DepthPageTransformer 效果如下:
ZoomOutPageTransformer 的效果如下:
代码
public class DepthPageTransformer implements PageTransformer {
private static float MIN_SCALE = 0.75f;
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
Log.d("dd", "position:"+position);
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when
// moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE)
* (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.2f;
public void transformPage(View view, float position)
{
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
Log.d("dd",view.getTag()+" position:"+position);
if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1] // Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
}
else {
view.setTranslationX(-horzMargin + vertMargin / 2);
} // Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor); // Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +(scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity] // This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
在public void transformPage(View view, float position) 这个方法中
view 是当前view 或者是下一个view,那个position是float的类型,解析一下,可以加打印可以看到
position 是在滑动过程是是变化的
增加log调试 在view都加上tag ,
Override
public Object instantiateItem(ViewGroup container, int position) {
int index = position % DataConfig.ALL_IMAGE_IDS.length;
int id = DataConfig.ALL_IMAGE_IDS[index];
View view = null;
view = LayoutInflater.from(mContext).inflate(R.layout.details, null);
// 加上TAG
view.setTag(index);
ImageView imageView = (ImageView)view.findViewById(R.id.image);
// imageView.setImageResource(id);
Bitmap bitmap = mImageLoader.decodeSampledBitmapFromResource(mContext.getResources(), id,
400, 300);
imageView.setImageBitmap(bitmap);
container.addView(view);
return view;
}
看log
仔细观察从滑动到最后停止
view 当前页跟下一页交替打印的
可以理解为最左上角为 0.0放位置, 所有的view的 宽度都是为1的
那么往左边滑动时当前页position就是 当前页左上角相对于 0.0的位移 , 下一个的position,下一页的左定点相对对0.0放位移
所有滑动到一半时 前一页就是-0.5 , 下一页就是0.5
滑动结束时就是 -1.0 跟0
下载地址:http://download.csdn.net/detail/hewence1/7848639