ViewFlipper和AdapterViewFlipper是Android自带的一个多页面管理控件,下面这篇文章主要给大家介绍了关于Android中ViewFlipper和AdapterViewFlipper使用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
目录
一、ViewFlipper
在很多APP都有如下的公告通知效果(上下自动翻滚)

这种效果可以使用很多方式实现,有一个简便的方式可以使用ViewFlipper控件实现,ViewFlipper控件继承结果如下:

可以看出ViewFlipper继承自ViewAnimator,ViewAnimator可以将在添加到其中的两个或多个子View之间进行动画处理的简单。一次只显示子View。可以定期在每个子View之间自动翻转。
现在使用ViewFlipper自动上下滚动效果,非常简单,布局文件中定义ViewFlipper
... < ViewFlipper android:id = "@+id/vf_test" android:layout_width = "match_parent" android:layout_height = "50dip" android:autoStart = "true" android:background = "#00dd00" android:inAnimation = "@anim/anim_in" android:outAnimation = "@anim/anim_out" > < TextView android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center_vertical" android:paddingLeft = "10dip" android:text = "这第1条消息." android:textSize = "20sp" android:textStyle = "bold" /> < TextView android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center_vertical" android:paddingLeft = "10dip" android:text = "这第2条消息.." android:textSize = "20sp" android:textStyle = "bold" /> </ ViewFlipper > ...
|
显示效果如下:

默认ViewFlipper是无动画,这里通过inAnimation、outAnimation配置来子View进入和移出动画,
inAnimation动画配置如下文件(anim/anim_in.xml):
1 2 3 4 5 6 7 8 9 10 11 |
<? xml version = "1.0" encoding = "utf-8" ?> < set xmlns:android = "http://schemas.android.com/apk/res/android" > < translate android:duration = "400" android:fromYDelta = "100%p" android:toYDelta = "0" /> < alpha android:duration = "500" android:fromAlpha = "0.0" android:toAlpha = "1.0" /> </ set >
|
outAnimation动画配置如下文件(anim/anim_out.xml):
1 2 3 4 5 6 7 8 9 10 11 |
<? xml version = "1.0" encoding = "utf-8" ?> < set xmlns:android = "http://schemas.android.com/apk/res/android" > < translate android:duration = "400" android:fromYDelta = "0" android:toYDelta = "-100%p" /> < alpha android:duration = "500" android:fromAlpha = "1.0" android:toAlpha = "0.0" /> </ set >
|
可以看出,这里的两个动画文件均使用的是补间动画的动画集合(位移动画、透明度动画)
ViewFlipper可配置的参数:
android:autoStart : 设置显示该组件是否是自动播放(默认 false)
android:inAnimation : 设置组件进入时使用的动画
android:outAnimation : 设置组件移出时使用的动画
android:flipInterval:设置自动播放的时间间隔(ViewFlipper默认3000ms)
android:animateFirstView:设置显示该组件的第一个View时是否使用动画(默认true,可以手动向空的ViewFlipper addView 方式添加View看到效果)
ViewFlipper可以通过代码设置上述配置(不再列举),也可以通过代码来控制播放,具体api如下:
startFlipping() :开始播放
stopFlipping() : 停止播放
通常情况下我们滚动的内容是服务器下发的,所以个数无法得知,如果个数少的情况,使用ViewFlipper展示此效果没有什么大的问题,一但出现多数据情况,可能会出现内存上升。
例如:有10000条数据情况:
定义一个空的ViewFlipper,如下:
1 2 3 4 5 6 7 8 9 10 11 |
... < ViewFlipper android:id = "@+id/vf_test" android:layout_width = "match_parent" android:layout_height = "50dip" android:autoStart = "true" android:background = "#00dd00" android:inAnimation = "@anim/anim_in" android:outAnimation = "@anim/anim_out" > </ ViewFlipper > ...
|
每个子View布局(item_view.xml)如下:
1 2 3 4 5 6 7 |
< TextView xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center_vertical" android:paddingLeft = "10dip" android:textSize = "20sp" android:textStyle = "bold" />
|
再通过代码方式添加子View,如下:
1 2 3 4 5 6 7 8 |
... ViewFlipper vf_test = (ViewFlipper) findViewById(R.id.vf_test); for ( int i = 0 ; i < 10000 ; i++) { TextView textView = (TextView) LayoutInflater.from(DemoActivity. this ).inflate(R.layout.item_view, null ); textView.setText( "这是第" + i + "条消息" ); vf_test.addView(textView); } ...
|
运行APP可以明显看出页面卡顿来几秒后才显示,内存使用情况如下:

