CustomGallery.java
package zy.just.com.gallerydemo;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;
/**
* Created by print on 2016/4/5.
*/
public class CustomGallery extends Gallery {
private int galleryCenterPoint = 0;//gallery的中心点
private Camera camera;
public CustomGallery(Context context, AttributeSet attrs) {
super(context, attrs);
//这个方法设置为true时,getChildStaticTransformation方法才会起作用。谷歌是这么说的。
setStaticTransformationsEnabled(true);
camera=new Camera();
}
/**
* 当gallery的宽和高改变时,回调此方法。第一次计算出gallery的宽和高时,也会触发此方法。
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
galleryCenterPoint=getGalleryCenterPoint();
super.onSizeChanged(w, h, oldw, oldh);
}
/**
* 返回gallery每个Item的图形变换效果
* Transformation:指定当前item的变换效果。
* @param child
* @param t
* @return
*/
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
int viewCenterPoint = getViewCenterPoint(child);//item的中心点
int rotateAngle=0;//默认的旋转角度为0;
//如果当前的View的中心点,不等于gallery的中心点,就是两边的图片,需要计算旋转角度。
if(viewCenterPoint!=galleryCenterPoint){
//(gallery中心点-view的中心点)/图片的宽度,然后乘以最大旋转角度
//最终旋转角度
rotateAngle = (int)((float)(galleryCenterPoint-viewCenterPoint)/(float)child.getWidth()*50);
if(Math.abs(rotateAngle)>50){
rotateAngle=rotateAngle>0?50:-50;
}
}
//设置变换效果之前,必须要把上一个Transformation中的一个item的变换效果清除
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);//设置变换效果的类型是矩阵类型
startTransformationItem((ImageView) child, rotateAngle, t);
return true;
}
/**
* 设置变换效果
* @param iv gallery的item
* @param rotateAngle 旋转的角度(0-50)
* @param t 变换的对象
*/
private void startTransformationItem(ImageView iv,int rotateAngle,Transformation t){
camera.save();//保存状态
//3.放大效果。(中间的图片比两边的图片要大)
camera.translate(0,0,100f);//给摄像机定位
int absRotateAngle=Math.abs(rotateAngle);//获取旋转角度的绝对值
int zoom = -250+(absRotateAngle*2);//absRotateAngle为0是最大
camera.translate(0, 0, zoom);
//两边的图片稍小一些
//2.透明度。(中间的图片完全显示,两边有一定的透明度)
int alpha = (int)(255-(absRotateAngle*2.5));
iv.setAlpha(alpha);//alpha取值范围0-255,0完全透明
//1.旋转。(在中间的图片没有旋转角度,只要不在中间就有旋转角度)
camera.rotateY(rotateAngle);
Matrix matrix = t.getMatrix();//变换的矩阵,需要把变换的效果添加到矩阵中。
//给matrix赋值
camera.getMatrix(matrix);//把matrix矩阵交给camera对象,camera对象就会把上面添加的效果转换成矩阵添加到matrix矩阵中。
//矩阵前乘
matrix.preTranslate(-iv.getWidth()/2,-iv.getHeight()/2);
//矩阵后乘
matrix.preTranslate(iv.getWidth()/2,iv.getHeight()/2);
camera.restore();//恢复到之前保存的状态
}
/**
* 获得gallery的中心点
* @return
*/
private int getGalleryCenterPoint(){
return this.getWidth()/2;
}
/**
* 获得View的中心点
* @return
*/
private int getViewCenterPoint(View view){
return view.getWidth()/2+view.getLeft();//图片的宽度的一半,加上图片左边在父控件中的位置。
}
/**
* Created by print on 2016/4/5.
*/
public static class ImageUtils {
/**
* 根据id返回处理过的图片
* @param imageId
* @return
*/
public static Bitmap getInsertImage(Resources res,int imageId){
//1.获取原图
Bitmap bitmap = BitmapFactory.decodeResource(res, imageId);
//2.生成倒影图片
//创建矩阵
Matrix m = new Matrix();
m.setScale(1f,-1f);//两个参数分别表示水平翻转和垂直翻转。(1表示不翻转)
//后半张图片
Bitmap createBitmap = Bitmap.createBitmap(bitmap, 0, bitmap.getHeight() / 2, bitmap.getWidth(), bitmap.getHeight() / 2, m, false);
//3.把两张图片合成一张
Bitmap zuheBitmap= Bitmap.createBitmap(bitmap.getWidth(), (int) (bitmap.getHeight() * 1.5 + 5), Bitmap.Config.ARGB_8888);
//指定画板画在合成图上
Canvas c = new Canvas(zuheBitmap);
//把原图画在合成图的上边
c.drawBitmap(bitmap,0,0,null);
c.drawBitmap(createBitmap,0,bitmap.getHeight()+5,null);//把倒影图片画在合成图片上
//4.添加遮罩效果
Paint paint = new Paint();
//设置画笔颜色LinearGradient:线性渲染器
//LinearGradient。Shader.TileMode.CLAMP:
//渲染时,只要设置高度y的变化
LinearGradient shader = new LinearGradient(0,bitmap.getHeight()+5,0,zuheBitmap.getHeight(),0x70ffffff,0x00ffffff, Shader.TileMode.CLAMP);
paint.setShader(shader);
//设置模式是遮罩,取交集
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
c.drawRect(0,bitmap.getHeight(),bitmap.getWidth(),zuheBitmap.getHeight(),paint);
return zuheBitmap;
}
}
}
MainActivity.java
package zy.just.com.gallerydemo;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private int[] imageResIds;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomGallery customgallery = (CustomGallery) findViewById(R.id.customgallery);
imageResIds = new int[]{
R.mipmap.pic_1, R.mipmap.pic_2, R.mipmap.pic_3,
R.mipmap.pic_4, R.mipmap.pic_5, R.mipmap.pic_6,
R.mipmap.pic_7, R.mipmap.pic_8
};
customgallery.setAdapter(new MyAdapter());
}
class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return imageResIds.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv;
if(convertView==null){
iv = new ImageView(MainActivity.this);
}else{
iv= (ImageView) convertView;
}
Bitmap insertImage = CustomGallery.ImageUtils.getInsertImage(getResources(), imageResIds[position]);
BitmapDrawable bd = new BitmapDrawable(insertImage);
bd.setAntiAlias(true);//消除锯齿
//iv.setImageBitmap(insertImage);
iv.setImageDrawable(bd);
Gallery.LayoutParams layoutParams = new Gallery.LayoutParams(160,240);
//iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setLayoutParams(layoutParams);
return iv;
}
}
}