本文转载自:http://blog.csdn.net/harvic880925/article/details/39585347
一、基本实现
ViewFlipper是一个切换控件,一般用于图片的切换,当然它是可以添加View的,而不限定只用于ImageView,当然我们也可以自定义View,只是我们经常利用ViewFlipper来实现的是ImageView的切换,如果切换自定义的View,倒还不如使用ViewPager来做。
下面先看一下实现的效果:(实现四张图片的自动切换)
1、在XML中的布局:
- <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" >
- <ViewFlipper
- android:id="@+id/flipper"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_marginTop="10dp"
- android:flipInterval="2000" >
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_1"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_2"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_3"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_4"/>
- </ViewFlipper>
- </RelativeLayout>
2、JAVA代码:
- public class MainActivity extends Activity {
- ViewFlipper flipper;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- flipper = (ViewFlipper) findViewById(R.id.flipper);
- flipper.startFlipping();
- }
- }
可见,ViewFlipper使用起来非常简单,直接在xml中布好以后,直接就能用了。
源码在文章底部提供下载;
二、高级实现——实现手势滑动
这部分根据用户向左,向右滑的手拔势来判断当前是显示前一张图片,还是后一张图片,效果图如下:
找到了一个Gif录像工具:http://blog.bahraniapps.com/gifcam/ 挺好,还不需要安装。
首先,这里涉及到两个方面的内容:
(1)显示ViewFlipper中,当前图片的上一张,和下一张图片的接口:
- ViewFlipper::showNext(); //显示下一个视图
- ViewFlipper::showPrevious(); //显示上一个视图
这里要用到GestureDetector,我这里也会简单提一下GestureDetector的使用方法,更详细的请参看《用户手势检测-GestureDetector使用详解》
1、XML中布局不变:
- <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" >
- <ViewFlipper
- android:id="@+id/flipper"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_marginTop="10dp"
- android:flipInterval="2000" >
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_1"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_2"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_3"/>
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="300dip"
- android:scaleType="fitXY"
- android:src="@drawable/img_4"/>
- </ViewFlipper>
- </RelativeLayout>
2、JAVA代码
同样,先给出完整代码,然后逐步讲解:- public class MainActivity extends Activity implements OnTouchListener {
- private ViewFlipper mFlipper;
- private GestureDetector mDetector; //手势检测
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mFlipper = (ViewFlipper) findViewById(R.id.flipper);
- mFlipper.setOnTouchListener(this);
- mDetector = new GestureDetector(new simpleGestureListener());
- }
- public boolean onTouch(View v, MotionEvent event) {
- return mDetector.onTouchEvent(event);
- }
- private class simpleGestureListener extends GestureDetector.SimpleOnGestureListener{
- final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
- //不知道为什么,不加上onDown函数的话,onFling就不会响应,真是奇怪
- @Override
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- Toast.makeText(MainActivity.this, "ondown", Toast.LENGTH_SHORT).show();
- return true;
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // Fling left
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- mFlipper.showNext();
- Toast.makeText(MainActivity.this, "Fling Left", Toast.LENGTH_SHORT).show();
- } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Fling right
- mFlipper.showPrevious();
- Toast.makeText(MainActivity.this, "Fling Right", Toast.LENGTH_SHORT).show();
- }
- return true;
- }
- }
- }
根据《用户手势检测-GestureDetector使用详解》 中GestureDector的四步走策略来看这段代码:
(1) 创建OnGestureListener监听函数:我们这里使用SimpleOnGestureListener类来实现监听函数,因为这里不需要必须写出接口中的所有没必要的函数,(不知道为什么,我这里必须要实现OnDown函数,如果没有这个函数的重写,OnFling就不会响应,真是奇怪),然后在OnFling中根据X轴方向移动的距离和速度来判断当前用户是向左滑还是向右滑,从而利用showPrevious()或者showNext()来显示上一张或者下一张图片。关于这一部分代码,如果有不理解的同学,还是乖乖看 《用户手势检测-GestureDetector使用详解》这篇文章吧,这段代码在这篇文章的第五部分(五、OnFling应用——识别向左滑还是向右滑)
- private class simpleGestureListener extends GestureDetector.SimpleOnGestureListener{
- final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
- //不知道为什么,不加上onDown函数的话,onFling就不会响应,真是奇怪
- @Override
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- Toast.makeText(MainActivity.this, "ondown", Toast.LENGTH_SHORT).show();
- return true;
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // Fling left
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- mFlipper.showNext();
- Toast.makeText(MainActivity.this, "Fling Left", Toast.LENGTH_SHORT).show();
- } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Fling right
- mFlipper.showPrevious();
- Toast.makeText(MainActivity.this, "Fling Right", Toast.LENGTH_SHORT).show();
- }
- return true;
- }
- }
- private GestureDetector mDetector;
- public boolean onTouch(View v, MotionEvent event) {
- return mDetector.onTouchEvent(event);
- }
- mFlipper = (ViewFlipper) findViewById(R.id.flipper);
- mFlipper.setOnTouchListener(this);
根据这四步,代码也就结束了。
源码在文章底部提供下载;
但我们这里有个问题在于,我们这里的ImageView是写死的,但我们在使用中一般是要动态加入ImageView的,这就是下面的内容喽。
三、动态添加图片
上面,我们都是在ViewFlipper里直接加入ImageView来实现本地加载的VIew序列,但在程序中,我们一般是要动态加载View的,动态加载View,用到了ViewFlipper::addView函数。下面在上面的例子基础上更改一下,实现同样的功能:
1、XML代码:
- <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.viewflipperpart3.MainActivity" >
- <ViewFlipper
- android:id="@+id/flipper"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_marginTop="10dp"
- android:flipInterval="2000" />
- </RelativeLayout>
- public class MainActivity extends Activity implements OnTouchListener {
- private ViewFlipper mFlipper;
- private GestureDetector mDetector; //手势检测
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mFlipper = (ViewFlipper) findViewById(R.id.flipper);
- mFlipper.addView(getImageView(R.drawable.img_1));
- mFlipper.addView(getImageView(R.drawable.img_2));
- mFlipper.addView(getImageView(R.drawable.img_3));
- mFlipper.addView(getImageView(R.drawable.img_4));
- mFlipper.setOnTouchListener(this);
- mDetector = new GestureDetector(new simpleGestureListener());
- }
- private ImageView getImageView(int id){
- ImageView imageView = new ImageView(this);
- imageView.setImageResource(id);
- return imageView;
- }
- public boolean onTouch(View v, MotionEvent event) {
- return mDetector.onTouchEvent(event);
- }
- private class simpleGestureListener extends GestureDetector.SimpleOnGestureListener{
- final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
- //不知道为什么,不加上onDown函数的话,onFling就不会响应,真是奇怪
- @Override
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- Toast.makeText(MainActivity.this, "ondown", Toast.LENGTH_SHORT).show();
- return true;
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // Fling left
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- mFlipper.showNext();
- Toast.makeText(MainActivity.this, "Fling Left", Toast.LENGTH_SHORT).show();
- } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Fling right
- mFlipper.showPrevious();
- Toast.makeText(MainActivity.this, "Fling Right", Toast.LENGTH_SHORT).show();
- }
- return true;
- }
- }
- }
- private ImageView getImageView(int id){
- ImageView imageView = new ImageView(this);
- imageView.setImageResource(id);
- return imageView;
- }
- mFlipper = (ViewFlipper) findViewById(R.id.flipper);
- mFlipper.addView(getImageView(R.drawable.img_1));
- mFlipper.addView(getImageView(R.drawable.img_2));
- mFlipper.addView(getImageView(R.drawable.img_3));
- mFlipper.addView(getImageView(R.drawable.img_4));