针对任何操作系统的操作,其实都是通过事件驱动来完成的,例如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控件多了这也能节省不少时间
网友评论