Android-the simplest and coolest 3D image browsing effect in history,

Source: Internet
Author: User

Android-the simplest and coolest 3D image browsing effect in history,

Reprinted please indicate the source: http://blog.csdn.net/l1028386804/article/details/48052709

Nowadays, Android development has become an indispensable force in the mobile Internet development field. It is reasonable to achieve 3D effects in Android. So, how can we implement 3D image browsing like in IOS in Android? Next, I will publish today's key blog posts to share with you the amazing 3D image browsing effect in Android.

I. Principles

The old rule is still about the principle.

The overall implementation is based on the center of the mobile phone screen as the axis of symmetry, the picture is located in the center of the largest, but also the brightest, while the pictures on both sides are in the middle of the axis of symmetry, rotate the corresponding angles and adjust the brightness to a proper ratio to achieve symmetric effect. The specific 3D image browsing effect is implemented by customizing the Gallery, creating a class GalleryFlow that inherits the Gallery and rotating and scaling the image in this class, brightness settings. At the same time, in this class, I created a camera object camera to set the image change effect. At the same time, I customized an image adapter class ImageAdapter, which inherits BaseAdapter, it mainly displays interface images and creates images with reflections.

If the principle is exhausted, let's achieve this Cool 3D effect together.

II. Implementation 1. Custom adapter ImageAdapter

The Image Display Adapter. This class inherits the BaseAdapter to display the basic image, and displays the original image with a reflection. The specific implementation is to pass the context information in the interface and the array storing the image id in the constructor method, and generate the corresponding ImageView array through the passed image id array, used to store ImageView objects with image information. In the createRefectedBitmap () method, process the original image as an image with a reflection effect and store it in the ImageView object. Then, 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. porterduxfermode; 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 image display adapter ImageAdapter * @ author liuyazhuang **/public class ImageAdapter extends BaseAdapter {private Context context; private int [] imageIds; private ImageView [] images; // constructor public ImageAdapter (Context context, int [] imageIds) {this. context = context; this. imageIds = imageIds; // The image storage array 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 Image with reflection */public void createRefectedBitmap () {// The distance between the original image and the reflected image is int refectionGap = 4; // Add the image for (int I = 0; I <imageIds. length; I ++) {int imageId = imageIds [I]; // the original image Bitmap resourceBitmap = BitmapFactory. decodeResource (context. getResources (), imageId); int width = resourceBitmap. getWidth (); int height = resourceBitmap. getHeight (); // reflected image // reource: original image // x, y: Start position of the generated reflected image // width, heiht: generate reflected image width and height // Matrix m: used to set the image style (reflection) Matrix m = new Matrix (); // x: horizontal flip; y: vertical flip 1 supported; -1 flip m. setScale (1,-1); Bitmap refrectionBitmap = Bitmap. createBitmap (resourceBitmap, 0, height/2, width, height/2, m, false); // merged Bitmap bitmap = Bitmap. createBitmap (width, height + height/2, Config. ARGB_8888); // create a Canvas canvas Canvas = new canvas (bitmap); // draw the original image Canvas. drawBitmap (resourceBitmap, 0, 0, null); // draw the interval between the original image and the reflection. Paint defaultPaint = new Paint (); canvas. drawRect (0, height, width, height + refectionGap, defaultPaint); // draw the reflected image canvas. drawBitmap (refrectionBitmap, 0, height + refectionGap, null); // In ps, gradient and mask effect Paint = new paint (); // set the mask effect Paint. setXfermode (new porterduduxfermode (Mode. DST_IN); // sets the gradient effect. // sets the shader of the shadow as the mask coloring LinearGradient = new LinearGradient (0, height, 0, bitmap. getHeight (), 0x70ffffff, 0x00ffffff, TileMode. CLAMP); paint. setShader (shader); canvas. drawRect (0, height, width, bitmap. getHeight (), paint); // create a BitmapDrawable image BitmapDrawable bd = new BitmapDrawable (bitmap); // eliminate the image sawtooth effect and smooth the image bd. setAntiAlias (true); ImageView imageView = new ImageView (context); imageView. setImageDrawable (bd); // sets the image size to imageView. setLayoutParams (new GalleryFlow. layoutParams (160,240); // place the image in the images array images [I] = imageView ;}}}

2. Customize Gallery class GalleryFlow

In this class, we mainly implement operations such as image scaling, rotation, and brightness adjustment. Let's take a look at this class.

1) member variables

