Android realizes iOS camera sliding control _android

Source: Internet
Author: User
Tags abs gety stub

iOS compared to Android, the animation effect is one of the advantages, the iOS camera switch when the slide animation is very good, looking at is a 3D effect, and changes feel very natural. Android can also be through the graphics below camera can achieve 3D effect, began to try to do with this, the effect is not ideal, after sliding the distance between the groups of words changed, from three-dimensional space this is logical, but look at the very pinch. The spacing between the slide-effect text of the iOS camera is constant when it slides.

In the back by adjusting the TextView x direction of the scale to make the text look compact, and then through the calculation of the distance, in the sliding time to maintain consistency between the groups of words, the final implementation of the effect or iOS has a certain gap. First, the effect chart.

The following step-by-step how to achieve:

Mainaactivity.java:

Adds 6 TextView to the custom control, corresponding to each mode.

It also implements a gesture monitor to identify the sliding events. Some restrictions on the animation, the angle is less than 30 degrees, sliding distance greater than 15 to be effective.

Package Com.example.androidcustomnview;
Import android.app.Activity;
Import Android.graphics.Color;
Import Android.os.Bundle;
Import Android.util.Log;
Import Android.view.GestureDetector;
Import Android.view.GestureDetector.OnGestureListener;
Import Android.view.View;
Import Android.view.View.OnTouchListener;
Import android.view.MotionEvent;
Import Android.view.TextureView;
Import Android.view.ViewGroup;
Import android.view.animation.Animation;
Import Android.view.animation.Animation.AnimationListener;
Import Android.view.animation.AnimationSet;
Import android.view.animation.TranslateAnimation;
Import Android.widget.FrameLayout;
Import Android.widget.LinearLayout;
Import Android.widget.RelativeLayout;

