ViewSwitcher的使用

文档的说明

ViewSwitcher的api文档 >>

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;
            }
        });
    }

猜你喜欢

转载自blog.csdn.net/scholar_ii/article/details/80629340