文档的说明
ViewAnimator that switches between two views, and has a factory from which these views are created.
You can either use the factory to create the views, or add them yourself.
A ViewSwitcher can only have two child views, of which only one is shown at a time.
如文档说明,ViewSwitcher提供了切换两个View的功能(默认有切换的动画),值得注意的是ViewSwitcher只有两个子View(如果添加第三个View会抛异常)
简单的使用
第一步:添加两个子View
// 有种方式添加两个子view
a. 调用两试addView方法,添加两个子view
b.【推荐】调用setFactory方法,传入的Factory实例是生成两个子viwe的抽象工厂,setFactory会调用抽象工厂的make方法生成两个子view。
相关的源代码码如下(ViewSwitcher的源码)
public void setFactory(ViewFactory factory) {
mFactory = factory;
obtainView();
obtainView();
}
private View obtainView() {
//使用工厂实例来生产子View
View child = mFactory.makeView();
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp == null) {
lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
addView(child, lp);
return child;
}
第二步:在合适的时机调用showNext()方法显示子View(注在UI线程调用)
第三步: 想要切换(显示)另一个子view,再调用showNext即可
* 可选:可以调用setInAnimation和setOutAnimation更改两个子View的出场与退场动画*
进阶1:扩展子类
参考ViewSwitcher的子类TextSwitcher和ImageSwitcher
关键是实现显示子View的方式,一般的步骤如下
1. 获取要显示的子Veiw
2. 更新子View的UI(需要适当的强转类型,或访问子类UI树的其它节点,并修改其UI)
3. 显示子View
示例代码如下:
// ImageSwitcher的setImageURI的方法
public void setImageURI(Uri uri) {
ImageView image = (ImageView)this.getNextView();
image.setImageURI(uri);
showNext();
}
// 参考如上代码,我们扩展的ViewSwitcher子类的更新View的示例如下
public void updateAndShowView(PojoXXX pojo) {
View rootView = this.getNextView();
// 子view的UI树决定于你调用 setFactory时传入的工厂实例
TextView childView = (TextView)rootView.findViewById(R.id.xxx);
childView.setText(pojo.getName);
.....
//其它UI更新,
.....
showNext()
....
//子view与数据源绑定的操作,用于点击事件处理时能找到绑定的数据对象
getCurrentView().setTag(pojo)
....
}
// 点击事件的处理,给ViewSwitcher子类自己来来处理
private void init() {
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Object adData = getCurrentView().getTag();
if (adDatainstanceof PojoXXX) {
//具体的业务代码处理
}
}
});
}
进阶2:定时轮播
* 一般实现广播轮播的需求场景*
在进阶1的基础(继承ViewSwitcher)上加上一个定时器的功能,用于轮播
//如下事例代码是使用Handler与Runnable配合来实现定时轮换的功能(mHandler与mSwitchRunnable是扩展ViewSwitcher类的成员)
private Handler mHandler = new Handler(Looper.getMainLooper());
private Runnable mSwitchRunnable = new Runnable() {
@Oerride
public void run() {
switchAdItem();
mHandler.postDelayed(this, 1000 * 3);
}
}
private void switchAdItem() {
//获取一下个显示的数据
PojoXXX pojo = getNextData();
updateAndShowView(pojo);
}
//当然还需要启动与暂停轮播的方法
public void startSwitchAd() {
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(mSwitchRunnable, SWITCH_DELAY);
}
public void stopSwitchAd() {
mHandler.removeCallbacksAndMessages(null);
}
注:使用Timer与TimerTask来实现轮播也是一种选择,但建议还是直接使用handler,原因是使用前者还是需要把更新View的动作抛到UI线程(也要借助handler)
new ViewFactory时的注意事项
* LayoutParams参数的设置 *
setFactory(new ViewFactory() {
@Override
public View makeView() {
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.CENTER_VERTICAL;
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout._ad_switch_item, null);
/** 这里需要返回的是新建的view,所以inflater的第三个参数不传(意味着布局文件中的根结点的LayoutParams会效了),故再赋值一个p
**/
viewGroup.setLayoutParams(lp);
return viewGroup;
}
});
}