我学习Android都是结合源代码去学习,这样比较直观,非常清楚的看清效果,觉得很好,今天的学习源码是网上找的源码 百度搜就知道很多下载的地方 网上源码的名字叫:android gif模式和图片展现模式 图片展现神器.zip 我的博客写的比较乱,如果本篇文章没有看懂,请先看上篇文章,地址:http://blog.csdn.net/u014737138/article/details/40858705
写这篇文章的方法就是想看下ViewFlipper和ViewPager的区别
别的就不多说了,直接看代码:
1.在main.xml控件中定义这个控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ViewFlipper
android:id="@+id/viewflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
可以看到这个控件应该问世比ViewPager早的多啊!
2.定义四个动画布局,分别是向右滑进,向右滑出,向左滑进,向左滑出
左边进:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
左边出:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
右边进:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
右边出:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
看到这里面的属性,结合上面的移动动画对象的构造函数:
public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
可以看到在Android早先的版本中,它把这种翻页的效果是用xml属性来实现的,现在他把这个定义在一个移动动画对象中了,有这个对比,我们应该很清楚这个文件代表什么意思了
3.处理activity类:
A。初始化需要处理的图片:
private int[] imageID = { R.drawable.a, R.drawable.b, R.drawable.c,
R.drawable.d, R.drawable.e, R.drawable.f, R.drawable.g,
R.drawable.h };
B。定义ViewPager对象和手势对象,
private ViewFlipper viewFlipper = null;
private GestureDetector gestureDetector = null;
C。初始化处理:
viewFlipper = (ViewFlipper) this.findViewById(R.id.viewflipper);
gestureDetector = new GestureDetector(this);
把图片数据加载到viewFlipper上
// 添加用于切换的图片
for (int i = 0; i < imageID.length; i++)
{
// 定义一个ImageView对象
ImageView image = new ImageView(this);
image.setImageResource(imageID[i]);
// 充满父控件
image.setScaleType(ImageView.ScaleType.FIT_XY);
// 添加到viewFlipper中
viewFlipper.addView(image, new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
当我们new GestureDetector(this)的时候,它肯定自动的告诉你需要去继承一个接口
也就是处理滑动事件的回调函数
implements OnGestureListener
这种接口不是最好的,因为需要实现的接口有好多,很多代码都是一种浪费:如下
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
// OnGestureListener中的onFling方法就是滑动事件的回调函数
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float velocityX,
float velocityY) {
// TODO Auto-generated method stub
//对手指滑动的距离进行了计算,如果滑动距离大于120像素,就做切换动作,否则不做任何切换动作。
// 从左向右滑动
if (arg0.getX() - arg1.getX() > 120)
{
// 添加动画
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
this.viewFlipper.showNext();
return true;
}// 从右向左滑动
else if (arg0.getX() - arg1.getX() < -120)
{
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
this.viewFlipper.showPrevious();
return true;
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
其中只有public boolean onFling(MotionEvent arg0, MotionEvent arg1, float velocityX,float velocityY)
是我们需要的,它就是 OnGestureListener中的onFling方法就是滑动事件的回调函数
我们只需要去重载它就可以了
仔细看下我们是怎么重载这个函数的:
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float velocityX,
float velocityY) {
// TODO Auto-generated method stub
//对手指滑动的距离进行了计算,如果滑动距离大于120像素,就做切换动作,否则不做任何切换动作。
// 从左向右滑动
if (arg0.getX() - arg1.getX() > 120)
{
// 添加动画
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
this.viewFlipper.showNext();
return true;
}// 从右向左滑动
else if (arg0.getX() - arg1.getX() < -120)
{
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
this.viewFlipper.showPrevious();
return true;
}
return true;
}
很简单的代码,两个判断:决定是向左滑还是向右滑:
从左向右滑:if (arg0.getX() - arg1.getX() > 120)
从右向左滑:else if (arg0.getX() - arg1.getX() < -120)
那么是怎么滑的呢?就是怎么让这个图片加载出来呢,使用的是这样的代码:
// 添加动画
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
首先是去设置ViewFlipper对象,如果是向左滑,动画加载工具去加载这个动画
然后把下个视图显示出来:this.viewFlipper.showNext();
最后需要去重载下触摸事务:
@Override
public boolean onTouchEvent(MotionEvent event)
{
return this.gestureDetector.onTouchEvent(event);
}
让手势监听器去处理它,而不是系统默认的处理方式
最后看看效果是怎么样:它可以一直向左滑,滑到尽头又从末尾的那个变成开头的,也可以一直向右滑