Android应用开发之遍历所有控件的递归和非递归实现
白羽 2018-08-10 来源 :网络 阅读 1324 评论 0

摘要:本文将带你了解Android应用开发之遍历所有控件的递归和非递归实现,希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之遍历所有控件的递归和非递归实现,希望本文对大家学Android有所帮助


题目描述
给出布局的根节点,要求不使用递归的方式将所有类型为Button的控件背景设置为红色。
分析
对于Android中的布局来说,有两种类型的节点,一种是ViewGroup布局,另外一种是View控件,按照类似树形结构来组织(注意,不是二叉树)。 对于控件的遍历,可以转化为对树的遍历。对树的遍历有递归方式和非递归的方式,非递归方式又可以分为深度优先遍历和广度优先遍历。
实现
Java代码  <?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="//schemas.android.com/apk/res/android"      android:id="@+id/rootView"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:layout_margin="10dp"      android:background="#abcdef"      android:orientation="vertical">        <LinearLayout          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:background="#156ec7"          android:orientation="horizontal"          android:padding="10dp">            <TextView              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:padding="5dp"              android:text="文本1"              android:textColor="#ffffff" />            <TextView              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:padding="5dp"              android:text="文本2"              android:textColor="#ffffff" />          </LinearLayout>          <Button          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="按钮1" />        <RelativeLayout          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:background="#5d9726"          android:padding="10dp">            <Button              android:id="@+id/btn"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="按钮2" />            <TextView              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"                />            <TextView              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" />        </RelativeLayout>    </LinearLayout>  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="//schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:background="#abcdef"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#156ec7"
        android:orientation="horizontal"
        android:padding="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="文本1"
            android:textColor="#ffffff" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="文本2"
            android:textColor="#ffffff" />


    </LinearLayout>


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#5d9726"
        android:padding="10dp">

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按钮2" />

        <TextView
            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"

            />

        <TextView
            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" />

    </RelativeLayout>

</LinearLayout>
 
界面效果和对应的树结构如下:其中有颜色的节点类型为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 < childCount; 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 < childCount; 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());            }      }      }  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 < childCount; 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 < childCount; 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 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程