ViewFlipper的使用

举报
ShaderJoy 发表于 2021/12/30 01:02:57 2021/12/30
【摘要】 看一下类的继承结构,我们可以明白很多。 java.lang.Object    ↳ android.view.View      ↳ android.view.ViewGroup        ↳ android...

看一下类的继承结构,我们可以明白很多。

java.lang.Object
   ↳ android.view.View
     ↳ android.view.ViewGroup
       ↳ android.widget.FrameLayout
         ↳ android.widget.ViewAnimator
           ↳ android.widget.ViewFlipper
  它的作用是什么呢,就是一个简单的 ViewAnimator ,将添加到ViewFlipper的View形成动画。但是在一个时间点只要一个View显示。当然,也可以设置让动画自动的有规律的显示。

它不仅拥有从父类继承的字段、属性以及xml属性,他还有自己的两个xml属性:    

  1.android:autoStart  是否开启自动开始动画,值为true或false

  2.android:flipInterval  滑动的时间间隔

  

 四、公共方法

  public bool isAutoStart ()

    如果视图显示到窗口上时会自动调用startFlipping()方法,则返回true

  public bool isFlipping()

  如果子视图正在切换,则返回true 

  public bool setAutoStart (bool autoStart)

  设置视图显示到窗口上时是否会自动调用startFlipping()方法

  public bool setFlipInterval (int milliseconds)

  视图间切换的时间间隔

  参数

                            milliseconds    毫秒数

  public bool startFlipping ()

  开始在子视图间定时循环切换

  public bool stopFlipping ()

    停止切换

  通过查看 API文档可以发现,android.widget.ViewAnimator类继承至FrameLayout,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。该类有如下几个和动画相关的函数:
  
    setInAnimation:设置 View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为android.view.animation.Animation;一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID。
  • setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。
  • showNext: 调用该函数来显示FrameLayout里面的下一个View。
  • showPrevious: 调用该函数来显示FrameLayout里面的上一个View。
 
  一般不直接使用 ViewAnimator而是使用它的两个子类ViewFlipper和ViewSwitcher。
  
  ViewFlipper可以用来指定FrameLayout内多个View之间的切换效果,可以一次指定也可以每次切换的时候都指定单独的效果。该类额外提供了上面所示的几个函数。ViewFlipper是继承至FrameLayout的,所以它是一个Layout里面可以放置多个View。在示例中定义一个ViewFlipper,里面包含三View作为示例的三个屏幕,每个View中包含一张图片。
  xml布局如下:

    
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <ViewFlipper
  7. android:id="@+id/details"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:flipInterval="1000"
  11. android:inAnimation="@anim/push_left_in" <!--inAnimationoutAnimation分别指定View进出使用的动画效果-->
  12. android:outAnimation="@anim/push_left_out"
  13. android:persistentDrawingCache="animation" >
  14. <LinearLayout
  15. android:layout_width="fill_parent"
  16. android:layout_height="fill_parent"
  17. android:orientation="vertical" >
  18. <ImageView
  19. android:id="@+id/image1"
  20. android:layout_width="fill_parent"
  21. android:layout_height="wrap_content"
  22. android:src="@drawable/a" >
  23. </ImageView>
  24. </LinearLayout>
  25. <LinearLayout
  26. android:layout_width="fill_parent"
  27. android:layout_height="fill_parent"
  28. android:orientation="vertical" >
  29. <ImageView
  30. android:id="@+id/image2"
  31. android:layout_width="fill_parent"
  32. android:layout_height="wrap_content"
  33. android:src="@drawable/b" >
  34. </ImageView>
  35. </LinearLayout>
  36. <LinearLayout
  37. android:layout_width="fill_parent"
  38. android:layout_height="fill_parent"
  39. android:orientation="vertical" >
  40. <ImageView
  41. android:id="@+id/image3"
  42. android:layout_width="fill_parent"
  43. android:layout_height="wrap_content"
  44. android:src="@drawable/c" >
  45. </ImageView>
  46. </LinearLayout>
  47. </ViewFlipper>
  48. </LinearLayout></span>

