06.输入系统:第10课第16节_输入系统_补充知识_activity_window_decor_view关系_实验

在上一节从理论上讲解了activity,window,decor,view之间的关系,该小节我们编写源代码,去验证这些知识点。在原来的AS工程APP_0001_LEDDemp-V3上进行修改,先把APP_0001_LEDDemp-V3改成APP_0008_ViewHierarcky,然后打开该工程。

在原来的基础上修改layout下的content_main.xml文件,先修改一下button按钮的显示信息(修改为):

    <Button
        android:id="@+id/BUTTON"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
  -     android:text="ALL OFF"
  +     android:text="Print ViewHierarchy"/>

然后修改MainActivity.java文件,根据前面的学习,我们知道,在点击Botton时,会执行 class MyButtonListener implements View.OnClickListener 中的onClick(View view)方法。删除该方法下的所有内容,只调用函数printViewHierarchy:

    class MyButtonListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            View decorView = getWindow().getDecorView();
            printViewHierarchy(decorView,0,-1);
        }
    }

然后printViewHierarchy的实现如下:

/*传入三个参数,parent为遍历的对象,level为所处节点等级,如根节点为一个*,其孩子为两个*
childidx为孩子的序列号*/
public void printViewHierarchy(View parent, int level, int childidx){
        /*	 打印格式,
         *   * DecorView child -1 (x, y), (w, h)
         *   ** FrameLayout child 0 (x, y), (w, h)
         *   *** TextView  child 0  (x, y), (w, h)
         *   ** FrameLayout child 1 (x, y), (w, h)
         *   *** Button   child 0   (x, y), (w, h)
         *   *** TextView  child 1  (x, y), (w, h)
         *   *** FrameLayout  child 2 (x, y), (w, h)
         */
        int i;
        String levelStr = "*";
        for (i = 0; i < level; i++) //根据传入的level,进而确定打印几个*
            levelStr += "*";

        int[] positons = new int[2]; //View保存坐标
        parent.getLocationOnScreen(positons);
		/*信息打印:包括位置,宽度。高度,*等级,以及是第几个孩子*/
        Log.d(TAG, levelStr + " " + parent.getClass().getName() + " child " + childidx + " (" + positons[0] + ", " + positons[1] + "), ("+parent.getWidth()+", "+parent.getHeight()+")");
		/*如果parent是一个ViewGroup实例(也就是说明其还有孩子)*/
        if (parent instanceof ViewGroup){
            View child;//定义一个View child
            ViewGroup root = (ViewGroup)parent; //从parent获得这个孩子
            i = 0;
            /*直到root=null,即没有孩子了跳出循坏*/
            while ((child = root.getChildAt(i)) != null){
            	/*把孩子当做View parent传入,进行遍历,每递归一次*增加一个,但是i从零开始,
            	在一次递归中,i随着遍历的孩子个数的增加而增加(同级孩子)*/
                printViewHierarchy(child, level+1, i);
                i++;
            }
        }
    }

该函数为一个递归函数,我们让其打印出树状结构,其中的代表根节点,代表上一个的孩子,那么*就是上一个**的孩子,并且打印其所在xy的位置,下面我们来分析一下这个递归函数的实现过程。 为了方便分析,做了以下修改:

-	public class MainActivity extends AppCompatActivity {
+	public class MainActivity extends Activity {

让MainActivity集成于Activity,然后我们运行程序,点击Botton按钮,可以看到如下打印信息:

* com.android.internal.policy.DecorView child -1 (0, 0), (1024, 600)
	** android.widget.LinearLayout child 0 (0, 0), (940, 600)
		*** android.view.ViewStub child 0 (0, 0), (0, 0)
		*** android.widget.FrameLayout child 1 (0, 42), (940, 558)
			**** android.support.design.widget.CoordinatorLayout child 0 (0, 42), (940, 558)
				***** android.support.design.widget.AppBarLayout child 0 (0, 42), (940, 84)
					****** android.support.v7.widget.Toolbar child 0 (0, 42), (940, 84)
				***** android.widget.LinearLayout child 1 (0, 126), (940, 474)
					****** android.widget.TextView child 0 (0, 126), (940, 34)
					****** android.widget.Button child 1 (0, 160), (940, 84)
					****** android.widget.CheckBox child 2 (0, 244), (940, 56)
					****** android.widget.CheckBox child 3 (0, 300), (940, 56)
					****** android.widget.CheckBox child 4 (0, 356), (940, 56)
					****** android.widget.CheckBox child 5 (0, 412), (940, 56)
				***** android.support.design.widget.FloatingActionButton child 2 (814, 474), (98, 98)
	** android.view.View child 1 (940, 0), (84, 600)
	** android.view.View child 2 (0, 0), (940, 42)

根据上述的分支结构,我们可以知道根节点* com.android.internal.policy.DecorView child -1 (0, 0), (1024, 600)为整个屏幕,他有3个孩子,分别为** android.widget.LinearLayout child 0 (0, 0), (940, 600),** android.view.View child 1 (940, 0), (84, 600),** android.view.View child 2 (0, 0), (940, 42)。并且其 ** android.widget.LinearLayout child 0 (0, 0), (940, 600)又存在两个孩子*** android.view.ViewStub child 0 (0, 0), (0, 0)与 *** android.widget.FrameLayout child 1 (0, 42), (940, 558),依次类推,根据其坐标以及width与height可以画春如下框图:
在这里插入图片描述
这样就把我们的APP复原了。

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/88552086
今日推荐