Paste the Code:
1. Extended Gallery:
Copy codeThe Code is as follows: public class GalleryFlow extends Gallery {
Private Camera mCamera = new Camera (); // Camera class
Private int mMaxRotationAngle = 60; // Maximum Rotation Angle
Private int mMaxZoom =-300; // maximum zoom Value
Private int mCoveflowCenter; // radius value
Public GalleryFlow (Context context ){
Super (context );
// Supports conversion. Run the getChildStaticTransformation method.
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 ){
System. out. println ("view left:" + view. getLeft ());
System. out. println ("view width:" + view. getWidth ());
Return view. getLeft () + view. getWidth ()/2;
}
Copy codeThe Code is as follows: // controls the rotation of each image in the gallery (the method in the rewritten gallery)
Protected boolean getChildStaticTransformation (View child, Transformation t ){
// Obtain the radius of the current sub-view
Final int childCenter = getCenterOfView (child );
System. out. println ("childCenter:" + childCenter );
Final int childWidth = child. getWidth ();
// Rotation Angle
Int rotationAngle = 0;
// Reset the conversion status
T. clear ();
// Set the Conversion Type
T. setTransformationType (Transformation. TYPE_MATRIX );
// If the image is in the center, it does not need to be rotated.
If (childCenter = mCoveflowCenter ){
TransformImageBitmap (ImageView) child, t, 0 );
} Else {
// Calculate the Image Rotation Angle Based on the Image Position in the gallery.
RotationAngle = (int) (float) (mCoveflowCenter-childCenter)/childWidth) * mMaxRotationAngle );
System. out. println ("rotationAngle:" + rotationAngle );
// If the absolute value of the rotation angle is greater than the maximum rotation angle (-mMaxRotationAngle or mMaxRotationAngle ;)
If (Math. abs (rotationAngle)> mMaxRotationAngle ){
RotationAngle = (rotationAngle <0 )? -MMaxRotationAngle: mMaxRotationAngle;
}
TransformImageBitmap (ImageView) child, t, rotationAngle );
}
Return true;
}
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 ){
// Save the effect
MCamera. save ();
Final Matrix imageMatrix = t. getMatrix ();
// Image Height
Final int imageHeight = child. getLayoutParams (). height;
// Image Width
Final int imageWidth = child. getLayoutParams (). width;
// Returns the absolute value of the rotation angle.
Final int rotation = Math. abs (rotationAngle );
// Forward the camera angle on the Z axis. The actual effect is to enlarge the image.
// If the image is moved on the Y axis, the image is moved up and down; on the X axis, the image is moved left and right.
MCamera. translate (0.0f, 0.0f, 100366f );
// 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 );
}
// Rotate on the Y axis, and flip the corresponding image vertically to the inside.
// If the image is rotated on the X axis, the image is reversed horizontally.
MCamera. rotateY (rotationAngle );
MCamera. getMatrix (imageMatrix );
ImageMatrix. preTranslate (-(imageWidth/2),-(imageHeight/2 ));
ImageMatrix. postTranslate (imageWidth/2), (imageHeight/2 ));
MCamera. restore ();
}
}
2. Fill the image container (BaseAdapter ): Copy codeThe Code is as follows: 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];
}
/**
* Create a reflection effect
* @ Return
*/
Public boolean createReflectedImages (){
// The distance between the reflected image and the source Image
Final int reflectionGap = 4;
Int index = 0;
For (int imageId: mImageIds ){
// Returns the bitmap object decoded from the source image.
Bitmap originalImage = BitmapFactory. decodeResource (mContext. getResources (), imageId );
Int width = originalImage. getWidth ();
Int height = originalImage. getHeight ();
// Create a matrix object
Matrix matrix = new Matrix ();
// Specify an angle to rotate with the coordinates of 0 and 0
// Matrix. setRotate (30 );
// Specify the matrix (the X axis remains unchanged, and the Y axis is opposite)
Matrix. preScale (1,-1 );
// Apply the Matrix to the source image, and return a reflection bitmap with the same width and 1/2 height.
Bitmap reflectionImage = Bitmap. createBitmap (originalImage, 0,
Height/2, width, height/2, matrix, false );
// Create a bitmap with the same width and height as the source image and the height of the reflected image.
Bitmap bitmapWithReflection = Bitmap. createBitmap (width,
(Height + height/2), Config. ARGB_8888 );
// Initialize the previously created bitmap to the canvas
Canvas canvas = new Canvas (bitmapWithReflection );
Canvas. drawBitmap (originalImage, 0, 0, null );
Paint deafaultPaint = new Paint ();
DeafaultPaint. setAntiAlias (false );
// Canvas. drawRect (0, height, width, height + reflectionGap, deafaultPaint );
Canvas. drawBitmap (reflectionImage, 0, height + reflectionGap, null );
Paint paint = new Paint ();
Paint. setAntiAlias (false );
/**
* Parameter 1: The x position of the initial point of the gradient,
* Parameter 2: Y axis,
* Parameter 3 and 4: determine the destination point of the gradient,
* The last parameter is the tile mode,
* The Gradient image is set here based on the Shader class, so we use the setShader method of painting to set this Gradient.
*/
LinearGradient shader = new LinearGradient (0, originalImage. getHeight (), 0,
BitmapWithReflection. getHeight () + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode. MIRROR );
// Set the shadow.
Paint. setShader (shader );
Paint. setXfermode (new porterduxfermode (android. graphics. PorterDuff. Mode. DST_IN ));
// Use a defined paint brush to build a rectangular shadow gradient effect
Canvas. drawRect (0, height, width, bitmapWithReflection. getHeight () + reflectionGap, paint );
// Create an ImageView to display the painted bitmapWithReflection
ImageView imageView = new ImageView (mContext );
ImageView. setImageBitmap (bitmapWithReflection );
// Set the imageView size, that is, the final size of the displayed image.
ImageView. setLayoutParams (new GalleryFlow. LayoutParams (300,400 ));
// ImageView. setScaleType (ScaleType. MATRIX );
MImages [index ++] = imageView;
}
Return true;
}
@ SuppressWarnings ("unused ")
Private Resources getResources (){
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 )));
}
}
3. Create an Activity: Copy codeThe Code is as follows: public class Gallery3DActivity 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. im0000100, R. drawable. img0130, R. drawable. im0000200,
R. drawable. img0230, R. drawable. img0330, R. drawable. im1_354 };
ImageAdapter adapter = new ImageAdapter (this, images );
Adapter. createReflectedImages (); // create a reflection effect
GalleryFlow galleryFlow = (GalleryFlow) this. findViewById (R. id. Gallery01 );
GalleryFlow. setFadingEdgeLength (0 );
GalleryFlow. setSpacing (-100); // spacing between images
GalleryFlow. setAdapter (adapter );
GalleryFlow. setOnItemClickListener (new OnItemClickListener (){
Public void onItemClick (AdapterView <?> Parent, View view,
Int position, long id ){
Toast. makeText (getApplicationContext (), String. valueOf (position), Toast. LENGTH_SHORT). show ();
}
});
GalleryFlow. setSelection (4 );
}
}
I have made comments in the above implementation code. I believe you can fully understand them. In a slight explanation, BaseAdapter mainly implements the image reflection effect and creates a display area for the original image and the reflection. In GalleryFlow, the image is rotated and scaled based on the position on the screen.
As follows: