先看效果图:
自定义Gallery控件实现.
主要有4个文件,1个Layout,1个Activity,1个Adapter,1个Gallery
Activity:
public
class
ActivityMain
extends
Activity {
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.layout_gallery);
Integer[] images = { R.drawable.img0001, R.drawable.img0030,
R.drawable.img0100, R.drawable.img0130, R.drawable.img0200,
R.drawable.img0230, R.drawable.img0300, R.drawable.img0330,
R.drawable.img0354 };
ImageAdapter adapter =
new
ImageAdapter(
this
, images);
adapter.createReflectedImages();
GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.Gallery01);
galleryFlow.setAdapter(adapter);
}
}
|
Gallery:
public
class
GalleryFlow
extends
Gallery {
private
Camera mCamera =
new
Camera();
private
int
mMaxRotationAngle =
60
;
private
int
mMaxZoom = -
120
;
private
int
mCoveflowCenter;
public
GalleryFlow(Context context) {
super
(context);
this
.setStaticTransformationsEnabled(
true
);
}
public
GalleryFlow(Context context, AttributeSet attrs) {
super
(context, attrs);
this
.setStaticTransformationsEnabled(
true
);
}
public
GalleryFlow(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
this
.setStaticTransformationsEnabled(
true
);
}
public
int
getMaxRotationAngle() {
return
mMaxRotationAngle;
}
public
void
setMaxRotationAngle(
int
maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public
int
getMaxZoom() {
return
mMaxZoom;
}
public
void
setMaxZoom(
int
maxZoom) {
mMaxZoom = maxZoom;
}
private
int
getCenterOfCoverflow() {
return
(getWidth() - getPaddingLeft() - getPaddingRight()) /
2
+ getPaddingLeft();
}
private
static
int
getCenterOfView(View view) {
return
view.getLeft() + view.getWidth() /
2
;
}
@Override
protected
boolean
getChildStaticTransformation(View child, Transformation t) {
final
int
childCenter = getCenterOfView(child);
final
int
childWidth = child.getWidth();
int
rotationAngle =
0
;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if
(childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t,
0
);
}
else
{
rotationAngle = (
int
) (((
float
) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if
(Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle <
0
) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return
true
;
}
@Override
protected
void
onSizeChanged(
int
w,
int
h,
int
oldw,
int
oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super
.onSizeChanged(w, h, oldw, oldh);
}
private
void
transformImageBitmap(ImageView child, Transformation t,
int
rotationAngle) {
mCamera.save();
final
Matrix imageMatrix = t.getMatrix();
final
int
imageHeight = child.getLayoutParams().height;
final
int
imageWidth = child.getLayoutParams().width;
final
int
rotation = Math.abs(rotationAngle);
// 在Z轴上正向移动camera的视角,实际效果为放大图片。
// 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
mCamera.translate(
0
.0f,
0
.0f,
100
.0f);
// As the angle of the view gets less, zoom in
if
(rotation < mMaxRotationAngle) {
float
zoomAmount = (
float
) (mMaxZoom + (rotation *
1.5
));
mCamera.translate(
0
.0f,
0
.0f, zoomAmount);
}
// 在Y轴上旋转,对应图片竖向向里翻转。
// 如果在X轴上旋转,则对应图片横向向里翻转。
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth /
2
), -(imageHeight /
2
));
imageMatrix.postTranslate((imageWidth /
2
), (imageHeight /
2
));
mCamera.restore();
}
}
|
Adapter:
public
class
ImageAdapter
extends
BaseAdapter {
int
mGalleryItemBackground;
private
Context mContext;
private
Integer[] mImageIds;
private
ImageView[] mImages;
public
ImageAdapter(Context c, Integer[] ImageIds) {
mContext = c;
mImageIds = ImageIds;
mImages =
new
ImageView[mImageIds.length];
}
public
boolean
createReflectedImages() {
final
int
reflectionGap =
4
;
int
index =
0
;
for
(
int
imageId : mImageIds) {
Bitmap originalImage = BitmapFactory.decodeResource(mContext
.getResources(), imageId);
int
width = originalImage.getWidth();
int
height = originalImage.getHeight();
Matrix matrix =
new
Matrix();
matrix.preScale(
1
, -
1
);
Bitmap reflectionImage = Bitmap.createBitmap(originalImage,
0
,
height /
2
, width, height /
2
, matrix,
false
);
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height /
2
), Config.ARGB_8888);
Canvas canvas =
new
Canvas(bitmapWithReflection);
canvas.drawBitmap(originalImage,
0
,
0
,
null
);
Paint deafaultPaint =
new
Paint();
canvas.drawRect(
0
, height, width, height + reflectionGap,
deafaultPaint);
canvas.drawBitmap(reflectionImage,
0
, height + reflectionGap,
null
);
Paint paint =
new
Paint();
LinearGradient shader =
new
LinearGradient(
0
, originalImage
.getHeight(),
0
, bitmapWithReflection.getHeight()
+ reflectionGap,
0x70ffffff
,
0x00ffffff
, TileMode.CLAMP);
paint.setShader(shader);
paint.setXfermode(
new
PorterDuffXfermode(Mode.DST_IN));
canvas.drawRect(
0
, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
ImageView imageView =
new
ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
imageView.setLayoutParams(
new
GalleryFlow.LayoutParams(
180
,
240
));
// imageView.setScaleType(ScaleType.MATRIX);
mImages[index++] = imageView;
}
return
true
;
}
private
Resources getResources() {
// TODO Auto-generated method stub
return
null
;
}
public
int
getCount() {
return
mImageIds.length;
}
public
Object getItem(
int
position) {
return
position;
}
public
long
getItemId(
int
position) {
return
position;
}
public
View getView(
int
position, View convertView, ViewGroup parent) {
return
mImages[position];
}
public
float
getScale(
boolean
focused,
int
offset) {
return
Math.max(
0
,
1
.0f / (
float
) Math.pow(
2
, Math.abs(offset)));
}
}
|
gallery在拖动图片过程中,会不断调用getChildStaticTransformation 方法,在该方法中,用Camera实现Z轴旋转。
http://www.cnblogs.com/yyyyy5101/archive/2011/12/14/2287871.html