The main member variables here are: the maximum rotation angle, the maximum scaling value, the position of the recorded center point, and the camera object.

The specific implementation code is as follows:

// Maximum Rotation Angle private int maxRotateAngle = 50; // maximum zoom value private int maxZoom =-250; // record the position of the center point private int currentOfGallery; // create the Camera object private camera Camera = new Camera ();

2) constructor

Here, I wrote three constructor methods of Gallery and called setStaticTransformationsEnabled (true) in each constructor. The function of this method is to specify whether the image changes. false: no true: Yes. When the setStaticTransformationsEnabled method is called, Android calls back the getChildStaticTransformation method below.

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 image changes. false: no true: setStaticTransformationsEnabled (true);} public GalleryFlow (Context context) {super (context ); setStaticTransformationsEnabled (true );}

3) getChildStaticTransformation Method

This method calls a method called by Android when setStaticTransformationsEnabled. The operations I perform in this method are to calculate the image rotation angle and set the image deformation style, at the same time, call the image deformation placement method transformationBitmap to achieve the image deformation effect.

The specific implementation code is as follows:

@ Overrideprotected boolean getChildStaticTransformation (View child, Transformation t) {// get the image's center point int currentOfChild = getCurrentOfView (child); int width = child. getLayoutParams (). width; int height = child. getLayoutParams (). height; // Rotation Angle int rotateAngle = 0; t. clear (); // set the image deformation style t. setTransformationType (Transformation. TYPE_MATRIX); // if (currentOfChild = currentOfGallery) {transformationBitmap (Imag EView) child, t, 0);} else {// not the center position rotateAngle = (int) (float) (currentOfGallery-currentOfChild)/width * maxRotateAngle ); if (Math. abs (rotateAngle)> maxRotateAngle) {rotateAngle = rotateAngle <0? -MaxRotateAngle: maxRotateAngle;} // transformationBitmap (ImageView) child, t, rotateAngle);} return true ;}

4) transformationBitmap

The main operation of this method is to perform deformation of the image through the camera object.

The specific implementation code is as follows:

/*** Image deformation ** @ param child * @ param t * @ param I */private void transformationBitmap (ImageView child, Transformation t, int rotateAngle) {// Save the effect of image changes camera. save (); Matrix imageMatrix = t. getMatrix (); int rotate = Math. abs (rotateAngle); int imageWidth = child. getWidth (); int imageHeight = child. getHeight (); // z: positive number: The image becomes larger // x: horizontal movement // y: vertical movement of camera. translate (0.0f, 0.0f, 100366f); // if (rotate <maxRotateAngle) {float zoom = (float) (rotate * 1.5) + maxZoom); camera. translate (0.0f, 0.0f, zoom); // sets the child gradient effect of the image. setAlpha (int) (255-rotate * 2.5);} // rotate the camera vertically to the display center. rotateY (rotateAngle); camera. getMatrix (imageMatrix); imageMatrix. preTranslate (-(imageWidth/2),-(imageHeight/2); imageMatrix. postTranslate (imageWidth/2, imageHeight/2); // restore the camera effect of image changes. restore ();}

5) obtain the center of the Gallery image.

The specific implementation code is as follows:

/*** Obtain the center point of the Gallery display image * @ return */public int getCurrentOfGallery () {return (getWidth ()-getPaddingLeft ()-getPaddingRight ()) /2 + getPaddingLeft ();}

6) obtain the image Center

The specific implementation code is as follows:

/*** Obtain the image center ** @ param view * @ return */public int getCurrentOfView (View view) {return view. getLeft () + view. getWidth ()/2 ;}

