Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)

来源:互联网 发布:张力网络营销策划 编辑:程序博客网 时间:2024/05/16 14:51
标签:Android
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://smallwoniu.blog.51cto.com/3911954/1308959

现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习惯性的有事没事的左右滑屏,也不知道在干什么。。。j_0059.gif嘿嘿),由于前段时间项目的需要,所以也对其研究了一下,总的来说滑屏实现有三种方式:(至于其他的实现方式目前后还没碰到。。。)

1.ViewPager 2.ViewFlipper 3.ViewFlow


一.ViewPager


官方文档介绍:http://developer.android.com/reference/android/support/v4/view/ViewPager.html

175956838.png


根据继承关系我们可以看出,ViewPager不在android sdk 自带jar包中,来源google 的补充组件android-support-v4.jar中,所以我们在3.0以前的版本中使用就需要导入该jar包了。


1.1 介绍该类是一个布局管理器,它允许用户通过滑动左、右页的数据。你必须要一个实现了PagerAdapter接口从而生成的页面视图。


1.2 使用:

activity_main.xml

1
2
3
4
5
6
7
8
9
10
<RelativeLayoutxmlns: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">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
</RelativeLayout>


MainActivity类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package comzhf.android_viewpager;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
 * 主界面:ViewPagerViewPager不在android sdk 自带jar包中,来源google 的补充组件android-support-v4.jar
 */
public class ViewPagerActivity extendsActivity {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    privateViewPager mViewPager;
    List<View> viewList;
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        LayoutInflater mInflater = getLayoutInflater().from(this);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        View v1 = mInflater.inflate(R.layout.layout1,null);
        View v2 = mInflater.inflate(R.layout.layout2,null);
        View v3 = mInflater.inflate(R.layout.layout3,null);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        //添加页面数据
        viewList =new ArrayList<View>();
        viewList.add(v1);
        viewList.add(v2);
        viewList.add(v3);
        //实例化适配器
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mViewPager.setAdapter(newMyPagerAdapter(viewList));
        mViewPager.setCurrentItem(0);//设置默认当前页
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        View view = viewList.get(0);
        TextView textView = (TextView) view.findViewById(R.id.text_1);
        textView.setText("我是第一页");
        Button button = (Button) view.findViewById(R.id.button_1);
        button.setOnClickListener(newOnClickListener() {
            publicvoid onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(),"你点击了按钮", Toast.LENGTH_SHORT).show();
                }
        });
    }
}


这里还有三个布局文件:layout1.xml (其余两个类似,略)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/guide01">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="叶片一"
        android:textSize="25sp"/>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    <Button
        android:id="@+id/button_1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="点击我"
        >
    </Button>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
</LinearLayout>


效果图:

183843192.png183843821.png183845132.png

补充说明:

1.这里我们用了Layout作为每个page的填充数据,其实官方文档说ViewPager+Fragment配合使用更好

2.每个页面的响应事件我们可以在OnPageChangeListener监听器类中进行捕获和处理对应事件。


二.ViewFlipper


官方文档:http://developer.android.com/reference/android/widget/ViewFlipper.html

190300918.png

2.1 介绍:ViewFilpper控件是系统自带控件之一,主要用于在同一个屏幕间的切换及设置动画效果、间隔时间,且可以自动播放。

顺便提及一下,View动画关系图:

195450865.png

2.2 使用:

2.2.1 静态加载

activity_main.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<RelativeLayoutxmlns: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/body_flipper"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#f0f0f0">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
         <include
            android:id="@+id/layout01"
            layout="@layout/page1"/>
        <include
            android:id="@+id/layout02"
            layout="@layout/page2"/>
        <include
            android:id="@+id/layout02"
            layout="@layout/page3"/>
        <include
            android:id="@+id/layout02"
            layout="@layout/page4"/>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
    </ViewFlipper>
</RelativeLayout>

