经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
【Android初级】如何实现一个比相册更高大上的左右滑动特效(附源码)
来源:cnblogs  作者:snowyeti  时间:2021/2/18 14:52:03  对本文有异议

在Android里面,想要实现一个类似相册的左右滑动效果,我们除了可以用Gallery、HorizontalScrollView、ViewPager等控件,还可以用一个叫做 ViewFlipper 的类来代替实现,它继承于 ViewAnimator。如见其名,这个类是跟动画有关,会将添加到它里面的两个或者多个View做一个动画,然后每次只显示一个子View,通过在 View 之间切换时执行动画,最终达到一个类似相册能左右滑动的效果。

本次功能要实现的两个基本效果

  1. 最基本的左右滑动效果
  2. 从屏幕的45度方向进入和退出的效果

实现思路

  1. 按照 ViewFlipper 的源码说明,它是将两个或多个View用动画展示出来。那么我就在 ViewFlipper 内放入两个布局,每个布局都包含一个 TextView 和 ImageView,分别用于显示文字和图片
  2. 既然要有动画效果,我准备使用Android的位移动画类 TranslateAnimation,设置起始的横纵坐标值
  3. 为了让效果明显,我会设置 ViewFlipper 的进入和退出屏幕的动画,并且在左滑时呈现一个动画、右滑时呈现另一个动画(需要判断是左滑还是右滑:重写 onTouchEvent 方法,比较横坐标X的值的变化)

源码如下:

1、主Activity

  1. // import语句省略
  2. public class ViewFlipperDemo extends Activity {
  3. private static final String TAG = "ViewFlipperDemo";
  4. private ViewFlipper mViewFlipper;
  5. private float mOldTouchValue;
  6. @Override
  7. protected void onCreate(Bundle onSavedInstance) {
  8. super.onCreate(onSavedInstance);
  9. // 设置为全屏
  10. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  11. requestWindowFeature(Window.FEATURE_NO_TITLE);
  12. setContentView(R.layout.view_flipper_demo);
  13. mViewFlipper = findViewById(R.id.viewFlipper1);
  14. }
  15. @Override
  16. public boolean onTouchEvent(MotionEvent event) {
  17. switch (event.getAction()) {
  18. case MotionEvent.ACTION_DOWN:
  19. mOldTouchValue = event.getX();
  20. break;
  21. case MotionEvent.ACTION_UP:
  22. float currentX = event.getX();
  23. // 手指向右滑动: 手指向右滑动时横坐标 X 的值会变大,因此 currentX 的值更大
  24. if (mOldTouchValue < currentX) {
  25. // 进入屏幕的动效
  26. mViewFlipper.setInAnimation(AnimationHelper.inFromLeftAnimation());
  27. // 退出屏幕的动效
  28. mViewFlipper.setOutAnimation(AnimationHelper.outToRightAnimation());
  29. mViewFlipper.showNext();
  30. }
  31. // 横坐标的值变小,说明是左滑
  32. if (mOldTouchValue > currentX) {
  33. // 进入屏幕的动效
  34. mViewFlipper.setInAnimation(AnimationHelper.inFromRightAnimation());
  35. // 退出屏幕的动效
  36. mViewFlipper.setOutAnimation(AnimationHelper.outToLeftAnimation());
  37. mViewFlipper.showPrevious();
  38. }
  39. break;
  40. default:
  41. break;
  42. }
  43. return super.onTouchEvent(event);
  44. }
  45. }

