3DGallery图库
一、倒影、遮罩、渐变、抗锯齿、合成1、定义一个类
CustomeGallery继承Gallery 2、将资源图片转成Bitmap 3、进行翻转,合成,保存到一个List 4、通过ListView展示出来 5、代码: ImageAdapter.java
|
二、变形 CustomeGallery.java package cn.zengfansheng.customeGallery.view;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;
/**
* 自定义的Gallery
* @author hacket
*/
@SuppressWarnings("deprecation")
public class CustomeGallery extends Gallery {
private int currentCenterOfGallery;// 展示图片的中心点
public CustomeGallery(Context context, AttributeSet attrs) {
super(context, attrs);
setStaticTransformationsEnabled(true);// 可以转化(变形)
}
public CustomeGallery(Context context,int[] imageIds) {
super(context);
setStaticTransformationsEnabled(true);// 可以转化(变形)
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
currentCenterOfGallery = getCurrentCenterOfGallery();
}
// 1、获取grallery展示图片的中心点
public int getCurrentCenterOfGallery(){
// (grallery宽度-左边paddingLeft-右边paddingRigth)/2+左边paddingLeft
// getLeft()+getWidth()/2;
return (getWidth()-getPaddingLeft()-getPaddingRight())/2+getPaddingLeft();
}
// 2、获取图片的中心点
public int getCurrentCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
// 3、
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
// 得到图片的中心点
int currentOfChild = getCurrentCenterOfView(child);
int childHeight = child.getLayoutParams().height;
int childWidth = child.getLayoutParams().width;
int rotateAngle = 0;// 旋转的角度
t.clear();// 清理之前的转换
// 图片变形的风格样式
t.setTransformationType(Transformation.TYPE_MATRIX);
if (currentOfChild == currentCenterOfGallery) {
// 是中心位置,旋转角度为0
transformationBitmap((ImageView) child, t, 0);
} else {
// 不是中心位置
rotateAngle = (int) ((float)(currentCenterOfGallery - currentOfChild) /childWidth * maxRotateAngle);
if(Math.abs(rotateAngle) > maxRotateAngle){//旋转角度绝对值大于最大等于maxRotateAngle
rotateAngle = rotateAngle < 0 ? -maxRotateAngle : maxRotateAngle;
}
transformationBitmap((ImageView) child, t, rotateAngle);
}
return true;
}
private Camera camera = new Camera();
private int maxZoom = -250;//最大缩放值
private int maxRotateAngle = 50;//最大旋转角度
// 图片变形
private void transformationBitmap(ImageView child,Transformation t,int rotateAngle){
camera.save();//保存
Matrix imageMatrix = t.getMatrix();
int rotate = Math.abs(rotateAngle);
int imageWidth = child.getWidth();
int imageHeight = child.getHeight();
//z轴 正数 图片放大
//x水平移动, y垂直移动
camera.translate(0.0f, 0.0f, 100.0f);
if (rotate < maxRotateAngle) {
float zoom = (float) ((rotate * 1.5) + maxZoom);
camera.translate(0.0f, 0.0f, zoom);
child.setAlpha((int) (255 - rotate * 2.5));
}
// 图片向展示中心 进行垂直角度的旋转
camera.rotateY(rotateAngle);
camera.getMatrix(imageMatrix);
// Preconcats matrix相当于右乘矩阵
// Postconcats matrix相当于左乘矩阵。
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
camera.restore();// 还原
}
} |
|
OOM问题:如果加载的图片过多,内存会溢出,程序崩溃 使用软引用 SoftReference()来包裹ImageView |
System.gc() 通知垃圾回收器回收垃圾 问题1:每次都要暂停那么几十ms(看log) 问题2:只是显示说明要调用垃圾回收器来回收垃圾,但并不能保证立刻就运行垃圾回收器来回收垃圾 Indicates to the VM that it would be a good time to run the garbage collector. Note that this is a hint only. There is no guarantee that the garbage collector will actually be run. |
解决OOM问题:如果加载的图片过多,会导致OOM溢出 解决:使用软引用SoftReference, a) new出来一个map用来存储软引用对象 private Map<Integer, SoftReference<ImageView>> map = new HashMap<Integer, SoftReference<ImageView>>(); b)将ImageView对象存储到软引用中去 public void intiImageView(){
for (int i = 0; i < imageIds.length; i++) {
// 通过id获取倒影合成的ImageView
ImageView invertImageView = getInvertImage(imageIds[i]);
// 用一个软引用关联该倒影ImageView
SoftReference<ImageView> softReferenceIV = new SoftReference<ImageView>(invertImageView);
// 将该软引用加到map中去
map.put(i, softReferenceIV);
}
} c) 从软引用中获取ImageView,get(),如果返回null,说明已经被垃圾回收器给回收了, 不为null的话,那么为该ImageView对象 // 从集合中获取指定位置的软引用
SoftReference<ImageView> ivSoftReference = map.get(position);
// 获取该软引用引用的对象
ImageView imageView = ivSoftReference.get();//得到所引用的对象,如果为null,表示已经被垃圾回收器回收
if (imageView == null) {// 如果为null,说明已经被回收,那么重新创建一个
Log.i(TAG, "回收对象:"+position);
imageView = getInvertImage(imageIds[position]);
}
// 否则,用该软引用所引用的对象
return imageView; 结果: 可以看到,当到了15后,14,13直接从软引用中get()数据了,而不是重新创建对象 |