MainActivity类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.zhf.android_viewflipper_view;
import android.os.Bundle;
import android.app.Activity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.AnimationUtils;
import android.widget.ViewFlipper;
/**
 * ViewFlipper 静态加载
 * @author ZHF
**/
public class MainActivity extendsActivity implementsOnTouchListener{
    privateViewFlipper viewFlipper;
    privatefloat touchDownX;  // 手指按下的X坐标
    privatefloat touchUpX;  //手指松开的X坐标
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    @Override
    publicvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        viewFlipper = (ViewFlipper) findViewById(R.id.body_flipper);
        viewFlipper.setOnTouchListener(this);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    @Override
    publicboolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            // 取得左右滑动时手指按下的X坐标
            touchDownX = event.getX();
            returntrue;
        }else if (event.getAction() == MotionEvent.ACTION_UP) {
            // 取得左右滑动时手指松开的X坐标
            touchUpX = event.getX();
            // 从左往右,看前一个View
            if(touchUpX - touchDownX > 100) {
                // 显示上一屏动画
                viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
                       R.anim.push_right_in));
                viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
                        R.anim.push_right_out));
                // 显示上一屏的View
                viewFlipper.showPrevious();
                // 从右往左,看后一个View
            }else if (touchDownX - touchUpX > 100) {
                //显示下一屏的动画
                viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
                        R.anim.push_left_in));
                viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
                        R.anim.push_left_out));
                // 显示下一屏的View
                viewFlipper.showNext();
            }
            returntrue;
        }
        returnfalse;
    }
}

动画配置文件(右进右出同理,略):

push_left_in.xml:

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

push_left_out.xml:

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

效果:

204143396.png204144556.png

向左滑屏 向右滑屏

补充

上述的page只有4个,而真实项目中的page页面个数是不确定的,所以下面这种方式是项目中经常用到的。


2.2.2 动态加载重要

参考文章:http://blog.csdn.net/yuzhiboyi/article/details/7702953

activity_main2.xml

1
2
3
4
5
6
7
8
9
10
11
<RelativeLayoutxmlns: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">
    <com.zhf.android_viewflipper_view.MyViewFlipper
        android:id="@+id/body_flipper"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#f0f0f0">
    </com.zhf.android_viewflipper_view.MyViewFlipper>
</RelativeLayout>

flipper_view.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0"encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="none">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher"/>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
        <TextView
            android:id="@+id/textView"
            android:textSize="100dip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
</ScrollView>

注:这里并不是所有的View都能有onFling回调函数,外部需要加ScrollView !

MyGestureListener类:自定义滑动事件监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.zhf.android_viewflipper_view;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
/**
 * 自定义滑动事件监听器
 * SimpleOnGestureListener已经实现了OnGestureListener接口和OnDoubleTapListener接口,
 * 可以有选择性的复写需要的方法,提供方法onFling()作为滑动事件的回调函数
 * @author ZHF
 *
 */