push_left_in.xml文件:

    
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" >
  3. <translate
  4. android:duration="500"
  5. android:fromXDelta="100%p"
  6. android:toXDelta="0" />
  7. <alpha
  8. android:duration="500"
  9. android:fromAlpha="0.0"
  10. android:toAlpha="1.0" />
  11. </set>

push_left_out.xml文件:

    
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" >
  3. <translate
  4. android:duration="500"
  5. android:fromXDelta="0"
  6. android:toXDelta="-100%p" />
  7. <alpha
  8. android:duration="500"
  9. android:fromAlpha="1.0"
  10. android:toAlpha="0.0" />
  11. </set>

 这里注意一下,我们这用的是left,所以动画是从右向左的,当然你也可以设置从左向右。
  主Activity代码:

    
  1. public class ViewFlipperDemo extends Activity {
  2. private ViewFlipper flipper;
  3. @Override
  4. public void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_view_flipper_demo);
  7. flipper=(ViewFlipper) findViewById(R.id.details);
  8. flipper.setAutoStart(true);//自动开始,不然不会开始。
  9. }
  10. @Override
  11. public boolean onCreateOptionsMenu(Menu menu) {
  12. getMenuInflater().inflate(R.menu.activity_view_flipper_demo, menu);
  13. return true;
  14. }
  15. }

 这样 ViewFlipper就开始工作了,可以看到图片在不停的循环、从右到左的显示。这一点,Gallery就不及它了。但是,我们是无法控制页面的,它自己在循环,点击滑动都无效。所以, 如果要是能通过手势的左右滑动来实现屏幕的切换就比较优雅了。 通过 android.view.GestureDetector类可以检测各种手势事件,该类有两个回调接口分别用来通知具体的事件:
 
     GestureDetector.OnDoubleTapListener:用来通知 DoubleTap事件,类似于鼠标的双击事件,该接口有如下三个回调函数:
 
1.   onDoubleTap(MotionEvent e):通知 DoubleTap手势,
2.   onDoubleTapEvent(MotionEvent e):通知 DoubleTap手势中的事件,包含down、up和move事件(这里指的是在双击之间发生的事件,例如在同一个地方双击会产生DoubleTap手势,而在DoubleTap手势里面还会发生down和up事件,这两个事件由该函数通知);
3.   onSingleTapConfirmed(MotionEvent e):用来判定该次点击是 SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,OPhone系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
GestureDetector.OnGestureListener:用来通知普通的手势事件,该接口有如下六个回调函数:

1.   onDown(MotionEvent e): down事件;
2.   onSingleTapUp(MotionEvent e):一次点击 up事件;
3.   onShowPress(MotionEvent e): down事件发生而move或则up还没发生前触发该事件;
4.   onLongPress(MotionEvent e):长按事件;
5.   onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑动手势事件;
6.   onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上拖动事件。
 
  在上述事件中,如果在程序中处理的该事件就返回 true否则返回false,在GestureDetector中也定义了一个SimpleOnGestureListener类,这是个助手类,实现了上述的所有函数并且都返回false。如果在项目中只需要监听某个事件继承这个类可以少些几个空回调函数。
  要走上面的程序中添加滑动手势来实现屏幕切换的话,首先需要定义一个GestureDetector:
  
private GestureDetector mGestureDetector;
     
  
并在onCreate函数初始化:
  