Import Android.widget.TextView; public class Mainactivity extends activity implements ontouchlistener{private static final String TAG = "mainactivity.t
 AG ";
 CUSTOMVIEWL MCUSTOMVIEWL;

 string[] name = new string[] {"Time-lapse photography", "slow Motion", "video", "Photo", "Square", "Panorama"}; Gesturedetector MgesturedetectoR
 Relativelayout Rootview;
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
  Setcontentview (R.layout.activity_main);
  MCUSTOMVIEWL = (CUSTOMVIEWL) Findviewbyid (R.id.mcustomview);
  Rootview = (relativelayout) Findviewbyid (r.id.viewroot);
  Rootview.setontouchlistener (this);
  Mcustomviewl.getparent ();
  Mcustomviewl.addindicator (name); Mgesturedetector = new Gesturedetector (This, new Mygesturedetectorlis ()); Class Mygesturedetectorlis implements Gesturedetector.ongesturelistener {private static final int Degreelim
  it = 30;
  
  private static final int distancelimit = 15;
  Private Boolean isscroll = false; @Override public boolean Ondown (Motionevent e) {//TODO auto-generated Method Stub log.d (TAG, "mygesturedetectorl
   is Ondown ");
   Isscroll = false;
  return true; @Override public void onshowpress (Motionevent e) {//TODO auto-generated method stub} @Override publi C Boolean OnSIngletapup (motionevent e) {//TODO auto-generated method stub return false; @Override public boolean onscroll (Motionevent E1, motionevent E2, float Distancex, float distancey) {//T
   Odo auto-generated Method stub if (Isscroll) return false;
   Double degree = Math.atan (Math.Abs (E2.gety ()-e1.gety ())/Math.Abs (E2.getx ()-E1.getx ())) * 180/MATH.PI;
   float delta = e2.getx ()-E1.getx ();
    if (Delta > Distancelimit && degree < Degreelimit) {LOG.D (TAG, "right sliding");
    Isscroll = true;
   Mcustomviewl.scrollright ();
    else if (Delta <-distancelimit && Degree < Degreelimit) {LOG.D (TAG, "slide Left");
    Isscroll = true;
   Mcustomviewl.scrollleft ();
  return false; @Override public void onlongpress (Motionevent e) {//TODO auto-generated method stub} @Override pu Blic boolean onfling (motionevent E1, motionevent E2, float Velocityx, float velocityy) {//TODO auto-generated met
   Hod stubreturn false; @Override public boolean Ontouch (View v., motionevent event) {//TODO auto-generated method stub return MGe
 Sturedetector.ontouchevent (event);

 }


}

Customviewl.java:

Custom control, inherited from LinearLayout. In OnLayout, the position of the next child controls is recalculated, because the scale of each group of text is different, and the position of each child control must be layout again, which is the same as the display area of the text and the click Area, so that the onclick event set for each child control is valid.

The Dispatchdraw method is to redraw each child control, more than the distance between each child control to the center control position, set the TextView x direction of the scale, in order to be looking to have a stereo effect.

After sliding, start an animation, the animation after the end of the requestlayout, recalculate the position of each control. This can be continuously sliding, if the animation in the implementation, will be saved, and so on after the animation will then run the next animation. The calculation of the sliding distance of each child control is interested in their own research, here is not to repeat, in fact, is also a mathematical knowledge.

Package Com.example.androidcustomnview;
Import Android.content.Context;
Import Android.graphics.Camera;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import android.graphics.LinearGradient;
Import Android.graphics.Matrix;
Import Android.graphics.Paint;
Import Android.graphics.Shader;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.util.AttributeSet;
Import Android.util.Log;
Import android.view.MotionEvent;
Import Android.view.View;
Import Android.view.WindowManager;
Import android.view.animation.Animation;
Import Android.view.animation.Animation.AnimationListener;
Import android.view.animation.TranslateAnimation;
Import Android.widget.LinearLayout;

Import Android.widget.TextView;
 public class Customviewl extends LinearLayout {private static final String TAG = "Customviewl.tag";
 Private Matrix Mmatrix;
 Camera Mcamera; 
 private int mcurrentitem = 2;
 private int screenwidth;

 Private Paint Mpaint; public static final Float Itemscale = 0.1f;
  Public Customviewl {Super (context);
 TODO auto-generated Constructor stub initview (context); Public Customviewl (context, AttributeSet attrs, int defstyleattr, int defstyleres) {Super (context, attr
  S, defstyleattr, defstyleres);
 Initview (context);
  Public Customviewl (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
 Initview (context);
  Public Customviewl (context, AttributeSet attrs) {Super (context, attrs);
 Initview (context); } private void Initview {screenwidth = (WindowManager) getcontext (). Getsystemservice (Context.window
 _service)). Getdefaultdisplay (). GetWidth ();
  @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {log.d (TAG, "onlayout");
  Super.onlayout (changed, L, T, R, b);
  View v = getchildat (Mcurrentitem);
   
  int delta = getwidth ()/2-v.getleft ()-V.getwidth ()/2; for (int i = 0; i < Getchildcount ();
   i++) {View V1 = getchildat (i);
    if (i = = Mcurrentitem) {v1.layout (V1.getleft () + Delta, V1.gettop (), v1.getright () + Delta, V1.getbottom ());
   Continue
   float Mscale = Math.Abs (i-mcurrentitem) * Itemscale;
   int move = (int) (V1.getwidth () * MSCALE/2);
     if (I < Mcurrentitem) {for (int j = i + 1; j < Mcurrentitem; J + +) {View v2 = Getchildat (j);
    Move + + (int) (V2.getwidth () * Math.Abs (j-mcurrentitem) * Itemscale);
     } else {for (int j = i-1 J > mcurrentitem; j--) {View v2 = Getchildat (j);
    Move + + (int) (V2.getwidth () * Math.Abs (j-mcurrentitem) * Itemscale);
   } move =-move;
  V1.layout (V1.getleft () + Delta + move, V1.gettop (), v1.getright () + Delta + move, V1.getbottom ());
 } mrequstlayout = false;
  @Override protected void Dispatchdraw (Canvas Canvas) {int count = Getchildcount ();
  for (int i = 0; i < count; i++) {Updatechilditem (canvas,i); }
 }
 
 public void Updatechilditem (Canvas canvas,int Item) {//LOG.D (TAG, "Updatechilditem");  
  View v = getchildat (item);
  float desi = 1-math.abs (item-mcurrentitem) * Itemscale;
  ((TextView) v). Setscalex (Desi);
  Drawchild (Canvas, V, Getdrawingtime ());  
 Updatetextcolor (); private void Updatetextcolor () {for (int i =0 i < Getchildcount (); i++) {if (i = = Mcurrentitem) {(Te
   Xtview) Getchildat (i)). SetTextColor (Color.yellow);
   else {(TextView) Getchildat (i)). SetTextColor (Color.White);
 
 }} Boolean scrooltoright = false;
  public void Scrollright () {if (mrequstlayout) return; if (Mcurrentitem > 0) {if (manimationrunning) {if (Animationrunningcount < 1) {currentitemcopy = Mcur
     RentItem-1;
     animationrunningcount++;
    Scrooltoright = true;
   } return;
   } mcurrentitem--;
   Starttraanimation (Mcurrentitem,mcurrentitem + 1);
  Updatetextcolor ();
 } private int currentitemcopy; public void ScrolLleft () {if (mrequstlayout) return; if (Mcurrentitem < Getchildcount ()-1) {if (manimationrunning) {if (Animationrunningcount < 1) {Curr
     Entitemcopy = Mcurrentitem + 1;
     animationrunningcount++;
    Scrooltoright = false;
   } return;
   } mcurrentitem++;
   Starttraanimation (mcurrentitem,mcurrentitem-1);
  Updatetextcolor (); } public void Addindicator (string[] name {for (int i=0; i< name.length; i++) {TextView Mtextview = new T
   Extview (GetContext ());
   Mtextview.settext (Name[i]);
   Mtextview.settextcolor (Color.White);
   Mtextview.setlines (1); Linearlayout.layoutparams ll = new Linearlayout.layoutparams (LinearLayout.LayoutParams.WRAP_CONTENT, Linearlay Out.
   Layoutparams.wrap_content);
   Ll.setmargins (20, 0, 20, 0);
  AddView (MTEXTVIEW,LL); Class Myanimationlistener implements Android.view.animation.Animation.AnimationListener {@Override public vo ID Onanimationstart (Animation Animation) {Log. D (TAG, "Onanimationstart");
  Manimationrunning = true; @Override public void Onanimationend (Animation Animation) {//TODO auto-generated Method Stub log.d (TAG, "OnA

   Nimationend ");
   for (int i= 0; i < Getchildcount (); i++) {Getchildat (i). Clearanimation ();
   } Mrequstlayout = true;
   Requestlayout ();
   Manimationrunning = false;
      if (Animationrunningcount > 0) {CustomViewL.this.post (new Runnable () {@Override public void run () {
      TODO auto-generated method Stub animationrunningcount--;
      Mcurrentitem = currentitemcopy; int lastitem = Scrooltoright?
      Currentitemcopy + 1:currentitemcopy-1;
      Starttraanimation (Currentitemcopy,lastitem);
     Updatetextcolor ();
   }
    }); @Override public void Onanimationrepeat (Animation Animation) {}} private int animitiondurationtime =
 300;
 private int animationrunningcount = 0;
 Private Boolean manimationrunning = false; Private Boolean MRequstlayout = false;
  public void starttraanimation (int item,int last) {LOG.D (TAG, "starttraanimation item =" + Item);
  View v = getchildat (item);
  Final int width = v.getwidth ();
  Final int childcount = Getchildcount ();
  
  int traslate = getwidth ()/2-v.getleft ()-WIDTH/2;

  int currentitemwidthscale = (int) (width * itemscale);   
   for (int i = 0; i < ChildCount i++) {int delta = CURRENTITEMWIDTHSCALE/2; 
   LOG.D (TAG, "i =" + i + "delta before =" + Delta);
    if (I < item) {delta =-delta;
     for (int j = i; J < item; j +) {int A;
     if (i = = j) {a = (int) (Getchildat (j). GetWidth () * ITEMSCALE/2);
     else {a = (int) (Getchildat (j). GetWidth () * Itemscale); Delta = Item < last?
    Delta-a: Delta + A;
     Or else if (I > Item) {for (int j = Item + 1; J <= I; j + +) {int A;
     if (j = = i) {a = (int) (Getchildat (j). GetWidth () * ITEMSCALE/2); else {a = (int) (GetchildAt (j). GetWidth () * Itemscale); Delta = Item < last?
    Delta-a: Delta + A;
   } else {delta = 0;
   } log.d (TAG, "delta =" + Delta);
   Delta + + traslate;
   Translateanimation Translateani = new Translateanimation (0, Delta, 0, 0);
   Translateani.setduration (Animitiondurationtime);
   Translateani.setfillafter (TRUE);
   if (i = = Item) translateani.setanimationlistener (new Myanimationlistener ());
   Manimationrunning = true;
  Getchildat (i). Startanimation (Translateani);

 }
 }
}

Finally said layout file, both sides are supposed to do a shadow effect, in order to simplify, review the next PS, on top of a picture, appear on both sides of the shadow.

<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 "Tools:context" = "Com.example.androidcustomnview.MainActivity" > <relativelayout android:id= "@+id/viewroot" android:gravity= "Center" android:layout_width= "match_parent" android:layout_height= "Match_parent" > < Com.example.androidcustomnview.CustomViewL android:orientation= "Horizontal" android:background= "@android: color/ Background_dark "android:id=" @+id/mcustomview "android:layout_width=" match_parent "android:layout_height=" Wrap_co Ntent "> </com.example.androidcustomnview.CustomViewL> <imageview android:layout_width=" Wrap_co Ntent "android:layout_height=" wrap_content "android:layout_alignleft=" @id/mcustomview "android:layout_alignTop=" @ Id/mcustomview "android:layout_alignright=" @id/mcustomview "Android:layout_alignbottom= "@id/mcustomview" android:background= "@drawable/test"/> </RelativeLayout> </relativelayout&

 Gt

The whole is not complex, there are a number of mathematical calculations, geometric problems, the effect is not up to the iphone's effect, if the great God has ideas, can guide.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.