简介
ViewAnimator是一个基类,继承来了FrameLayout,因此它表现出帧布局的特征,可以将多个View组件叠在一起,它所额外增加的功能是:在View切换时表现出动画效果。
它的子类有ViewSwitcher、ViewFlipper、ImageSwitcher、TextSwitcher。
一般采用ViewAnimator的子类。
常用的XML属性
XML属性 | 说明 |
---|---|
android:animateFirstView | 设置ViewAnimator显示第一个View组件时是否显示动画 |
android:inAnimation | 设置ViewAnimator显示组件时所使用的动画 |
android:outAnimation | 设置ViewAnimator隐藏组件时所使用的动画 |
ViewSwitcher
ViewSwitcher是ImageSwitcher、TextSwitcher的父类,代表了视图切换组件,可以将多个View重叠在一起,每次只显示一个组件,当程序从一个View切换到另一个View,ViewSwitcher支持指定动画效果。
示例:
做一个简单的图片浏览器
实现过程:
1 在xml布局文件中添加ViewSwitcher组件,和Button按钮,以控制翻页。
activity_test1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewSwitcher
android:id="@+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ViewSwitcher>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="next"
android:text="下一个"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="prev"
android:text="上一个"/>
</LinearLayout>
</LinearLayout>
2 创建一个布局文件,给ViewSwitcher中每一个View设置的布局。
slideimage2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/slideimg">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是图片"
android:textSize="20sp"
android:id="@+id/slidetx">
</TextView>
</LinearLayout>
3 回到java文件中,获取到ViewSwitcher组件,并初始化变量。
private ViewSwitcher viewSwitcher;
viewSwitcher = (ViewSwitcher)findViewById(R.id.viewSwitcher);
4 给ViewSwitcher设置一个Factory,使用LayoutInflater.from(this). inflate(R.layout.slideimage,null)将xml布局文件转化为一个View对象,供makeView()方法使用。
viewSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
return inflater.inflate(R.layout.slideimage2,null);
}
});
5 设置next和prev方法,用于控制上下翻页,这里注意控制边界,然后给ViewSwitcher设置动画,由于自带的动画只有从左淡入,从右淡出,可以用于向前翻页,向后翻页应是相反的,所以需要自定义动画效果。
public void next(View view){
if(count>=images.length-1)
count=-1;
viewSwitcher.setInAnimation(this,R.anim.slide_in_right);
viewSwitcher.setOutAnimation(this,R.anim.slide_out_left);
ImageView img = viewSwitcher.getNextView().findViewById(R.id.slideimg);
img.setImageResource(images[++count]);
TextView tv = viewSwitcher.getNextView().findViewById(R.id.slidetx);
tv.setText("我是图片"+(count+1));
viewSwitcher.showNext();
}
public void prev(View view){
if(count<1)
count = images.length;
viewSwitcher.setInAnimation(this,android.R.anim.slide_in_left);
viewSwitcher.setOutAnimation(this,android.R.anim.slide_out_right);
ImageView img = viewSwitcher.getNextView().findViewById(R.id.slideimg);
img.setImageResource(images[--count]);
TextView tv = viewSwitcher.getNextView().findViewById(R.id.slidetx);
tv.setText("我是图片"+(count+1));
viewSwitcher.showPrevious();
}
建立动画资源文件:
slide_in_right.xml
<?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="@android:integer/config_mediumAnimTime"
/>
</set>
slide_out_left.xml
<?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="@android:integer/config_mediumAnimTime"/>
</set>
6 然后使用SimpleOnGestureListener给图片浏览器手势滑动功能。
gestureDetector = new GestureDetector(this,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityX > 0)
prev(null);
if (velocityX < 0)
next(null);
return super.onFling(e1, e2, velocityX, velocityY);
}
});
Test1Activity类里:
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
7 完整java代码
public class Test1Activity extends AppCompatActivity{
GestureDetector gestureDetector = null;
private ViewSwitcher viewSwitcher;
private int count = -1;
int [] images = new int[]{
R.drawable.img5,
R.drawable.img6,
R.drawable.img7,
R.drawable.img4
};
private LayoutInflater inflater;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
inflater = LayoutInflater.from(this);
viewSwitcher = (ViewSwitcher)findViewById(R.id.viewSwitcher);
viewSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
return inflater.inflate(R.layout.slideimage2,null);
}
});
next(null);
gestureDetector = new GestureDetector(this,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityX > 0)
prev(null);
if (velocityX < 0)
next(null);
return super.onFling(e1, e2, velocityX, velocityY);
}
});
}
public void next(View view){
if(count>=images.length-1)
count=-1;
viewSwitcher.setInAnimation(this,R.anim.slide_in_right);
viewSwitcher.setOutAnimation(this,R.anim.slide_out_left);
ImageView img = viewSwitcher.getNextView().findViewById(R.id.slideimg);
img.setImageResource(images[++count]);
TextView tv = viewSwitcher.getNextView().findViewById(R.id.slidetx);
tv.setText("我是图片"+(count+1));
viewSwitcher.showNext();
}
public void prev(View view){
if(count<1)
count = images.length;
viewSwitcher.setInAnimation(this,android.R.anim.slide_in_left);
viewSwitcher.setOutAnimation(this,android.R.anim.slide_out_right);
ImageView img = viewSwitcher.getNextView().findViewById(R.id.slideimg);
img.setImageResource(images[--count]);
TextView tv = viewSwitcher.getNextView().findViewById(R.id.slidetx);
tv.setText("我是图片"+(count+1));
viewSwitcher.showPrevious();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
}
ImageSwitcher和TextSwitcher
它们都继承了ViewSwitcher,因此具有一些共同更多特征,都可以在切换View组件时使用动画效果,ImageSwitcher的View组件必须是ImageView,TextSwitcher的View组件必须是TextView。
ImageView使用方法:
1. 为ImageSwitcher提供一个ViewFactory,该ViewFactory生成的View组件必须是ImageView。
2. 需要切换图片时,只需要调用ImageSwitcher的setImageDrawable()、setImageResource()、setImageURI()方法更换图片即可,注意不能有showNext()和showPreview()方法。
示例:
activity_test1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageSwitcher
android:id="@+id/imageSwitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inAnimation="@android:anim/fade_in"
android:outAnimation="@android:anim/fade_out">
</ImageSwitcher>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="next"
android:text="下一个"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="prev"
android:text="上一个"/>
</LinearLayout>
</LinearLayout>
Test1Activity.java
public class Test1Activity extends AppCompatActivity{
GestureDetector gestureDetector = null;
private ImageSwitcher imageSwitcher;
private int count = -1;
int [] images = new int[]{
R.drawable.img5,
R.drawable.img6,
R.drawable.img7,
R.drawable.img4
};
private LayoutInflater inflater;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
inflater = LayoutInflater.from(this);
imageSwitcher = (ImageSwitcher)findViewById(R.id.imageSwitcher);
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
//这里直接new了一个ImageView,也可以类似上个例子,从xml中加载布局
return new ImageView(getApplicationContext());
}
});
next(null);
gestureDetector = new GestureDetector(this,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityX > 0)
prev(null);
if (velocityX < 0)
next(null);
return super.onFling(e1, e2, velocityX, velocityY);
}
});
}
public void next(View view){
if(count>=images.length-1)
count=-1;
imageSwitcher.setImageResource(images[++count]);
}
public void prev(View view){
if(count<1)
count = images.length;
imageSwitcher.setImageResource(images[--count]);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
}
TextSwitcher的使用方法类似,在makeView方法中把ImageView换成TextView就可以了。
ViewFlipper
ViewFlipper组件继承了ViewAnimator,它调用addView(View view)添加多个组件,给ViewFlipper添加多个组件之后,就可以使用动画控制多个组件之间的切换效果了。
ViewFlipper与AdapterViewFlipper类似,都可以控制组件的切换效果,区别是ViewFlipper通过addView方法添加多个View,而AdapterViewFlipper则只要传入一个adapter就可以了。
示例:
用ViewFlipper浏览图片