专栏首页程序亦非猿Android Studio 4.0+ 中新的 UI 层次结构调试工具

Android Studio 4.0+ 中新的 UI 层次结构调试工具

调试 UI 的问题有时很棘手,Android Studio 4.0 内置了全新的布局检查器 (Layout Inspector),它的使用效果类似 Chrome 开发者工具,可以帮助开发者调试 Android 应用的 UI (用户界面)。布局检查器可用于设备和 Android 模拟器,它可以展示视图的层次结构。该工具有助于定位由根节点引起的问题。和上一个版本不同的是,新版本的布局检查器可以以三维的视角来展现视图层次结构,您可以直观地看到视图的布局方式。通过该工具您可以逐层来检查视图层次结构,同时它还会展示所有视图的属性,包括继承自视图父类的属性。

接下来我们一起了解一下最新版本的布局检查器是如何发挥作用的。首先点击窗口的 View 菜单,找到 Tool Window 子菜单,然后选择 Layout Inspector,这样就打开了布局检查器窗口。

布局检查器仅显示正在运行的进程的 UI 层次结构。也就是说您需要连接到设备或者模拟器上的一个正在运行的可调试应用,有两种方式可以满足该条件:

  • 如果您没有正在运行的进程,那么需要首先连接到一台设备或者启动一个 Android 模拟器实例,并且点击窗口的 Run 按钮来启动应用;
  • 如果您的应用进程已经运行,点击 select process,选择正在运行的设备,然后从设备右侧的列表来选择一个已运行的应用。
  • Android 模拟器实例 https://developer.android.google.cn/studio/run/emulator

选择所需的应用进程后,布局检查器会基于当前 UI 层次结构创建一个快照。如果您启用了 Live Updates 选项,那么当您在设备上操作界面时,快照会动态更新。

该版本的布局检查器延续了之前版本的功能并且更加多样化。首先,布局检查器可以用两种方式显示 UI 层次结构: 以二维的轮廓格式,或者以一种称为旋转模式 (rotation mode) 的三维视图形式。

点击 rotation 按钮会在二维和三维视图之间进行切换。当处于旋转模式时,您可以旋转 UI 层次结构。旋转操作可以帮助您更直观地了解视图的组织结构。请注意,旋转仅在 Android 10 或以上的设备上才可以使用。

您也可以选中一个视图,然后右键点击它后,窗口仅显示它的子视图。

同样,您可以仅显示一个所选视图的父视图。

右侧的窗格会显示所选视图的所有已声明的属性和继承的属性。您可以通过点击任何已声明的属性来打开布局相关的 xml 文件。和旋转特性一样,这个功能也仅适用于 Android 10 以上的设备。

通过布局检查器您还可以将新设计的界面和现有 UI 进行比较。要加载布局设计,点击 Load Overlay,然后选择一个布局设计。图片成功加载后,您可以改变它的半透明值 (alpha) 来比较现有布局与所选的设计布局之间的区别。

布局检查器示例

现在大家已经了解了布局检查器的使用方式。那么接下来我们通过实例来看一下如何使用它来解决应用的问题。这里我们有一个简单的示例应用,它包含一个 fragment,其中有一些静态文本和一个图片。如果您在阅读文章时想同步进行操作,可以先按照下面步骤操作创建工程。

  1. 打开 Android Studio 4.0,然后在 File 菜单里选择 New Project;
  2. 选择 Bottom Navigation Activity,点击 Next 然后点击 Finish;
  3. 替换 activity_main.xml 和 fragment_home.xml 的内容;
  4. 替换 HomeFragment.kt 的内容。
  • activity_main.xml https://gist.github.com/yenerm/9a07014e71a9a9df4c0c72bd615d0671
  • fragment_home.xml https://gist.github.com/yenerm/b0b84304fa57e8c9f99433eb489eba26
  • HomeFragment.kt https://gist.github.com/yenerm/7418d98137118d1e96f2e655346c54b4

当您运行应用的时候,您会看到一个可爱的 android,但是里面少了一些东西: 底部的导航标签。看一下布局文件,我们可以看到底部的导航视图是存在的,但是屏幕却没有显示它。

看来布局检查器大显身手的时候到了: 我们运行一下程序并检查一下这个问题,成功连接应用进程后,切换到旋转视图会看到应用的 UI 出现了问题。

首先我们可以看到 LinearLayout 里布局了一个工具栏 (toolbar),然后是 navigation host。在它下面,您可以看到导航栏位于最下方——看来底部的导航栏被挤出了屏幕。

有可能是 navigation host 的尺寸设置错了,我们尝试把它的高度设置为 'wrap_content':

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:defaultNavHost="true"
        android:layout_weight="9"
        app:navGraph="@navigation/mobile_navigation" />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav_menu" />
</LinearLayout>

回到布局检查器,您可以看到 LinearLayout 的尺寸正常了,但是底部的导航栏的位置不对:

有很多方法可以解决这个问题: 我们可以设置 navigation host 和底部导航栏的 layout_weight 参数,或者我们可以将 LinearLayout 换成 ConstraintLayout,但是切换布局不是本文的重点,所以我们设置一下 layout_weights 参数:

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:defaultNavHost="true"
        android:layout_weight="9"
        app:navGraph="@navigation/mobile_navigation" />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav_menu" />
</LinearLayout>

然后得到如下结果:

再运行应用的时候,布局就正常了。

快快尝试一下布局检查器的新特性,然后和我们分享您的使用体验吧。欢迎大家向我们反馈问题,或者告诉我们新的特性需求。

本文分享自微信公众号 - 程序亦非猿(chengxuyifeiyuan)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Flutter 应用性能优化最佳实践

    通常来说,Flutter 技术构建的应用程序在默认情况下都是高性能的。所以你只需要避开常见的陷阱,就可以获得优异的性能,而不需要使用复杂的分析工具对细节做优化。...

    程序亦非猿
  • 按下电源键后竟然发生了这一幕 —— Android 系统启动流程分析

    作为一名 Android 程序员,你有没有想过:那么复杂的 Android 系统,它是怎样运行起来的,我们的 App 又是怎样被 Android 系统加载后呈现...

    程序亦非猿
  • 接口幂等性这么重要,它是什么?怎么实现?

    如果我们系统中对接过支付宝充值功能的,我们需要给支付宝提供一个回调接口,支付宝回调信息中会携带(out_trade_no【商户订单号】,trade_no【支付宝...

    程序亦非猿
  • 第14章 使用Kotlin 进行 Android 开发(2)

    我们使用 fastjson 来解析这个数据。在 app 下面的 build.gradle中添加依赖

    一个会写诗的程序员
  • 笔记17 | 复习AlertDialog(对话框)示例

    项勇
  • Android项目实战(二十):浅谈ListView悬浮头部展现效果

    听着music睡
  • [android] 帧布局

    /*******************2016年5月3日 更新**************************************/

    陶士涵
  • Android开发之Loader与LoaderManager

    Loader是什么,有什么作用? 顾名思义就是加载器,简单来说,Loader做了2件事: (1)在单独的线程中读取数据,不会阻塞UI线程 (2)监视数据的更...

    YungFan
  • 利用 v7 Toolbar 自定义 Android ActionBar

    要使用 Toolbar,首先要在 layout 里面添加组件,例如在 activity_main.xml 里添加

    tonglei0429
  • Fragment栈回退和传参方式

    当你需要点击返回键是返回上一个Fragment而不是直接退出Activity时,需要把之前的fragment加入返回栈。

    提莫队长

扫码关注云+社区

领取腾讯云代金券