本文共 3615 字,大约阅读时间需要 12 分钟。
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
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; }
* 可选:可以调用setInAnimation和setOutAnimation更改两个子View的出场与退场动画*
参考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) { //具体的业务代码处理 } } });}
* 一般实现广播轮播的需求场景*
在进阶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)
* 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; } }); }
转载地址:http://qtmbi.baihongyu.com/