Reprint Please specify source: http://blog.csdn.net/l1028386804/article/details/48052709
Now, Android development has become an indispensable force in the field of mobile Internet development, so it is reasonable to achieve 3D effect in Android. So how do you achieve 3D image viewing in android like iOS? Below, I will be heavy to launch today's key blog, and everyone together in Android to achieve cool 3D picture viewing effect.
First, the principle
The usual, still want to come up with the principle of things.
The overall implementation is the cell phone screen is the center of the axis of symmetry, is located in the middle of the picture display the largest, also the brightest, while the left and right sides of the picture with the most intermediate position for the axis of symmetry, respectively, rotating the corresponding angle, while brightness adjustment to the appropriate proportion, has reached a symmetrical effect. Specific 3D browse picture effect, I was implemented by Custom Gallery, create a class Galleryflow, Inherit gallery, in this class to do the image rotation, scaling, brightness settings and other operations. At the same time, in this class, I created a camera object cameras to set the image change effect, while customizing an image of the adapter class Imageadapter, this class inherits baseadapter, mainly to implement the display of the interface picture, and create a picture with reflection.
The principle is over, let us come together to achieve this cool 3D effect bar.
II. Implementation 1, custom adapter Imageadapter
The adapter that displays the picture, this class inherits the Baseadapter, completes the basic display of the image, and displays the original image with a reflection image. The concrete implementation is that, in the construction method, the context information in the interface, and the array that holds the image ID are passed over, and the corresponding ImageView array is generated by passing the image ID array to hold the ImageView object with the picture information. In the Createrefectedbitmap () method, the original image is processed into a reflection-effect picture in the ImageView object, and the ImageView object is stored in the ImageView array.
The specific implementation code is as follows:
Package Com.lyz.gallery.activity;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmap.config;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.lineargradient;import Android.graphics.matrix;import Android.graphics.paint;import Android.graphics.porterduff.mode;import Android.graphics.porterduffxfermode;import Android.graphics.shader.tilemode;import Android.graphics.drawable.bitmapdrawable;import Android.view.View;import Android.view.viewgroup;import Android.widget.baseadapter;import android.widget.imageview;/** * Custom Picture Display Adapter Imageadapter * @author Liuyazhuang * */public class Imageadapter extends Baseadapter {private Context context;p Rivate int[] imageids;private imageview[] images;//construction method Public Imageadapter (context context, int[] imageids) { This.context = Context;this.imageids = imageids;//An array of images stored images = new Imageview[imageids.length];} @Overridepublic int GetCount () {return images.length;} @Overridepublic OBject getItem (int position) {return images[position];} @Overridepublic long Getitemid (int position) {return position;} @Overridepublic view GetView (int position, view Convertview, ViewGroup parent) {return images[position];} /** * Create a picture with reflection */public void Createrefectedbitmap () {//the distance between the original picture and the reflection image int refectiongap = 4;//Add a picture to the image array for (int i = 0; I < ; Imageids.length; i++) {int imageId = imageids[i];//original picture bitmap Resourcebitmap = Bitmapfactory.decoderesource (Context.getresources (), IMAGEID); int width = resourcebitmap.getwidth (); int height = resourcebitmap.getheight ();//Reflection Image//reource: Original image//x,y: The starting position of the reflection image//width,heiht: Generate reflection Image width and height//matrix m: The style used to set the picture (reflection) Matrix M = new Matrix ();//x: horizontal flip; y: Vertical flip 1 support;-1 Flip M.setscale (1,-1); Bitmap Refrectionbitmap = Bitmap.createbitmap (resourcebitmap, 0, HEIGHT/2, width, height/2,m, false);//composite image with Reflection Bitma P bitmap = bitmap.createbitmap (width, height + height/2, config.argb_8888);//create canvas canvases canvas = new canvas (bitmap);//Draw Original Picture Canvas.drawbitmap (resourcebitmap, 0, 0,NULL);//Draw the interval between the original picture and the reflection paint Defaultpaint = new paint (); canvas.drawrect (0, height, width, height + refectiongap, Defaultpaint)///Draw Reflection Picture Canvas.drawbitmap (Refrectionbitmap, 0, height + refectiongap, null); gradient and matte effect in//ps paint paint = New Paint ();//Set Matte effect Paint.setxfermode (new Porterduffxfermode (mode.dst_in));//Set gradient effect//Set shader to colorize the mask lineargradient Shader = new LinearGradient (0, height, 0, bitmap.getheight (), 0X70FFFFFF, 0X00FFFFFF, Tilemode.clamp);p Aint.setshader ( shader); Canvas.drawrect (0, height, width, bitmap.getheight (), paint);//create bitmapdrawable picture bitmapdrawable BD = new Bitmapdrawable (bitmap);//Eliminate the image jagged effect, make the picture smooth Bd.setantialias (true); ImageView ImageView = new ImageView (context); Imageview.setimagedrawable (BD);//Set Picture size Imageview.setlayoutparams (new Galleryflow.layoutparams (160, 240));// Place the picture in the images array images[i] = ImageView;}}}
2, Custom gallery class Galleryflow
The main implementation of this class is the image scaling, rotation, brightness adjustment and other operations, the following we decompose to see this class.
1) member variables
The main variables here are the maximum rotation angle, the maximum zoom value, the position of the recording center point, the camera object
The specific implementation code is as follows:
Maximum rotation angle private int maxrotateangle = 50;//Max scale value private int maxzoom = -250;//Record middle point position private int currentofgallery;// Create camera object Private camera camera = new camera ();
2) Construction method
Here I have made a copy of the three constructor methods for gallery and called Setstatictransformationsenabled (true) in each of the constructor methods, which is used to specify whether the shape changes false: No true: Yes. When we call the Setstatictransformationsenabled method, Android will callback the following Getchildstatictransformation method
The specific implementation code is as follows:
Public Galleryflow (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); Setstatictransformationsenabled (TRUE);} Public Galleryflow (context context, AttributeSet Attrs) {Super (context, attrs);//Specifies whether the graphic changes false: No true: is setstatictransformationsenabled (true);} Public Galleryflow (Context context) {super (context); setstatictransformationsenabled (true);}
3) Getchildstatictransformation method
This method is called when the setstatictransformationsenabled, Android will call back a method, I have done in this method is mainly: Calculate the angle of rotation of the image, set the image deformation style, At the same time call the picture deformation of the method transformationbitmap to achieve the effect of image deformation.
The specific implementation code is as follows:
@Overrideprotected Boolean getchildstatictransformation (View child, Transformation t) {//Get the center point of the picture int currentofchild = Getcurrentofview (child); int width = Child.getlayoutparams (). Width;int height = child.getlayoutparams (). height;// Rotate the angle int rotateangle = 0;t.clear ();//Set Picture warp style t.settransformationtype (Transformation.type_matrix);//Position Center point position if ( Currentofchild = = currentofgallery) {Transformationbitmap ((ImageView) child, T, 0);} else{//is not a central position rotateangle = (int) ((float) (currentofgallery-currentofchild)/width * maxrotateangle); if (Math.Abs ( Rotateangle) > Maxrotateangle) {rotateangle = Rotateangle < 0?-maxrotateangle:maxrotateangle;} Picture variants Transformationbitmap ((ImageView) child, T, Rotateangle);} return true;}
4) Image deformation method Transformationbitmap
The main operation of this method is to complete the deformation operation of the image through the camera object.
The specific implementation code is as follows:
/** * Picture Warp * @param child * @param t * @param i */private void Transformationbitmap (ImageView child, transformation T, int Rotateangle) {//Save image Change Effect Camera.save (); Matrix Imagematrix = T.getmatrix (); int rotate = Math.Abs (rotateangle); int imagewidth = Child.getwidth (); int imageheight = Child.getheight ();//z: positive: Picture becomes larger//x: horizontal movement//y: Vertical Movement Camera.translate (0.0f, 0.0f, 100.0f);//current rotation angle is less than the maximum rotation angle if (rotate < Maxrotateangle) {Float zoom = (float) ((rotate * 1.5) + maxzoom), Camera.translate (0.0f, 0.0f, zoom);// Sets the picture gradient effect Child.setalpha ((int) (255-rotate * 2.5));} The image is rotated vertically from the display center Camera.rotatey (rotateangle); Camera.getmatrix (Imagematrix); Imagematrix.pretranslate (-( IMAGEWIDTH/2),-(IMAGEHEIGHT/2)); Imagematrix.posttranslate (IMAGEWIDTH/2, IMAGEHEIGHT/2);// Restores the effect of image changes Camera.restore ();}
5) Get the center point method of Gallery display picture
The specific implementation code is as follows:
/** * Get center point of gallery Display image * @return */public int getcurrentofgallery () {return (GetWidth ()-Getpaddingleft ()-Getpaddingrig HT ())/2 + Getpaddingleft ();}
6) Get the image center point method
The specific implementation code is as follows:
/** * Get Image Center Point * @param view * @return */public int Getcurrentofview (view view) {return view.getleft () + view.getwidth ()/2 ;}
7) Onsizechanged method
This method is when the screen size changes, the Android automatic callback method, my operation in this method is to get to the gallery display image of the center point assigned to the member variable currentofgallery.
The specific code is as follows:
@Overrideprotected void onsizechanged (int w, int h, int oldw, int oldh) {currentofgallery = Getcurrentofgallery (); Super.on SizeChanged (W, H, OLDW, OLDH);}
8) The complete code is as follows:
Package Com.lyz.gallery.activity;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;/** * Custom Gallery * @author Liuyazhuang * */public class Galleryflow extends Gallery {//MAX rotation angle private int maxrotateangle = 50;// Maximum scaling value private int maxzoom = -250;//Record middle point position private int currentofgallery;//Create camera object private camera camera = new camera ();p Ubli C Galleryflow (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); Setstatictransformationsenabled (TRUE);} Public Galleryflow (context context, AttributeSet Attrs) {Super (context, attrs);//Specifies whether the graphic changes false: No true: is setstatictransformationsenabled (true);} Public Galleryflow (Context context) {super (context); setstatictransformationsenabled (true);} @Overrideprotected void onsizechanged (int w, int h, int oldw, int oldh) {Currentofgallery = Getcurrentofgallery (); Super.onsizechanged (W, H, OLDW, OLDH);} @Overrideprotected Boolean getchildstatictransformation (View child, Transformation t) {//Get the center point of the picture int currentofchild = Getcurrentofview (child); int width = Child.getlayoutparams (). Width;int height = child.getlayoutparams (). height;// Rotate the angle int rotateangle = 0;t.clear ();//Set Picture warp style t.settransformationtype (Transformation.type_matrix);//Position Center point position if ( Currentofchild = = currentofgallery) {Transformationbitmap ((ImageView) child, T, 0);} else{//is not a central position rotateangle = (int) ((float) (currentofgallery-currentofchild)/width * maxrotateangle); if (Math.Abs ( Rotateangle) > Maxrotateangle) {rotateangle = Rotateangle < 0?-maxrotateangle:maxrotateangle;} Picture variants Transformationbitmap ((ImageView) child, T, Rotateangle);} return true;} /** * Picture Warp * @param child * @param t * @param i */private void Transformationbitmap (ImageView child, transformation T, int Rotateangle) {//Save image Change Effect Camera.save (); Matrix Imagematrix = T.getmatrix (); int rotate = Math.Abs (rotateangle); int imagewidth = Child.getwidth (); int imageheight = Child.getheight ();//z: positive: Picture becomes larger//x: Move horizontally//y: Vertical Movement Camera.translate (0.0f, 0.0f, 100.0f);//current rotation angle is less than the maximum rotation angle if (rotate < maxrotateangle) {float zoom = (float) ((rotate * 1.5) + Maxzoom) camera.translate (0.0f, 0.0f, zoom);//Set Picture gradient effect Child.setalpha ((int) (255-rotate * 2.5));} The image is rotated vertically from the display center Camera.rotatey (rotateangle); Camera.getmatrix (Imagematrix); Imagematrix.pretranslate (-( IMAGEWIDTH/2),-(IMAGEHEIGHT/2)); Imagematrix.posttranslate (IMAGEWIDTH/2, IMAGEHEIGHT/2);// Restores the effect of image changes Camera.restore ();} /** * Get center point of gallery Display image * @return */public int getcurrentofgallery () {return (GetWidth ()-Getpaddingleft ()-Getpaddingrig HT ())/2 + Getpaddingleft ();} /** * Get Image Center Point * @param view * @return */public int Getcurrentofview (view view) {return view.getleft () + view.getwidth ()/2 ;}}
3, Mainactivity
The main function of this class is to load the layout file, construct an array of IDs for the images to be displayed, and invoke the Imageadapter method to implement the display of the picture.
The specific implementation code is as follows:
Package Com.lyz.gallery.activity;import Android.os.bundle;import Android.app.activity;import android.view.Menu;/** * Program Main Entrance * @author Liuyazhuang * */public class Mainactivity extends Activity {private Galleryflow gallery_flow;//an array of picture IDs Private int[] imageids; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (r.layout.activity_main);//Constructs an array that holds the image id Imageids = new int[]{r.drawable.photo1, R.drawable.photo2,r.drawable.photo3,r.drawable.photo4,r.drawable.photo5,r.drawable.photo6,r.drawable.photo7, R.drawable.photo8};gallery_flow = (galleryflow) Findviewbyid (r.id.gallery_flow);//Instantiate Imageadapter object Imageadapter adapter = new Imageadapter (this, imageids);//load picture in image array Adapter.createrefectedbitmap (); Gallery_flow.setadapter ( adapter);} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.menu.main, menu); return true;}}
4. layout file Activity_main.xml
This layout file is simple enough to place a galleryflow control that we define ourselves.
The specific implementation code is as follows:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools " android:layout_width=" match_parent " android:layout_height=" Match_parent " android:background= "@android: Color/black" > <com.lyz.gallery.activity.galleryflow android:id = "@+id/gallery_flow" android:layout_width= "match_parent" android:layout_height= "Match_parent"/>< /relativelayout>
5, Androidmanifest.xml
Nothing is done in this file, it's Android Auto-generated content.
The specific implementation code is as follows:
<?xml version= "1.0" encoding= "Utf-8"? ><manifest xmlns:android= "http://schemas.android.com/apk/res/ Android " package=" com.lyz.gallery.activity " android:versioncode=" 1 " android:versionname=" 1.0 "> <uses-sdk android:minsdkversion= "8" android:targetsdkversion= "/> <application" android:allowbackup= "true" android:icon= "@drawable/ic_launcher" android:label= "@string/app_name" android:theme= "@style/apptheme" > <activity android:name= " Com.lyz.gallery.activity.MainActivity " android:label=" @string/app_name "> <intent-filter> <action android:name= "Android.intent.action.MAIN"/> <category android:name= " Android.intent.category.LAUNCHER "/> </intent-filter> </activity> </ Application></manifest>
Third, the Operation effect
Four, warm tips
You can go to link http://download.csdn.net/detail/l1028386804/9058447 download Android implementation 3D Picture Browse effect sample full source code
In this example, for the sake of the aspect, I write some text directly in the layout file and the related class, Everyone in the real project to write these words in the String.xml file, in the external reference to these resources, remember, this is the most basic development knowledge and specifications as an Android programmer, I am here just to facilitate directly written in the class and layout files.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android--The simplest and coolest 3D image browsing effect in history