Android实现IOS相机滑动控件

Android实现IOS相机滑动控件,第1张

概述IOS相比于Android,动画效果是一方面优势,IOS相机切换时滑动的动画很不错,看着是有一个3D的效果,而且变化感觉很自然。Android也可以通过Graphics下面的Camera可以实现3D效果,开始尝试着用这个做了一下,效果不理

IOS相比于AndroID,动画效果是一方面优势,IOS相机切换时滑动的动画很不错,看着是有一个3D的效果,而且变化感觉很自然。AndroID也可以通过Graphics下面的Camera可以实现3D效果,开始尝试着用这个做了一下,效果不理想,滑动之后各组文字之间的距离就变了,从立体空间来说这是合逻辑的,但是看着很别捏。IOS相机的滑动效果文字之间的间隔在滑动的时候是不变的。

后面通过调整TextVIEw X方向的scale使文字看着紧凑一点,然后通过计算的距离的方式,在滑动的时候保持各组文字之间的间隔一致,最后实现的效果还是和IOS的有一定的差距。先上个效果图的。 

下面逐步来说下怎么实现:

MainaActivity.java: 

往自定义的控件加了6个TextVIEw,对应各个模式。 

这里面还实现了一个手势监听,来识别滑动事件。对动画做了一些限制,角度小于30度,滑动距离大于15才能生效。 

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.TAG"; CustomVIEwL mCustomVIEwL; String[] name = new String[] {"延时摄影","慢动作","视频","拍照","正方形","全景"}; 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()); 48  }  class myGestureDetectorlis implements GestureDetector.OnGestureListener {    private static final int degreelimit = 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,"myGestureDetectorlis onDown");   isScroll = false;   return true;  }  @OverrIDe  public voID onShowPress(MotionEvent e) {   // Todo auto-generated method stub     }  @OverrIDe  public boolean onSingleTapUp(MotionEvent e) {   // Todo auto-generated method stub   return false;  }    @OverrIDe  public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY) {   // Todo 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,"向右滑");    isScroll = true;    mCustomVIEwL.scrollRight();   } else if (delta < -distancelimit && degree < degreelimit) {    Log.d(TAG,"向左滑");    isScroll = true;    mCustomVIEwL.scrollleft();   }   return false;  }    @OverrIDe  public voID onLongPress(MotionEvent e) {   // Todo auto-generated method stub     }  @OverrIDe  public boolean onFling(MotionEvent e1,float veLocityX,float veLocityY) {   // Todo auto-generated method stub   return false;  }   } @OverrIDe public boolean ontouch(VIEw v,MotionEvent event) {  // Todo auto-generated method stub  return mGestureDetector.ontouchEvent(event); }}

CustomVIEwL.java:

自定义的控件,继承自linearLayout。在onLayout里面,重新计算了下各个子控件的位置,因为各组文字的scale是不一样的,必须重新Layout一下各个子控件的位置,是文字的显示区域和点击区域是一样的,这样给各个子控件设置的onClick事件才有效。

dispatchDraw方法是重绘各个子控件,更具各个子控件到中心控件的位置的距离,设置了各个TextVIEw X方向的scale,为了就是看着要有一个立体的效果。

滑动之后,开始一个动画,动画结束之后重新requestLayout一下,重新计算下各个控件的位置。这个可以连续滑动的,如果这次动画在执行,会保存一下,等动画完了之后会接着跑下一个动画。各个子控件滑动距离的计算有兴趣的可以自己研究下,这里就不赘述了,其实也是数学知识。 

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(Context context) {  super(context);  // Todo auto-generated constructor stub  initVIEw(context); }  public CustomVIEwL(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes) {  super(context,attrs,defStyleAttr,defStyleRes);  initVIEw(context); } public CustomVIEwL(Context context,int defStyleAttr) {  super(context,defStyleAttr);  initVIEw(context); } public CustomVIEwL(Context context,AttributeSet attrs) {  super(context,attrs);  initVIEw(context); }  private voID initVIEw(Context context) {  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.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) {    ((TextVIEw)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 = mCurrentItem - 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) {     currentItemcopy = 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 TextVIEw(getContext());   mTextVIEw.setText(name[i]);   mTextVIEw.setTextcolor(color.WHITE);   mTextVIEw.setlines(1);   linearLayout.LayoutParams ll = new linearLayout.LayoutParams(     linearLayout.LayoutParams.WRAP_CONTENT,linearLayout.LayoutParams.WRAP_CONTENT);   ll.set@R_502_5553@s(20,20,0);   addVIEw(mTextVIEw,ll);  } }  class myAnimationListener implements androID.vIEw.animation.Animation.AnimationListener {  @OverrIDe  public voID onAnimationStart(Animation animation) {   Log.d(TAG,"onAnimationStart ");   mAnimationRunning = true;  }  @OverrIDe  public voID onAnimationEnd(Animation animation) {   // Todo auto-generated method stub   Log.d(TAG,"onAnimationEnd ");   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;    }   } 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);   translateAni.setDuration(AnimitionDurationTime);   translateAni.setFillAfter(true);   if (i == item) translateAni.setAnimationListener(new myAnimationListener());   mAnimationRunning = true;   getChildAt(i).startAnimation(translateAni);  } }}

最后说一下布局文件,两边本来是要做一个阴影效果的,为了简便,复习了下PS,就在上面盖了张图片,显得两边有阴影。  

<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_content"   >     </com.example.androIDcustomnvIEw.CustomVIEwL>  <ImageVIEw    androID:layout_wIDth="wrap_content"   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>

整个来说其实也不复杂,有好些数学计算,几何问题,效果也没达到iphone的效果,如果有大神有想法,可以指导下。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android实现IOS相机滑动控件全部内容,希望文章能够帮你解决Android实现IOS相机滑动控件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1148739.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存