7) onSizeChanged Method

This method is the Android automatic callback method when the screen size changes. In this method, I assign the central point of the retrieved Gallery display image to the member variable currentOfGallery.

The Code is as follows:

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {currentOfGallery = getCurrentOfGallery();super.onSizeChanged(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 {// Maximum Rotation Angle private int maxR OtateAngle = 50; // maximum zoom value private int maxZoom =-250; // record the position of the center point private int currentOfGallery; // create the Camera object private camera Camera = new Camera (); public GalleryFlow (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle ); setStaticTransformationsEnabled (true);} public GalleryFlow (Context context, AttributeSet attrs) {super (context, attrs); // specify whether the image changes. false: no true: setStaticTransformat IonsEnabled (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 image center point int currentOfChild = getCurrentOfView (ch Ild); int width = child. getLayoutParams (). width; int height = child. getLayoutParams (). height; // Rotation Angle int rotateAngle = 0; t. clear (); // set the image deformation style t. setTransformationType (Transformation. TYPE_MATRIX); // if (currentOfChild = currentOfGallery) {transformationBitmap (ImageView) child, t, 0 );} else {// not the central position rotateAngle = (int) (float) (currentOfGallery-currentOfChild)/width * maxRotateAngle); if (Math. abs (r OtateAngle)> maxRotateAngle) {rotateAngle = rotateAngle <0? -MaxRotateAngle: maxRotateAngle;} // transformationBitmap (ImageView) child, t, rotateAngle);} return true ;} /*** image deformation ** @ param child * @ param t * @ param I */private void transformationBitmap (ImageView child, Transformation t, int rotateAngle) {// Save the effect of image changes camera. save (); Matrix imageMatrix = t. getMatrix (); int rotate = Math. abs (rotateAngle); int imageWidth = child. getWidth (); int imageHeight = child. getHeight (); // z: positive number: The image becomes larger // x: horizontal movement // y: vertical movement of camera. translate (0.0f, 0.0f, 100366f); // if (rotate <maxRotateAngle) {float zoom = (float) (rotate * 1.5) + maxZoom); camera. translate (0.0f, 0.0f, zoom); // sets the child gradient effect of the image. setAlpha (int) (255-rotate * 2.5);} // rotate the camera vertically to the display center. rotateY (rotateAngle); camera. getMatrix (imageMatrix); imageMatrix. preTranslate (-(imageWidth/2),-(imageHeight/2); imageMatrix. postTranslate (imageWidth/2, imageHeight/2); // restore the camera effect of image changes. restore ();}/*** get the center point of the Gallery display image * @ return */public int getCurrentOfGallery () {return (getWidth ()-getPaddingLeft ()-getPaddingRight ()) /2 + getPaddingLeft ();}/*** obtain the 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 the id array of the image to be displayed, and call the ImageAdapter method to display the image.

The specific implementation code is as follows:

Package com. lyz. gallery. activity; import android. OS. bundle; import android. app. activity; import android. view. menu;/*** main program entry * @ author liuyazhuang **/public class MainActivity extends Activity {private GalleryFlow gallery_flow; // array containing image IDs private int [] imageIds; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); // construct an array 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 the ImageAdapter object ImageAdapter adapter = new ImageAdapter (this, imageIds); // load the image adapter to the Image array. createRefectedBitmap (); gallery_flow.setAdapter (adapter) ;}@ Overridepublic boolean onCreateOptionsMenu (Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater (). inflate (R. menu. main, menu); return true ;}}

4. layout file activity_main.xml

This layout file is simple, that is, a self-defined GalleryFlow control is placed.

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

This file does not perform any operations and is automatically generated by Android.

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="18" />    <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>

Iii. Running Effect


4. Tips

You can go to the links

In this example, for the purpose of writing some text directly in the layout file and related classes, you need to write these words in the real project. in xml files, reference these resources externally. Remember, this is the most basic development knowledge and specification for an Android programmer. I am writing these resources in the class and layout files for convenience.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.