Android中经常要遍历一个容器中得所有view,并给这些view做一些业务,比如设置view的touch监听,再比如设置view不可点击等等。那么遍历view的方式中我们通常用到的是递归,但递归数据比较大时性能不是很好,接下来我将介绍递归和非递归的两种遍历方式.
#递归的方式遍历
首先介绍下递归的方式遍历容器中所有view并设置touch监听,直接上代码
/**
* 递归遍历
* 为指定View及其所有子View添加Touch监听.
* @param rootView
* @param l
*/
public static void recursionTravelView(View rootView, View.OnTouchListener l){
if (rootView.hasOnClickListeners()){
rootView.setOnTouchListener(l);
}
if (rootView instanceof ViewGroup){
ViewGroup viewGroup = (ViewGroup) rootView;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = viewGroup.getChildAt(i);
recursionTravelView(child, l);
}
}
}
#广度遍历
广度遍历的方式遍历容器中所有view并设置touch监听,直接上代码
/**
* 广度遍历
* 为指定View及其所有子View添加Touch监听.
* @param rootView
* @param l
*/
public static void depthTravelView(View rootView, View.OnTouchListener l){
ArrayDeque queue = new ArrayDeque<>();
queue.addLast(rootView);
while (!queue.isEmpty()) {
View temp = (View) queue.getLast();
//队尾出队
queue.pollLast();
if (temp instanceof ViewGroup) {
int childCount = ((ViewGroup) temp).getChildCount();
for (int i = childCount-1; i >= 0; i--) {
queue.addLast(((ViewGroup) temp).getChildAt(i));
}
}
//业务:如果view设置了listener那么就设置Touch监听
if (temp.hasOnClickListeners()) {
temp.setOnTouchListener(l);
}
}
}
#深度遍历
深度遍历的方式遍历容器中所有view并设置touch监听,直接上代码
/**
* 深度遍历
* 为指定View及其所有子View添加Touch监听.
* @param rootView
* @param l
*/
public static void breadthTravelView(View rootView, View.OnTouchListener l){
ArrayDeque queue = new ArrayDeque<>();
queue.addLast(rootView);
while (!queue.isEmpty()) {
View temp = (View) queue.getFirst();
if (temp instanceof ViewGroup) {
int childCount = ((ViewGroup) temp).getChildCount();
for (int i = 0; i < childCount; i++) {
queue.addLast(((ViewGroup) temp).getChildAt(i));
}
}
//业务:如果view设置了listener那么就设置Touch监听
if (temp.hasOnClickListeners()) {
temp.setOnTouchListener(l);
}
//队头出队
queue.pollFirst();
}
}