android 递归添加控件,Android应用开发之遍历所有控件的递归和非递归实现
本文将带你了解Android应用开发之遍历所有控件的递归和非递归实现,希望本文对大家学Android有所帮助题目描述给出布局的根节点,要求不使用递归的方式将所有类型为Button的控件背景设置为红色。分析对于Android中的布局来说,有两种类型的节点,一种是ViewGroup布局,另外一种是View控件,按照类似树形结构来组织(注意,不是二叉树)。对于控件的遍历,可以转化为对树的遍历。对树的遍.
本文将带你了解Android应用开发之遍历所有控件的递归和非递归实现,希望本文对大家学Android有所帮助
题目描述
给出布局的根节点,要求不使用递归的方式将所有类型为Button的控件背景设置为红色。
分析
对于Android中的布局来说,有两种类型的节点,一种是ViewGroup布局,另外一种是View控件,按照类似树形结构来组织(注意,不是二叉树)。 对于控件的遍历,可以转化为对树的遍历。对树的遍历有递归方式和非递归的方式,非递归方式又可以分为深度优先遍历和广度优先遍历。
实现
Java代码 <?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#abcdef"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#156ec7"
android:orientation="horizontal"
android:padding="10dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="文本1"
android:textColor="#ffffff" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="文本2"
android:textColor="#ffffff" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#5d9726"
android:padding="10dp">
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2" />
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn"
android:padding="5dp"
android:text="文本3"
android:textColor="#ffffff"
/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn"
android:layout_toRightOf="@id/tv"
android:padding="5dp"
android:text="文本4"
android:textColor="#ffffff" />
界面效果和对应的树结构如下:其中有颜色的节点类型为viewGroup
布局
抽象树结构
具体算法实现
以下方式实现了三种方式的遍历结果,读者可以参考。
Java代码 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewGroup root = (ViewGroup) findViewById(R.id.rootView); travelTree3(root); } //递归遍历树 private void travelTree1(View root) { if (root instanceof ViewGroup) { int childCount = ((ViewGroup) root).getChildCount(); for (int i = 0; i = 0; i--) { stack.addLast(((ViewGroup) top).getChildAt(i)); } } //如果栈顶为View类型,输出 else if (top instanceof View) Log.i("visitView", top.toString()); } } } public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup root = (ViewGroup) findViewById(R.id.rootView);
travelTree3(root);
}
//递归遍历树
private void travelTree1(View root) {
if (root instanceof ViewGroup) {
int childCount = ((ViewGroup) root).getChildCount();
for (int i = 0; i
travelTree1(((ViewGroup) root).getChildAt(i));
}
} else if (root instanceof View) {
Log.i("visitView", root.toString());
if (root instanceof Button)
root.setBackgroundColor(Color.parseColor("#ff0000"));
}
}
//非递归广度遍历,利用队列数据结构
private void travelTree2(View root) {
ArrayDeque queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
//取得队头
View front = (View) queue.getFirst();
//如果为viewGroup则使子节点入队列
if (front instanceof ViewGroup) {
int childCount = ((ViewGroup) front).getChildCount();
for (int i = 0; i
queue.addLast(((ViewGroup) front).getChildAt(i));
}
}
//如果队头为View类型,输出
else if (front instanceof View)
Log.i("visitView", front.toString());
//队头出队
queue.pollFirst();
}
}
//非递归深度遍历,利用栈数据结构
private void travelTree3(View root) {
ArrayDeque stack = new ArrayDeque();
stack.addLast(root);
while (!stack.isEmpty()) {
//取得栈顶
View top = (View) stack.getLast();
//出栈
stack.pollLast();
//如果为viewGroup则使子节点入栈
if (top instanceof ViewGroup) {
int childCount = ((ViewGroup) top).getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
stack.addLast(((ViewGroup) top).getChildAt(i));
}
}
//如果栈顶为View类型,输出
else if (top instanceof View)
Log.i("visitView", top.toString());
}
}
}
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!
更多推荐
所有评论(0)