这里的每个item还仅为一个TextView,如果每个item布局复杂,所占用的内存更高。像这种大数据的情况,我们可以使用适配器模式的ViewFlipper(AdapterViewFlipper)来替代。
二、AdapterViewFlipper
AdapterViewFlipper的继承关系如下:

注:AdapterViewFlipper是api11(Android 3.0)中新增的,现在的APP最低支持版本肯定大于此版本,基本可以忽略。
从继承关系可以看出AdapterViewFlipper同ListView类似,都继承了AdapterView,所以AdapterViewFlipper可以像ListView一样使用数据适配器来填充数据。
先定义一个AdapterViewFlipper如下:
... < AdapterViewFlipper android:id = "@+id/avf_view" android:layout_width = "match_parent" android:layout_height = "50dip" android:autoStart = "true" android:background = "#00FF00" android:flipInterval = "3000" android:inAnimation = "@animator/anim_in" android:outAnimation = "@animator/anim_out" /> ...
|
同ViewFlipper,AdapterViewFlipper默认是无动画,这里通过inAnimation、outAnimation配置来子View进入和移出动画(注意这里只能配置单一的ObjectAnimator属性动画),这里设置了一个自动播放动画间隔(android:flipInterval)3000毫秒,因为AdapterViewFlipper默认间隔是10000毫秒,android:autoStart 同ViewFlipper设置动画是否自动播放,android:animateFirstView在AdapterViewFlipper设置是无效的。
这里AdapterViewFlipper因为继承自AdapterViewAnimator所以它也有android:loopViews(设置循环到最后一个组件后是否自动“转头”到第一个组件)配置,但是,AdapterViewFlipper设置这个属性无效,源码解释为视图翻转器应该循环浏览视图(在AdapterViewFlipper构造函数中将loopViews设置了true)
AdapterViewFlipper同ViewFlipper可以通过代码设置上述配置(不再列举),也可以通过代码来控制播放,具体api如下:
startFlipping() :开始播放
stopFlipping() : 停止播放
inAnimation动画配置如下文件(animator/anim_in.xml):
1 2 3 4 5 6 |
<? xml version = "1.0" encoding = "utf-8" ?> < objectAnimator xmlns:android = "http://schemas.android.com/apk/res/android" android:duration = "500" android:propertyName = "translationY" android:valueFrom = "150" android:valueTo = "0" />
|
这里属性动画存放在animator目录下。
outAnimation动画配置如下文件(animator/anim_out.xml):
1 2 3 4 5 6 |
<? xml version = "1.0" encoding = "utf-8" ?> < objectAnimator xmlns:android = "http://schemas.android.com/apk/res/android" android:duration = "500" android:propertyName = "translationY" android:valueFrom = "0" android:valueTo = "-150" />
|
这里的valueFrom、valueTo是移动距离(像素),如想适配,可使用代码创建属性动画计算View移动的精确距离。
AdapterViewFlipper因为继承了AdapterView,所以需要通过代码设置一个Adapter展现效果,数据适配器如下:
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 |
public class ViewFlipperAdapter extends BaseAdapter { private Context context; private List<String> data; public ViewFlipperAdapter(Context context, List<String> data) { this .context = context; this .data = data; } @Override public int getCount() { return data == null ? 0 : data.size(); } @Override public Object getItem( int position) { return data == null ? null : data.get(position); } @Override public long getItemId( int position) { return position; } @Override public View getView( int position, View convertView, ViewGroup parent) { View view; ViewHolder viewHolder; if (convertView == null ) { view = LayoutInflater.from(context).inflate(R.layout.item_view, parent, false ); viewHolder = new ViewHolder(view); view.setTag(viewHolder); } else { view = convertView; viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.tv_item.setText(data.get(position)); return view; } static class ViewHolder { public TextView tv_item; public ViewHolder(View view) { this .tv_item = view.findViewById(R.id.tv_item); } } }
|
这里使用ViewHolder做了数据适配器View缓存处理,效率更高。
这里的每个item布局(item_view)如下:
1 2 3 4 5 6 7 8 |
<? xml version = "1.0" encoding = "utf-8" ?> < TextView xmlns:android = "http://schemas.android.com/apk/res/android" android:id = "@+id/tv_item" android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center_vertical" android:textSize = "20sp" android:textStyle = "bold" />
|
最后设置数据适配器到AdapterViewFlipper上即可:
1 2 3 4 5 6 7 8 9 10 11 12 |
... AdapterViewFlipper avf_view = (AdapterViewFlipper) findViewById(R.id.avf_view); List<String> data = new ArrayList<>(); for ( int i = 0 ; i < 10000 ; i++) { data.add( "这是第" + i + "条消息" ); } ViewFlipperAdapter viewFlipperAdapter = new ViewFlipperAdapter( this , data); //也可通过代码设置动画 //avf_view.setInAnimation(ObjectAnimator.ofFloat(avf_view, View.TRANSLATION_Y,150.0f,0.0f)); //avf_view.setOutAnimation(ObjectAnimator.ofFloat(avf_view, View.TRANSLATION_Y,0.0f,-150.0f)); avf_view.setAdapter(viewFlipperAdapter); ...
|
这里直接构造了10000条数据,因为有了数据适配器,运行很轻松。
显示效果与ViewFlipper例子中基本一致,因为AdapterViewFlipper只能设置单一属性动画,所以此处没有渐变动画,只有位移动画。
内存使用情况如下:

AdapterViewFlipper继承了AdapterView,所以同ListView,也可以设置setOnItemClickListener来监听每个Item的点击事件,当然也可以在数据适配中为每一个Item设置点击事件。这里如果setOnItemClickListener设置每个Item的点击事件,默认是不回调的,因为AdapterViewFlipper父类AdapterViewAnimator中重写了onTouchEvent函数,但是在MotionEvent.ACTION_DOWN时返回值一直是false,导致onTouchEvent函数中的MotionEvent.ACTION_UP,无法回调,从而无法回调OnItemClickListener,因此要想使回调生效,只需重写onTouchEvent函数,并返回true即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class MyAdapterViewFlipper extends AdapterViewFlipper { public MyAdapterViewFlipper(Context context) { super (context); } public MyAdapterViewFlipper(Context context, AttributeSet attrs) { super (context, attrs); } public MyAdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) { super (context, attrs, defStyleAttr); } public MyAdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super (context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onTouchEvent(MotionEvent ev) { super .onTouchEvent(ev); return true ; } }
|
代码中可以使用MyAdapterViewFlipper,这样设置setOnItemClickListener就可以正常回调了。
Android ViewFlipper、AdapterViewFlipper对比
复用性
动画效果
属性配置
ViewFlipper的默认Interval为3000ms(3秒);
AdapterViewFlipper的默认Interval为10000ms(10秒);
ViewFlipper只有1条数据也执行动画,AdapterViewFlipper只有1条数据时不会执行动画;
AdapterViewFlipper比ViewFlipper多一个android:loopViews配置,但是AdapterViewFlipper设置此属性无效;
AdapterViewFlipper中设置android:animateFirstView是无效的,在ViewFlipper中设置有效;
总结
到此这篇关于Android中ViewFlipper和AdapterViewFlipper使用的文章就介绍到这了
转自:https://www.jb51.net/article/247641.htm