ViewFlipper是安卓原生控件,平时开发中用到的次数不多,一次偶然看见的时候,发现对这个控件的印象一片空白,今天本节文章就是给自己补课,UI控件还是没有完全熟悉ε=(´ο`*)))唉!
首先,看看官方文档中的描述:
从官方文档中,我们可以看见ViewFlipper继承自ViewAnimator和FrameLayout,里面封装好了动画的实现逻辑,每次ViewFlipper中只能展现一次元素,我们可以设置ViewFlipper中的元素动态更换。
这里,笔者将使用两种ViewFlipper的实现方式,一种比较直观,另一种比较优雅,读者可以根据自己情况参考。
(1)主布局文件中放入一个ViewFlipper
这里就参数做一个说明:
autoStart——设置是否自动播放
flipInterval——设置轮播动画时间
inAnimation——设置淡入动画,这里简单设置为平移动画
outAnimation——设置淡出动画,这里简单设置为平移动画
查看ViewFlipper的官方文档,可以发现对ViewFlippr进行设置的属性有蛮多,感兴趣的读者可以参考官方文档。
(2)ViewFlipper的item布局文件
布局也比较简单,这里采用了线性布局,计划在一个ViewFlipper中实现两个item的布局。同样的布局文件,复制两份,更换里面的文字即可。
这是shape的布局文件,简单为“热点”做个形状,美观一些。
(3)主Activity代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewFlipper vf = (ViewFlipper) findViewById(R.id.vf);
vf.addView(View.inflate(this, R.layout.view_advertisement_01, null));
vf.addView(View.inflate(this, R.layout.view_advertisement_02, null));
vf.addView(View.inflate(this, R.layout.view_advertisement_03, null));
}
}
通过inflate方法,把定义好的三个item布局文件放入到ViewFlipper中,这里放入的额动作采用了ViewFlipper的addView()方法,第一个参数为view,第二个参数一般为null即可。
运行效果如图:
通过以上的三个步骤,我们简单实现了一个公告轮播的效果,但是实际上是不够优雅的,我们要展现的三组文字,分别放到了三组布局文件中,分别定义,这样有XML布局文件中大量的代码重复,例子中是只有三组,但是如果要求的轮播公告更多一点的话,XML布局文件就更加的臃肿了,如果要求更改的话……实现方式十分的不雅。
这里给出一个更为优雅的实现方式,只在XML中设置一个item的布局文件,里面的textView的text不在XML中设置,而是在Activity代码中动态的设置,这样,无论多少组item需要实现,都只要在Activity代码中进行字符串的设置即可,布局文件不需要动,就算再次修改,也十分的方便。
优雅·优雅
(1)主布局文件中放置ViewFlpper——同上
(2)仅为ViewFlipper设置一个布局文件
可以看到,里面的内容和第一次的实现方式很相似,就是第二个textView中没有设置text,这里我们把text的设置任务放在了Activity中进行,实现一个动态的布局思路。
(3)主Activity文件
public class MainActivity extends AppCompatActivity {
private Context context;
private ViewFlipper viewFlipper;
private List titles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
viewFlipper = (ViewFlipper) findViewById(R.id.vf);
initData();
setViews();
}
private void setViews() {
if (titles.size() > 0) {
//计算ViewFlipper视图的数目
int viewNum = titles.size() / 2 + 1;
for (int i = 0; i < viewNum; i++) {
//每一个视图的第一个新闻标题中集合中的下标值
final int position = i * 2;
View itemView = View.inflate(context, R.layout.item_view, null);
TextView tvTitle1 = (TextView) itemView.findViewById(R.id.tv_title1);
TextView tvTitle2 = (TextView) itemView.findViewById(R.id.tv_title2);
LinearLayout ll = (LinearLayout) itemView.findViewById(R.id.ll_second);
//得到textView实例之后,用集合中的数据进行填充,通过循环完成
tvTitle1.setText(titles.get(position));
//判断第二行是否有数据,这里考虑进奇数视图的情况
if (position + 1 < titles.size()) {
tvTitle2.setText(titles.get(position + 1));
} else {
//表示该视图的第二个标题没有数据,隐藏第二行布局
ll.setVisibility(View.GONE);
}
//标题1的点击事件
tvTitle1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, titles.get(position), Toast.LENGTH_SHORT).show();
}
});
//标题2的点击事件
tvTitle2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, titles.get(position + 1), Toast.LENGTH_SHORT).show();
}
});
viewFlipper.addView(itemView);
}
}
}
private void initData() {
titles = new ArrayList();
titles.add("你是最适合19.9元T恤的人!");
titles.add("《高能少年团加长版》一期上线!");
titles.add("古人是如何买年货的!");
titles.add("为何让手机24小时不离身!");
titles.add("我用了20年才看懂还珠格格");
titles.add("你的英伦腔是装的还是真的?");
titles.add("梁实秋:人没有不懒的");
}
}
可以看到我们把所有要加入到ViewFlipper中的数据通过initData()的方法进行初始化,把所有的数据都放入到一个集合里面,然后通过循环,把集合对应位置的数据逐个放入ViewFlipper中,这样就实现了和第一种方法中一样的效果,但是代码量大大缩减,减少了很多重复的XML布局代码,而且后期修改维护也十分的方便。
运行效果图如下:和第一种方法的效果类似,但是处理了奇数的item情况。