本文将带你了解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频道!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