mGestureDetector = new GestureDetector(this);
     

  参数是OnGestureListener,然后让Activity实现 OnGestureListener 和OnDoubleTapListener接口以及OnTouchListener:
  代码如下:

    
  1. public class ViewFlipperDemo extends Activity implements OnGestureListener,
  2. OnDoubleTapListener,OnTouchListener {
  3. private ViewFlipper flipper;
  4. private GestureDetector gestureDetector;
  5. private Button button;
  6. @Override
  7. public void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_view_flipper_demo);
  10. flipper = (ViewFlipper) findViewById(R.id.details);
  11. gestureDetector = new GestureDetector(this);//注册一个用于手势识别的类
  12. // flipper.setAutoStart(true);
  13. flipper.setOnTouchListener(this);
  14. flipper.setLongClickable(true); //允许长按住ViewFlipper,这样才能识别拖动等手势
  15. button=(Button) findViewById(R.id.button1);
  16. button.setOnClickListener(new OnClickListener() {
  17. public void onClick(View v) {
  18. //flipper.showNext();
  19. Intent intent=new Intent(ViewFlipperDemo.this,TestActivity.class);
  20. startActivity(intent);//进入其他Activity,没有问题
  21. }
  22. });
  23. }
  24. @Override
  25. public boolean onCreateOptionsMenu(Menu menu) {
  26. getMenuInflater().inflate(R.menu.activity_view_flipper_demo, menu);
  27. return true;
  28. }
  29. public boolean onSingleTapConfirmed(MotionEvent e) {
  30. // TODO Auto-generated method stub
  31. return false;
  32. }
  33. public boolean onDoubleTap(MotionEvent e) {
  34. // TODO Auto-generated method stub
  35. return false;
  36. }
  37. /*
  38. * 然后在onDoubleTap中实现双击自动切换的效果,再次双击则停止:
  39. *
  40. * @see
  41. * android.view.GestureDetector.OnDoubleTapListener#onDoubleTapEvent(android
  42. * .view.MotionEvent)
  43. */
  44. public boolean onDoubleTapEvent(MotionEvent e) {
  45. if (flipper.isFlipping()) {
  46. flipper.stopFlipping();
  47. } else {
  48. flipper.startFlipping();
  49. }
  50. return true;
  51. }
  52. public boolean onDown(MotionEvent e) {
  53. // TODO Auto-generated method stub
  54. return false;
  55. }
  56. public void onShowPress(MotionEvent e) {
  57. // TODO Auto-generated method stub
  58. }
  59. public boolean onSingleTapUp(MotionEvent e) {
  60. // TODO Auto-generated method stub
  61. return false;
  62. }
  63. public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  64. float distanceY) {
  65. // TODO Auto-generated method stub
  66. return false;
  67. }
  68. public void onLongPress(MotionEvent e) {
  69. // TODO Auto-generated method stub
  70. }
  71. /*
  72. * 这里实现的功能是从右往左滑动则切换到上一个View,从左往右滑动则切换到下一个View,并且使用不同的in、out 动画使切换效果看起来统一一些。
  73. *
  74. * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.
  75. * MotionEvent, android.view.MotionEvent, float, float)
  76. */
  77. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  78. float velocityY) {
  79. if (e1.getX()>e2.getX()) {
  80. flipper.showNext();
  81. } else if (e1.getX()<e2.getX()) {
  82. flipper.setInAnimation(getApplicationContext(),
  83. R.anim.push_right_in);
  84. flipper.setOutAnimation(getApplicationContext(),
  85. R.anim.push_right_out);
  86. flipper.showPrevious();
  87. flipper.setInAnimation(getApplicationContext(), R.anim.push_left_in);
  88. flipper.setOutAnimation(getApplicationContext(),
  89. R.anim.push_left_out);
  90. } else {
  91. return false;
  92. }
  93. return true;
  94. }
  95. public boolean onTouch(View v, MotionEvent event) {
  96. return this.gestureDetector.onTouchEvent(event);
  97. }
  98. }

这样就完成了ViewFlipper的介绍,总结一下。首先是他的类的继承结构,然后他的功能,利用它我们可以实现动画的滑动效果,可以点击滑动,拖动滑动,而且可以循环显示。
  最后再来测试一下ViewFlipper的监听效果,为什么这么说呢?因为在ViewPager的子布局文件,也就是我们的滑动页面,如果一个页面里面有一个Button我们想点击这个Button进入另一个Activity。那我们常规做法是在MainActivity里面实例化Button,然后设置setOnclickListener()。但是,这样做会报错的。不过这种情况在ViewFlipper里不存在,我们可以直接在MainActivity里面实例化Button,然后设置setOnclickListener(),可以进入其他的Activity。所以这也是ViewFlipper比ViewPager的一个优势。当然,ViewPager也有设置监听的解决方法,在我的关于ViewPager的文章里面有介绍,大家可以去看看

文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/8798869

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。