Android UI篇——自动设置所有View的事件【以Click事件为例】

释放双眼,带上耳机,听听看~!

针对任何操作系统的操作,其实都是通过事件驱动来完成的,例如Windows的鼠标驱动、Android的触摸驱动,针对开发者来说每一种驱动都对应一种事件,例如Android开发中的Touch事件、Click事件等,其中最常用的就是Click事件了,那么日常开发中怎样设置View的事件呢?以下是目前两种最常见的方式:

第一种:直接设置

protected void setListener() {//MainAcitivity实现了OnClickListener
       mTvActMainOpearte1.setOnClickListener(this);
       mTvActMainOpearte2.setOnClickListener(this);
       mTvActMainOpearte3.setOnClickListener(this);
}

第二种:使用ButterKnife

@OnClick(R.id.tv_act_ar_scan_prompt)
@Override
 public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_act_ar_scan_prompt:
                //TODO 
                break;
        }
}

两者都有一个共同的缺点,就是每一个需要的View都得一一设置事件,典型的没有技术含量的重复性劳动,那么有什么简单易行的办法可以替代呢?还真有,因为Android的View体系就是一个ViewTree,可以遍历RootView的每一个子View然后设置相应的事件如Click事件,这样就省去了不少开发工作量,下面是我的实现实现方式:

/**
  * 递归遍历所有控件并设置监听
  */
public static void setAutoAllViewClickListener(@NonNull View rootView, @NonNull View.OnClickListener onClickListener) {
        if (rootView instanceof ViewGroup) {
            ViewGroup rootViewGroup = (ViewGroup) rootView;
            int childCount = rootViewGroup.getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = rootViewGroup.getChildAt(i);
                if (child instanceof ViewGroup) {
                    setAutoAllViewClickListener(child, onClickListener);
                } else {
                    //除了可设置Click事件还可以设置其他事件,例如Touch事件等
                    child.setOnClickListener(onClickListener);
                }
            }
        } else {
            rootView.setOnClickListener(onClickListener);
        }
 }
/**
  *获取到RootView
  */
protected final View getRootView() {
        return ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
 }

使用此方法需要注意的是一般来说不设置ViewGroup,因为这会破坏相应的事件传递逻辑,造成ViewGroup拦截消费了事件,子View无法接受到事件,所以这里可灵活设置,特此说明下一下,所以在我的代码中就只设置了View的Click事件,有的时候不需要自动设置事件,可以设置一个方法避免setAutoAllViewClickListener被调用,下面是我的使用方法:

/**
  * 比较懒,就直接遍历所有View监听了
  */
 @CallSuper
  protected void setListener() {
        if (isAutoSetOnClickListener()) {
            ViewUtil.setAllViewClickListener(getRootView(), this);
        }
  }

/**
  * 是否自动设置所有View的Click事件
  * @return
  */
 protected boolean isAutoSetOnClickListener() {
        return true;
 }

在BaseActivity中统一设置Click事件,若子类不想设置直接覆写isAutoSetOnClickListener() return false即可

综上,在日常开发中就可省去不少开发工作量了,读者有不同观点可分享出来大家共同讨论!

补充一点,以上只是省去了对每一个View设置监听,具体监听还得自己实现即省去了类似于view.setClickListener(new OnClickListener())这样的代码,若View控件多了这也能节省不少时间

人已赞赏
Android文章

Android全埋点-页面浏览事件

2019-10-21 13:52:02

Android文章

RecyclerView + DataBinding实现的下拉刷新与加载更多

2019-10-21 18:53:43

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索