public class MyGestureListener extendsSimpleOnGestureListener{
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    privateOnFlingListener mOnFlingListener;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    /**用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发 **/
    @Override
    publicfinal booleanonFling(final MotionEvent e1, final MotionEvent e2,
            finalfloat speedX, finalfloat speedY) {
        if(mOnFlingListener == null) {
            returnsuper.onFling(e1, e2, speedX, speedY);
        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        floatXFrom = e1.getX();  //按下坐标
        floatXTo = e2.getX();
        floatYFrom = e1.getY();
        floatYTo = e2.getY();
        // 左右滑动的X轴幅度大于100,并且X轴方向的速度大于100
        if(Math.abs(XFrom - XTo) > 100.0f && Math.abs(speedX) >100.0f) {
            // X轴幅度大于Y轴的幅度
            if(Math.abs(XFrom - XTo) >= Math.abs(YFrom - YTo)) {
                if(XFrom > XTo) {
                    // 下一个
                    mOnFlingListener.flingToNext();
                }else {
                    // 上一个
                    mOnFlingListener.flingToPrevious();
                }
            }
        }else {
            returnfalse;
        }
        returntrue;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    /**自定义滑动的回调接口**/
    publicinterface OnFlingListener {
        voidflingToNext();  //滑动到下一页
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        voidflingToPrevious();  //滑动到上一页
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    publicOnFlingListener getOnFlingListener() {
        returnmOnFlingListener;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    publicvoid setOnFlingListener(OnFlingListener mOnFlingListener) {
        this.mOnFlingListener = mOnFlingListener;
    }
}


MyViewFlipper类:自定义View滑动类:监听滑动事件,并做切换视图的处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.zhf.android_viewflipper_view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ViewFlipper;
import com.zhf.android_viewflipper_view.MyGestureListener.OnFlingListener;
/**
 * 自定义View滑动类:监听滑动事件,并做切换视图的处理。
 * @author ZHF
 *
 */
public class MyViewFlipper extendsViewFlipper implementsOnFlingListener {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    //手势监听类
    privateGestureDetector mGestureDetector = null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    privateOnViewFlipperListener mOnViewFlipperListener = null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    publicMyViewFlipper(Context context) {
        super(context);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    publicMyViewFlipper(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    publicvoid setOnViewFlipperListener(OnViewFlipperListener mOnViewFlipperListener) {
        this.mOnViewFlipperListener = mOnViewFlipperListener;
        //初始化自定义滑动事件监听器
        MyGestureListener myGestureListener =new MyGestureListener();
        //绑定自定义的滑动监听器
        myGestureListener.setOnFlingListener(this);
        mGestureDetector =new GestureDetector(myGestureListener);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    @Override
    publicboolean onInterceptTouchEvent(MotionEvent ev) {
        if(null != mGestureDetector) {
            returnmGestureDetector.onTouchEvent(ev);
        }else {
            returnsuper.onInterceptTouchEvent(ev);
        }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    /**向下一条滑动事件**/
    @Override
    publicvoid flingToNext() {
        if(null != mOnViewFlipperListener) {
            intchildCnt = getChildCount();
            if(childCnt == 2) {
                removeViewAt(1);
            }
            addView(mOnViewFlipperListener.getNextView(),0);
            if(0 != childCnt) {
                setInAnimation(getContext(), R.anim.push_left_in);
                setOutAnimation(getContext(), R.anim.push_left_out);
                setDisplayedChild(0);
            }
        }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    /**向上一条滑动事件**/
    @Override
    publicvoid flingToPrevious() {
        if(null != mOnViewFlipperListener) {
            intchildCnt = getChildCount();
            if(childCnt == 2) {
                removeViewAt(1);
            }
            addView(mOnViewFlipperListener.getPreviousView(),0);
            if(0 != childCnt) {
                setInAnimation(getContext(), R.anim.push_right_in);
                setOutAnimation(getContext(), R.anim.push_right_out);
                setDisplayedChild(0);
            }
        }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    /**自定义View变化监听回调接口**/
    publicinterface OnViewFlipperListener {
        View getNextView();  //获取下一页View
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
        View getPreviousView(); //获取上一页View
    }
}

MainActivity2类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.zhf.android_viewflipper_view;
import com.zhf.android_viewflipper_view.MyViewFlipper.OnViewFlipperListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;
/**
 * ViewFlipper 动态加载
 * @author ZHF
 */
public class MainActivity2 extendsActivity implementsOnViewFlipperListener{
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
      privateMyViewFlipper myViewFlipper;
      privateint currentNumber;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        currentNumber =1//默认页号
        myViewFlipper = (MyViewFlipper) findViewById(R.id.body_flipper);
        //给ViewFlipper绑定自定义的滑动监听器
        myViewFlipper.setOnViewFlipperListener(this);
        //初始化页面数据,即View
        myViewFlipper.addView(createView(currentNumber));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    }
    /**获取下一页View**/
    @Override
    publicView getNextView() {
        currentNumber = currentNumber ==10 ? 1: currentNumber + 1;
        returncreateView(currentNumber);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
    /**获取上一页View**/
    @Override
    publicView getPreviousView() {
        currentNumber = currentNumber ==1 ? 10: currentNumber - 1;
        returncreateView(currentNumber);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
    /**更换View数据:这里是根据页号来更换textView上的文字**/
    privateView createView(intcurrentNumber) {
        LayoutInflater layoutInflater = LayoutInflater.from(this);
        ScrollView resultView = (ScrollView) layoutInflater.inflate(R.layout.flipper_view,null);
        ((TextView) resultView.findViewById(R.id.textView)).setText(currentNumber +"");
        returnresultView;
    }
}

效果图:

132603593.png--向左滑动(渐变过程不好截图)-->132604221.png

补充说明:

上述的三个类:

MyGestureListener:继承了SimpleGestureListener手势监听类, 复写了该类onFling()方法,用于监听用户按下滑动事件的处理;还自定义了滑动的回调接口OnFlingListener(包含了两个抽象方法flingToNext(),flingToPrevious)。


MyViewFlipper:是一个自定义ViewFlipper,该类首先实现和绑定了上一个类中的滑动的回调接口OnFlingListener,完成了接口中两个重要的方法。同时定义了一个View变化监听回调接口OnViewFlipperListener(包含了两个抽象方法getNextView(),getPreviousView())。


MainActivity2:加载布局,实现监听,统一处理页面数据View和滑动事件的绑定。


三.ViewFlow类


3.1介绍

ViewFlow不是google官方的api,它是gethub上的一个开源项目,利用ViewFlow可以产生视图切换的效果。ViewFlow 相当于 Android UI 部件提供水平滚动的 ViewGroup,使用 Adapter 进行条目绑定,例如ViewPager或是ViewFlipper。它提供了三个组件ViewFlow、FlowIndicator和TitleFlowIndicator,一般情况下,当你需要做一个滑动然而不确定view的数目时,可以考虑使用ViewFlow。如果你的view数目确定,使用Fragments 或兼容库里的ViewPager比较好 。


3.2使用:

A.首先下载ViewFlow开源库代码:

官方文档:https://github.com/pakerfeldt/android-viewflow

201334458.png

B.下载之后我们解压打开viewflow文件夹:

201922983.png

C.建项目将这三个类直接复制过来放项目中使用即可。

202404410.png







注:这里可能还需要一个styleable文件,直接将value文件夹下的attrs.xml拷入即可。

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.zhf.android_viewflow"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="135dp"
            android:orientation="vertical">
                                                                                                                                                                                                                                                                                                 
            <com.zhf.android_viewflow.ViewFlow
                android:id="@+id/viewflow"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                app:sidebuffer="3"/>
        </RelativeLayout>
        <com.zhf.android_viewflow.CircleFlowIndicator
            android:id="@+id/viewflowindic"
            android:layout_width="wrap_content"
            android:layout_height="140dp"
            android:layout_alignParentBottom="true"
            android:layout_gravity="center_horizontal"
            app:fadeOut="0"
            app:inactiveType="fill"
            android:paddingTop="125dp"/>
        <!--圆点指示器还支持activeColor、inactiveColor、activeType(填充或描边)、
            inactiveType(填充或描边)、
            fadeOut(设置圆点自动隐藏的秒数,若为0则不会自动隐藏)、
            radius(圆点的半径)等。
        -->
    </FrameLayout>
</LinearLayout>

注:这里需要强调一下,因为使用第三方的库组件,所以要在使用之前引入:

xmlns:app="http://schemas.android.com/apk/res/com.zhf.android_viewflow"


main_item.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:isScrollContainer="true"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:scrollbars="vertical">
<!-- isScrollContainer   设置当前View为滚动容器
    scrollbarAlwaysDrawVerticalTrack      设置是否始终显示垂直滚动条-->
    <ImageView
        android:id="@+id/imgView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal">
    </ImageView>
</LinearLayout>

MainActivity类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.zhf.android_viewflow;
import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
public class MainActivity extendsActivity {
    privateViewFlow viewFlow;
    privateCircleFlowIndicator indic;  //页表指示器
                                                                                                                                                                                                              
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                                                                                                                                                                                  
        viewFlow = (ViewFlow) findViewById(R.id.viewflow);
        //为其绑定适配器
        viewFlow.setAdapter(newImageAdapter(this),5);//初始位置5
                                                                                                                                                                                                              
        indic = (CircleFlowIndicator) findViewById(R.id.viewflowindic);
        //为viewFlow绑定页表指示器
        viewFlow.setFlowIndicator(indic);
    }
                                                                                                                                                                                                              
    /**处理转屏操作**/
    @Override
    publicvoid onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        viewFlow.onConfigurationChanged(newConfig);
    }
}


这里还有一个图片适配器:ImageAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.zhf.android_viewflow;
import com.cjf.ui.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
public class ImageAdapter extendsBaseAdapter{
                                                                                                                                                                              
    privateLayoutInflater mInflater;
    //图片资源的id
    privatestatic final int[] ids = { R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d,
        R.drawable.e, R.drawable.f, R.drawable.g, R.drawable.h};
    publicImageAdapter(Context context) {
        this.mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    @Override
    publicint getCount() {
        // TODO Auto-generated method stub
        returnids == null ? 0 :ids.length;
    }
    @Override
    publicObject getItem(intposition) {
        // TODO Auto-generated method stub
        returnposition;
    }
    @Override
    publiclong getItemId(intposition) {
        // TODO Auto-generated method stub
        returnposition;
    }
    @Override
    publicView getView(int position, View convertView, ViewGroup parent) {
                                                                                                                                                                                  
        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.image_item,null);
        }
        ((ImageView) convertView.findViewById(R.id.imgView)).setImageResource(ids[position]);
        returnconvertView;
    }
}


运行一下吧!效果图:

222917441.jpg转屏后222954776.jpg


恩,终于写完了! 希望这篇博客能帮助到大家!好累~~j_0068.gif

三个例子的源码我已总结好(独立的三个项目,压缩在一个zip里了)

下载地址:http://down.51cto.com/data/976370




      上部分中,我们已经讲解了通过系统提供的ViewFlipper来实现简单的图片滑动的效果。在这部分中,我们来讲解更加复杂的滑动界面是怎么实现的。

 
        在这部分的讲解中,我们使用了Android提供另一个非常有用的控件ViewPager。使用这个控件,需要用到google提到的一个包——android-support-v4.jar,这个包中包含了一些非常有用的类,其中就是ViewPager类来实现页面之间的切换操作,关于android-support-v4.jar的详细信息,大家可以访问google官方网站:http://developer.android.com/sdk/compatibility-library.html。
 
        具体的把Android提供的android-support-v4.jar导入工程,并add build path的方法这里不做介绍,可以参考以上提供的网址,里面会有详细的说明,步骤比较简单。
 
        下面通过两个例子来讲解一下比较复杂的滑动界面的实现。
 
一、Demo1
 
        Demo1实现的效果是我们在浏览新闻网页时经常会看到的,屏幕的上半部分是图片,下半部分是文字的介绍,而顶部是一个导航的工具栏可以供用户选择退出或者回到主菜单等。用户通过左右的滑动屏幕,实现翻页的效果。而在屏幕的最底部,会有对当前所处页面的指示标记。
 
        主布局文件main.xml的内容如下:

[代码]xml代码:

01<?xmlversion="1.0"encoding="utf-8"?>
02<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03    android:layout_width="fill_parent"
04    android:layout_height="fill_parent"
05    android:orientation="vertical">
06     
07     <LinearLayout
08        android:layout_width="fill_parent"
09        android:layout_height="wrap_content"
10        android:orientation="vertical">
11     <includeandroid:id="@+id/item_header"
12          layout="@layout/item_header"/>
13     <android.support.v4.view.ViewPager
14         android:id="@+id/myviewpager"
15         android:layout_width="fill_parent"
16         android:layout_height="wrap_content"/>
17     </LinearLayout>
18     
19     <LinearLayout
20        android:layout_width="fill_parent"
21        android:layout_height="fill_parent"
22        android:orientation="vertical">
23         
24      <RelativeLayout 
25         android:layout_width="fill_parent" 
26         android:layout_height="wrap_content" 
27         android:orientation="vertical">
28          
29       <LinearLayout 
30          android:id="@+id/mybottomviewgroup" 
31          android:layout_width="fill_parent" 
32          android:layout_height="wrap_content" 
33          android:layout_alignParentBottom="true" 
34          android:layout_marginBottom="40dp" 
35          android:gravity="center_horizontal" 
36          android:orientation="horizontal"
37           
38       </LinearLayout
39      
40      </RelativeLayout>
41     </LinearLayout>
42      
43</FrameLayout>
       
        最外层是LinearLayout,其中包括两个Linearlayout,第一个LinearLayout是显示新闻的主界面,而第二个LinearLayout是为了在底部存放指示当前界面的标记图片。值得注意的是第一个LinearLayout中包括又包括两部分,一个是通过include引入的item_header视图,一个是ViewPager控件,在这里还要注意ViewPager空间的布局方式。代码如下:

[代码]xml代码:

01<LinearLayout
02        android:layout_width="fill_parent"
03        android:layout_height="wrap_content"
04        android:orientation="vertical">
05     <includeandroid:id="@+id/item_header"
06          layout="@layout/item_header"/>
07     <android.support.v4.view.ViewPager
08         android:id="@+id/myviewpager"
09         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"/>
11     </LinearLayout>
       
        另外,在layout文件夹下还定义了item01——item06六个布局文件作为ViewPager的六个页面,在JAVA代码中会把它们分别添加进ViewPager。Item_header.xml布局定义了屏幕上方的导航栏,通过include的方式引入了main.xml布局文件。
 
        Demo1的JAVA代码如下:

[代码]java代码:

001package com.devdiv.test.ui_test_viewpager;
002 
003import java.util.ArrayList;
004import android.app.Activity;
005import android.content.Context;
006import android.os.Bundle;
007import android.os.Parcelable;
008import android.support.v4.view.PagerAdapter;
009import android.support.v4.view.ViewPager;
010import android.support.v4.view.ViewPager.OnPageChangeListener;
011import android.view.LayoutInflater;
012import android.view.View;
013import android.view.ViewGroup;
014import android.view.ViewGroup.LayoutParams;
015import android.view.Window;
016import android.widget.ImageView;
017public classUI_Test_ViewPagerActivity extendsActivity {
018  
019 privateViewPager mViewPager;
020 privateArrayList<View> mPageViews;
021 privateImageView mImageView;
022 privateImageView[] mImageViews;
023  
024 //该应用的主布局LinearLayout
025 privateViewGroup mainViewGroup;
026 //主布局底部指示当前页面的小圆点视图,LinearLayout
027 privateViewGroup indicatorViewGroup;
028  
029 //定义LayoutInflater
030 LayoutInflater mInflater;
031  
032    /** Called when the activity is first created. */
033    @Override
034    publicvoid onCreate(Bundle savedInstanceState) {
035        super.onCreate(savedInstanceState);
036        //setContentView(R.layout.main);
037         
038        //设置窗口无标题
039        requestWindowFeature(Window.FEATURE_NO_TITLE);
040         
041        //mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
042        mInflater = getLayoutInflater();
043         
044        mPageViews =new ArrayList<View>();
045        mPageViews.add(mInflater.inflate(R.layout.item01,null));
046        mPageViews.add(mInflater.inflate(R.layout.item02,null));
047        mPageViews.add(mInflater.inflate(R.layout.item03,null));
048        mPageViews.add(mInflater.inflate(R.layout.item04,null));
049        mPageViews.add(mInflater.inflate(R.layout.item05,null));
050        mPageViews.add(mInflater.inflate(R.layout.item06,null));
051         
052        mImageViews =new ImageView[mPageViews.size()];
053         
054        mainViewGroup = (ViewGroup) mInflater.inflate(R.layout.main,null);
055         
056        mViewPager = (ViewPager) mainViewGroup.findViewById(R.id.myviewpager);
057        indicatorViewGroup = (ViewGroup) mainViewGroup.findViewById(R.id.mybottomviewgroup);
058         
059        for(int i = 0; i < mImageViews.length; i++) {
060         mImageView =new ImageView(UI_Test_ViewPagerActivity.this); 
061         mImageView.setLayoutParams(newLayoutParams(20,20)); 
062         mImageView.setPadding(20,0, 20,0); 
063          
064         if(i == 0) {
065          mImageView.setBackgroundResource(R.drawable.page_indicator_focused);   
066   } else{
067    mImageView.setBackgroundResource(R.drawable.page_indicator);
068   }
069    
070         mImageViews[i] = mImageView;
071          
072         //把指示作用的远点图片加入底部的视图中
073         indicatorViewGroup.addView(mImageViews[i]);
074  }
075         
076        //注意这两种用法的区别,前者无法正常显示!!
077        //setContentView(R.layout.main);
078        setContentView(mainViewGroup);
079         
080         
081        mViewPager.setAdapter(newMyPagerAdapter());
082        mViewPager.setOnPageChangeListener(newOnPageChangeListener() {
083    
084   @Override
085   publicvoid onPageSelected(intarg0) {
086    // TODO Auto-generated method stub
087    for(int i = 0; i < mImageViews.length; i++) {
088     if(i == arg0) {
089      mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
090     } else {
091      mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
092     }
093    }
094   }
095    
096   @Override
097   publicvoid onPageScrolled(intarg0, float arg1, int arg2) {
098    // TODO Auto-generated method stub
099     
100   }
101    
102   @Override
103   publicvoid onPageScrollStateChanged(intarg0) {
104    // TODO Auto-generated method stub
105     
106   }
107  });
108         
109    }
110     
111    classMyPagerAdapter extends PagerAdapter {
112        @Override 
113        publicint getCount() { 
114            returnmPageViews.size(); 
115        
116   
117        @Override 
118        publicboolean isViewFromObject(View arg0, Object arg1) { 
119            returnarg0 == arg1; 
120        
121   
122        @Override 
123        publicint getItemPosition(Object object) { 
124            // TODO Auto-generated method stub 
125            returnsuper.getItemPosition(object); 
126        
127   
128        @Override 
129        publicvoid destroyItem(View arg0, int arg1, Object arg2) { 
130            // TODO Auto-generated method stub 
131            ((ViewPager) arg0).removeView(mPageViews.get(arg1)); 
132        
133   
134        @Override 
135        publicObject instantiateItem(View arg0, intarg1) { 
136            // TODO Auto-generated method stub 
137            ((ViewPager) arg0).addView(mPageViews.get(arg1)); 
138            returnmPageViews.get(arg1); 
139        
140   
141        @Override 
142        publicvoid restoreState(Parcelable arg0, ClassLoader arg1) { 
143            // TODO Auto-generated method stub 
144   
145        
146   
147        @Override 
148        publicParcelable saveState() { 
149            // TODO Auto-generated method stub 
150            returnnull
151        
152   
153        @Override 
154        publicvoid startUpdate(View arg0) { 
155            // TODO Auto-generated method stub 
156   
157        
158   
159        @Override 
160        publicvoid finishUpdate(View arg0) { 
161            // TODO Auto-generated method stub 
162   
163        }
164      
165    }
166     
167}
 
        其中,需要注意的是在自定义MyPagerAdapter继承自PagerAdapter,需要重写其中的一些重要方法,可以类比BaseAdapter的实现便于理解,具体实现参考API文档。

[代码]java代码:

01mImageViews = newImageView[mPageViews.size()];
02         
03        mainViewGroup = (ViewGroup) mInflater.inflate(R.layout.main,null);
04         
05        mViewPager = (ViewPager) mainViewGroup.findViewById(R.id.myviewpager);
06        indicatorViewGroup = (ViewGroup) mainViewGroup.findViewById(R.id.mybottomviewgroup);
07         
08        for(int i = 0; i < mImageViews.length; i++) {
09         mImageView =new ImageView(UI_Test_ViewPagerActivity.this); 
10         mImageView.setLayoutParams(newLayoutParams(20,20)); 
11         mImageView.setPadding(20,0, 20,0); 
12          
13         if(i == 0) {
14          mImageView.setBackgroundResource(R.drawable.page_indicator_focused);   
15   } else{
16    mImageView.setBackgroundResource(R.drawable.page_indicator);
17   }
18    
19         mImageViews[i] = mImageView;
20          
21         //把指示作用的远点图片加入底部的视图中
22         indicatorViewGroup.addView(mImageViews[i]);
23  }
 
        根据mPageViews的大小初始化ImageViews,也就是说ViewPager中存在几个Page就初始化几个圆点的图片进行相应的指示。并且根据位置,设置圆点的不同状态,出事情况下显示第一个Page,因此第一个圆点的图片是focused的状态。最后,通过indicatorViewGroup.addView(mImageViews[i])把所有圆点的图片添加到布局中,在屏幕上显示。
 
        底部圆点图片初始化并加入布局后,需要给ViewPager设置Adapter,这里使用的是我们自定义的MyPagerAdapter,然后执行setContentView操作。
 
        最后,为了是底部的圆点视图具有指示作用,需要为ViewPager设置监听器,来根据ViewPager的不同状态,改变底部圆点视图的状态。代码如下:

[代码]java代码:

01mViewPager.setOnPageChangeListener(newOnPageChangeListener() {
02    
03   @Override
04   publicvoid onPageSelected(intarg0) {
05    // TODO Auto-generated method stub
06    for(int i = 0; i < mImageViews.length; i++) {
07     if(i == arg0) {
08      mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
09     } else {
10      mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
11     }
12    }
13   }
14    
15   @Override
16   publicvoid onPageScrolled(intarg0, float arg1, int arg2) {
17    // TODO Auto-generated method stub
18     
19   }
20    
21   @Override
22   publicvoid onPageScrollStateChanged(intarg0) {
23    // TODO Auto-generated method stub
24     
25   }
26  });
27<font style="BACKGROUND-COLOR: #ffffff"face="Tahoma"></font>
 
 
        Demo1运行效果如下:
 
 
图1  Demo1运行效果1
 
 
图2  Demo1运行效果2
 
二、Demo2
       
        Demo2同样实现了左右滑动的效果,不过我们在不同的页面使用了不同的布局,这在实际的应用中也是很常见的。我们同样使用了ViewPager控件,具体方法和Demo1基本相同。
 
        不同在于,我们在两个页面中分别使用了ListView中GridView视图,并在代码中为它们分别绑定了不同的Adapter。ListView使用了简单的ArrayAdapter,显示一组数据。GridView使用了自定义的Adapter。
 
        由于Demo2和Demo1的内容非常相似,我们就不再展开分析,读者可以下载代码查看详细内容。
       
        Demo2运行效果如下:
 
 
图3  Demo2运行效果1
 
 
 
图4  Demo2运行效果2
Demo1源代码下载:UI_Test_ViewPager.rar
Demo2源代码下载:UI_Test_ViewPager3.rar

转自:http://www.devdiv.com/viewpager_-blog-20-8818.html





0 0
原创粉丝点击