2、对应的布局文件 view_flipper_demo.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical">
  5. <TextView android:layout_width="match_parent"
  6. android:layout_height="wrap_content"
  7. android:textColor="@color/colorBlack"
  8. android:gravity="center"
  9. android:text="这是一个ViewFlipper样例"
  10. android:paddingTop="20dp"/>
  11. <ViewFlipper android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:id="@+id/viewFlipper1">
  14. <LinearLayout android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:orientation="vertical"
  17. android:gravity="center">
  18. <TextView android:layout_width="match_parent"
  19. android:layout_height="wrap_content"
  20. android:textColor="@color/colorBlue"
  21. android:gravity="center"
  22. android:text="这是第一个ViewFlipper页面"/>
  23. <ImageView android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:src="@drawable/avasterdr"/>
  26. </LinearLayout>
  27. <LinearLayout android:layout_width="match_parent"
  28. android:layout_height="match_parent"
  29. android:orientation="vertical"
  30. android:gravity="center" >
  31. <TextView android:layout_width="match_parent"
  32. android:layout_height="wrap_content"
  33. android:textColor="@color/colorBlue"
  34. android:gravity="center"
  35. android:text="这是第二个ViewFlipper页面"/>
  36. <ImageView android:layout_width="wrap_content"
  37. android:layout_height="wrap_content"
  38. android:src="@drawable/avastertony"/>
  39. </LinearLayout>
  40. </ViewFlipper>
  41. </LinearLayout>

3、动画辅助类 AnimationHelper.java

  1. public class AnimationHelper {
  2. // 左滑的进入动画
  3. public static Animation inFromRightAnimation() {
  4. Animation inFromRight = new TranslateAnimation(
  5. Animation.RELATIVE_TO_PARENT,
  6. 1.0f,
  7. Animation.RELATIVE_TO_PARENT,
  8. 0.0f,
  9. Animation.RELATIVE_TO_PARENT,
  10. 0.0f,
  11. Animation.RELATIVE_TO_PARENT,
  12. 0.0f);
  13. inFromRight.setDuration(500);
  14. inFromRight.setInterpolator(new AccelerateInterpolator());
  15. return inFromRight;
  16. }
  17. // 左滑的退出动画
  18. public static Animation outToLeftAnimation() {
  19. Animation outToLeft = new TranslateAnimation(
  20. Animation.RELATIVE_TO_PARENT,
  21. 0.0f,
  22. Animation.RELATIVE_TO_PARENT,
  23. -1.0f,
  24. Animation.RELATIVE_TO_PARENT,
  25. 0.0f,
  26. Animation.RELATIVE_TO_PARENT,
  27. 0.0f);
  28. outToLeft.setDuration(500);
  29. outToLeft.setInterpolator(new AccelerateInterpolator());
  30. return outToLeft;
  31. }
  32. // 右滑的进入动画
  33. public static Animation inFromLeftAnimation() {
  34. Animation inFromLeft = new TranslateAnimation(
  35. Animation.RELATIVE_TO_PARENT,
  36. -1.0f,
  37. Animation.RELATIVE_TO_PARENT,
  38. 0.0f,
  39. Animation.RELATIVE_TO_PARENT,
  40. 0.0f,
  41. Animation.RELATIVE_TO_PARENT,
  42. 0.0f);
  43. inFromLeft.setDuration(500);
  44. inFromLeft.setInterpolator(new AccelerateInterpolator());
  45. return inFromLeft;
  46. }
  47. // 右滑的退出动画
  48. public static Animation outToRightAnimation() {
  49. Animation outToRight = new TranslateAnimation(
  50. Animation.RELATIVE_TO_PARENT,
  51. 0.0f,
  52. Animation.RELATIVE_TO_PARENT,
  53. 1.0f,
  54. Animation.RELATIVE_TO_PARENT,
  55. 0.0f,
  56. Animation.RELATIVE_TO_PARENT,
  57. 0.0f);
  58. outToRight.setDuration(500);
  59. outToRight.setInterpolator(new AccelerateInterpolator());
  60. return outToRight;
  61. }
  62. }

4、对应的效果图如下

可以看到,这个左右滑动效果没有任何酷炫的地方。我们不妨先来看看跟动画相关的几个重点地方:

(1)函数 setInAnimation:是指 View 进入屏幕的动效

