Android 3D Rotation View

Source: Internet
Author: User

Android 3D Rotation View

Today I saw an article on the internet writing about Android 3D Rotation (http://www.ibm.com/developerworks/cn/opensource/os-cn-android-anmt2/index.html? Ca = drs-), write one out of curiosity, and the running effect is as follows:

Next we will start to finish this step by step.

Achieve horizontal sliding
Package com. example. rotation3dview; import android. content. context; import android. util. attributeSet; import android. view. motionEvent; import android. view. view; import android. view. viewDebug. hierarchyTraceType; import android. view. viewGroup; import android. widget. imageView; public class Rote3DView extends ViewGroup {public Rote3DView (Context context, AttributeSet attrs) {super (context, attrs); initScreens ();} Public void initScreens () {ViewGroup. layoutParams p = new ViewGroup. layoutParams (ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT); for (int I = 0; I <3; I ++) {this. addView (new ImageView (this. getContext (), I, p);} (ImageView) this. getChildAt (0 )). setImageResource (R. drawable. page1); (ImageView) this. getChildAt (1 )). setImageResource (R. drawable. page2); (ImageView) this. getChi LdAt (2 )). setImageResource (R. drawable. page3) ;}@ Overrideprotected void onLayout (boolean changed, int l, int t, int r, int B) {int childLeft = 0; final int childCount = getChildCount (); for (int I = 0; I <childCount; I ++) {final View childView = getChildAt (I); if (childView. getVisibility ()! = View. GONE) {final int childWidth = childView. getMeasuredWidth (); childView. layout (childLeft, 0, childLeft + childWidth, childView. getMeasuredHeight (); childLeft + = childWidth ;}}@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); final int width = MeasureSpec. getSize (widthMeasureSpec); final int widthMode = MeasureSpec. GetMode (widthMeasureSpec); if (widthMode! = MeasureSpec. EXACTLY) {throw new IllegalStateException (exact size supported only);} final int heightMode = MeasureSpec. getMode (heightMeasureSpec); if (heightMode! = MeasureSpec. EXACTLY) {throw new IllegalStateException (exact size supported only);} final int count = getChildCount (); for (int I = 0; I <count; I ++) {getChildAt (I ). measure (widthMeasureSpec, heightMeasureSpec) ;}} private float mDownX; @ Overridepublic boolean onTouchEvent (MotionEvent event) {float x = event. getX (); switch (event. getAction () {case MotionEvent. ACTION_DOWN: mDownX = x; break; case MotionEvent. ACTION_MOVE: int disX = (int) (mDownX-x); mDownX = x; scrollBy (disX, 0); break; case MotionEvent. ACTION_UP: break; default: break;} return true ;}}
The slide above is not smooth yet. We can judge and process it when the gesture is lifted. The Code is as follows:
Package com. example. rotation3dview; import android. content. context; import android. graphics. camera; import android. graphics. canvas; import android. graphics. matrix; import android. util. attributeSet; import android. view. motionEvent; import android. view. velocityTracker; import android. view. view; import android. view. viewDebug. hierarchyTraceType; import android. view. viewGroup; import android. widget. imageView; impor T android. widget. scroller; public class Rote3DView extends ViewGroup {private int mCurScreen = 1; // The sliding speed is private static final int SNAP_VELOCITY = 500; private VelocityTracker mVelocityTracker; private int mWidth; private scroler mScroller; private Camera mCamera; private Matrix mMatrix; // rotation angle, which can be modified to observe the effect private float angle = 90; public Rote3DView (Context context, AttributeSet attrs) {super (context, att Rs); mScroller = new Scroller (context); mCamera = new Camera (); mMatrix = new Matrix (); initScreens ();} public void initScreens () {ViewGroup. layoutParams p = new ViewGroup. layoutParams (ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT); for (int I = 0; I <3; I ++) {this. addView (new ImageView (this. getContext (), I, p);} (ImageView) this. getChildAt (0 )). setImageResource (R. drawable. p Age1); (ImageView) this. getChildAt (1 )). setImageResource (R. drawable. page2); (ImageView) this. getChildAt (2 )). setImageResource (R. drawable. page3) ;}@ Overrideprotected void onLayout (boolean changed, int l, int t, int r, int B) {int childLeft = 0; final int childCount = getChildCount (); for (int I = 0; I <childCount; I ++) {final View childView = getChildAt (I); if (childView. getVisibility ()! = View. GONE) {final int childWidth = childView. getMeasuredWidth (); childView. layout (childLeft, 0, childLeft + childWidth, childView. getMeasuredHeight (); childLeft + = childWidth ;}}@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); final int width = MeasureSpec. getSize (widthMeasureSpec); final int widthMode = MeasureSpec. GetMode (widthMeasureSpec); if (widthMode! = MeasureSpec. EXACTLY) {throw new IllegalStateException (exact size supported only);} final int heightMode = MeasureSpec. getMode (heightMeasureSpec); if (heightMode! = MeasureSpec. EXACTLY) {throw new IllegalStateException (exact size supported only);} final int count = getChildCount (); for (int I = 0; I <count; I ++) {getChildAt (I ). measure (widthMeasureSpec, heightMeasureSpec);} scrollTo (mCurScreen * width, 0);} private float mDownX; @ Overridepublic boolean onTouchEvent (MotionEvent event) {if (mVelocityTracker = null) {mVelocityTracker = VelocityTracker. obtain ();} // pass the current touch event to VelocityTrack Er object mVelocityTracker. addMovement (event); float x = event. getX (); switch (event. getAction () {case MotionEvent. ACTION_DOWN: if (! MScroller. isFinished () {mScroller. abortAnimation ();} mDownX = x; break; case MotionEvent. ACTION_MOVE: int disX = (int) (mDownX-x); mDownX = x; scrollBy (disX, 0); break; case MotionEvent. ACTION_UP: final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker. computeCurrentVelocity (1000); int velocityX = (int) velocityTracker. getXVelocity (); if (velocityX> SNAP_VELOCITY & mCurScreen> 0) {snapToScr Een (mCurScreen-1);} else if (velocityX <-SNAP_VELOCITY & mCurScreen <getChildCount ()-1) {snapToScreen (mCurScreen + 1 );} else {snapToDestination ();} if (mVelocityTracker! = Null) {mVelocityTracker. recycle (); mVelocityTracker = null;} break;} return true ;}@ Overridepublic void computeScroll () {if (mScroller. computescroloffset () {scrollTo (mScroller. getCurrX (), mScroller. getCurrY (); postInvalidate () ;}} public void snapToDestination () {setMWidth (); final int destScreen = (getScrollX () + mWidth/2)/mWidth; snapToScreen (destScreen);} public void snapToScreen (int whichScreen) {w HichScreen = Math. max (0, Math. min (whichScreen, getChildCount ()-1); setMWidth (); int scrollX = getScrollX (); int startWidth = whichScreen * mWidth; if (scrollX! = StartWidth) {int delta = 0; int startX = 0; if (whichScreen> mCurScreen) {setPre (); delta = startWidth-scrollX; startX = mWidth-startWidth + scrollX ;} else if (whichScreen <mCurScreen) {setNext (); delta =-scrollX; startX = scrollX + mWidth;} else {startX = scrollX; delta = startWidth-scrollX;} mScroller. startScroll (startX, 0, delta, 0, Math. abs (delta) * 2); invalidate () ;}} private void setNext () {int count = this. getChildCount (); View view = getChildAt (count-1); removeViewAt (count-1); addView (view, 0);} private void setPre () {int count = this. getChildCount (); View view = getChildAt (0); removeViewAt (0); addView (view, count-1);} private void setMWidth () {if (mWidth = 0) {mWidth = getWidth ();}}}
Add the following code to implement the stereoscopic effect:
/** When sliding a View, the current View will be invalid. This function is used to re-draw the View and call the drawScreen function */@ Overrideprotected void dispatchDraw (Canvas canvas Canvas) {final long drawingTime = getDrawingTime (); final int count = getChildCount (); for (int I = 0; I <count; I ++) {drawScreen (canvas, I, drawingTime) ;}} public void drawScreen (Canvas canvas, int screen, long drawingTime) {// you can get the final int width = getWidth (); final int scrollWidth = Screen * width; final int scrollX = this. getScrollX (); // if (scrollWidth> scrollX + width | scrollWidth + width <scrollX) {return;} final View child = getChildAt (screen ); final int faceIndex = screen; final float currentDegree = getScrollX () * (angle/getMeasuredWidth (); final float faceDegree = currentDegree-faceIndex * angle; if (faceDegree> 90 | faceDegree <-90) {return;} final float CenterX = (scrollWidth <scrollX )? ScrollWidth + width: scrollWidth; final float centerY = getHeight ()/2; final Camera camera = mCamera; final Matrix matrix = mMatrix; canvas. save (); camera. save (); camera. rotateY (-faceDegree); camera. getMatrix (matrix); camera. restore (); matrix. preTranslate (-centerX,-centerY); matrix. postTranslate (centerX, centerY); canvas. concat (matrix); drawChild (canvas, child, drawingTime); canvas. restore ();}
 

 

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.