(2)函数 setOutAnimation:是指 View 退出屏幕的动效

(3)TranslateAnimation的构造函数的参数解释:

1、fromXType/toXType/fromYType/toYType,取值共有三个:

  • Animation.ABSOLUTE
  • Animation.RELATIVE_TO_SELF
  • Animation.RELATIVE_TO_PARENT

我这里用的是 Animation.RELATIVE_TO_PARENT,当传入该参数时,其余几个坐标值需要传入百分比参数(1.0表示100%);如果传入 Animation.ABSOLUTE,坐标值需要传入屏幕上的绝对位置(比如1000,1000)

2、fromXValue:起点的横坐标值

3、toXValue:终点的横坐标值

4、fromYValue:起点的纵坐标值

5、toYValue:终点的纵坐标值

如果我们想让这个效果变成45度从屏幕的四个角进入和退出,那代码就应该这么写(注意代码中传入的 4 个横纵坐标值):

  1. // 左滑的进入动画
  2. public static Animation inFromRightAnimation() {
  3. Animation inFromRight = new TranslateAnimation(
  4. Animation.RELATIVE_TO_PARENT,
  5. 1.0f,
  6. Animation.RELATIVE_TO_PARENT,
  7. 0.0f,
  8. Animation.RELATIVE_TO_PARENT,
  9. -1.0f,
  10. Animation.RELATIVE_TO_PARENT,
  11. 0.0f);
  12. inFromRight.setDuration(500);
  13. inFromRight.setInterpolator(new AccelerateInterpolator());
  14. return inFromRight;
  15. }
  16. // 左滑的退出动画
  17. public static Animation outToLeftAnimation() {
  18. Animation outToLeft = new TranslateAnimation(
  19. Animation.RELATIVE_TO_PARENT,
  20. 0.0f,
  21. Animation.RELATIVE_TO_PARENT,
  22. -1.0f,
  23. Animation.RELATIVE_TO_PARENT,
  24. 0.0f,
  25. Animation.RELATIVE_TO_PARENT,
  26. 1.0f);
  27. outToLeft.setDuration(500);
  28. outToLeft.setInterpolator(new AccelerateInterpolator());
  29. return outToLeft;
  30. }
  31. // 右滑的进入动画
  32. public static Animation inFromLeftAnimation() {
  33. Animation inFromLeft = new TranslateAnimation(
  34. Animation.RELATIVE_TO_PARENT,
  35. -1.0f,
  36. Animation.RELATIVE_TO_PARENT,
  37. 0.0f,
  38. Animation.RELATIVE_TO_PARENT,
  39. -1.0f,
  40. Animation.RELATIVE_TO_PARENT,
  41. 0.0f);
  42. inFromLeft.setDuration(500);
  43. inFromLeft.setInterpolator(new AccelerateInterpolator());
  44. return inFromLeft;
  45. }
  46. // 右滑的退出动画
  47. public static Animation outToRightAnimation() {
  48. Animation outToRight = new TranslateAnimation(
  49. Animation.RELATIVE_TO_PARENT,
  50. 0.0f,
  51. Animation.RELATIVE_TO_PARENT,
  52. 1.0f,
  53. Animation.RELATIVE_TO_PARENT,
  54. 0.0f,
  55. Animation.RELATIVE_TO_PARENT,
  56. 1.0f);
  57. outToRight.setDuration(500);
  58. outToRight.setInterpolator(new AccelerateInterpolator());
  59. return outToRight;
  60. }

对应的效果如下:

之所以有 -1.0f 这个值,是因为屏幕上的横纵坐标值的分布可以用如下象限来表示:

ViewFlipper中的 View 就位于象限的中心位置。因此,如果动画从左上角进入,那么它的起始横纵坐标就是(-1,-1)。大家可以按照这个思路去实现自己想要的动效。

欢迎交流~

原文链接:http://www.cnblogs.com/snowyeti/p/14364658.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号