第 2 章 布 局 布 局 是 所 有 带 界 面 的 Android 程 序 的 开 端 布 局 应 用 得 好 坏 直 接 决 定 了 程 序 的 用 户 体 验 虽 然 布 局 看 似 没 有 组 件 复 杂, 但 也 涉 及 到 了 很 多 技 巧 在 各 大 公 司 的 面 试 题 中 也 会 经 常 遇 到 关 于 布 局 的 一 些 问 题 通 过 这 些 问 题 可 以 考 查 应 聘 者 对 界 面 设 计 的 整 体 把 握 本 章 并 不 会 对 布 局 的 基 础 知 识 进 行 回 顾 和 总 结, 而 是 以 面 试 题 的 形 式 给 出 应 付 这 类 问 题 的 一 些 方 法 和 技 巧 2.1 Android 中 的 布 局 大 多 数 关 于 布 局 的 面 试 题 都 会 问 到 一 个 熟 得 不 能 再 熟 的 问 题 : 介 绍 一 下 Android 中 的 布 局, 或 Android 中 的 布 局 有 哪 些, 请 介 绍 一 下 它 们 关 于 这 类 问 题 并 不 需 要 对 每 一 种 布 局 详 细 阐 述, 而 只 需 要 介 绍 一 下 它 们 的 基 本 用 法 即 可 面 试 例 题 1: 请 说 出 Android 中 的 五 种 布 局, 并 简 单 介 绍 它 们 的 作 用 [ 国 内 某 著 名 软 件 公 司 2010 年 面 试 题 ] 答 案 : 五 种 布 局 是 FrameLayout( 堆 栈 布 局 ) LinearLayout( 线 性 布 局 ) RelativeLayout( 相 对 布 局 ) TableLayout( 表 格 布 局 ) 和 AbsoluteLayout( 绝 对 布 局 ) FrameLayout 在 布 局 文 件 中 使 用 <FrameLayout> 标 签 表 示 FrameLayout 布 局 中 的 View 都 会 以 层 叠 方 式 显 示, 类 似 于 Photoshop 的 图 层 放 在 最 后 的 View 会 显 示 在 最 上 层 因 此, 可 将 FrameLayout 称 为 堆 栈 布 局 LinearLayout 可 以 将 多 个 View 水 平 或 垂 直 排 列 如 果 android:orientation 属 性 的 值 为 horizontal, View 会 水 平 排 列 属 性 值 为 vertical,view 会 垂 直 排 列 horizontal 是 android:orientation 属 性 的 默 认 值 RelativeLayout 可 以 通 过 确 定 两 个 或 多 个 组 件 的 相 对 位 置 来 摆 放 组 件 与 组 件 相 对 位 置 相 关 的 属 性 包 括 android:layout_toleftof ( 将 当 前 组 件 置 于 该 属 性 指 定 组 件 的 左 侧 ) android:layout_torightof( 将 当 前 组 件 置 于 该 属 性 指 定 组 件 的 右 侧 ) android:layout_below( 将 当 前 组 件 置 于 该 属 性 指 定 组 件 的 下 方 ) 和 android:layout_above( 将 当 前 组 件 置 于 该 属 性 指 定 组 件 的 上 方 ) 这 4 个 属 性 值 必 须 指 定 已 经 存 在 的 ID TableLayout 布 局 可 以 将 View 按 表 格 形 式 排 列 AbsoluteLayout 可 以 设 置 View 的 绝 对 坐 标, 但 并 不 建 议 使 用 AbsoluteLayout 设 计 界 面, 因 为 这 样 无 法 适 应 屏 幕 分 辨 率 的 变 化
第 2 章 布 局 面 试 例 题 2:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android: orientation="vertical" > 中 的 xmlns:android 是 什 么 意 思?xmlns:android 的 值 可 以 任 意 设 置 吗? 请 说 明 原 因 [ 美 国 某 著 名 社 交 网 站 2011 年 面 试 题 ] 解 析 : 这 道 题 表 面 上 考 查 XML 命 名 空 间 与 布 局 文 件 的 关 系, 但 实 际 上 这 个 问 题 可 以 进 一 步 引 申 例 如, 布 局 文 件 的 命 名 空 间 与 自 定 义 组 件 的 关 系 紧 密 可 以 考 查 应 聘 者 如 何 预 定 义 自 定 义 组 件 的 属 性 在 自 定 义 组 件 时, 需 要 使 用 <declare-styleable> 标 签 定 义 属 性 名, 然 后 需 要 在 布 局 文 件 的 最 顶 层 标 签 中 指 定 R.java 文 件 的 位 置 下 面 举 一 个 例 子 假 设 有 一 个 Android 程 序 的 package 是 mobile.android.yd.interview 现 在 编 写 一 个 自 定 义 的 组 件 (EditText 组 件 的 扩 展, 类 名 为 EditTextExt) 首 先 在 res\values 目 录 中 建 立 一 个 attrs.xml 文 件, 并 输 入 如 下 内 容 : <resources> <declare-styleable name = " EditTextExt"> <attr name = "attr1" format = "reference"/> </declare-styleable> </rexources> 上 面 的 代 码 在 R.attr 类 中 会 生 成 一 个 attr1 变 量 如 果 在 布 局 文 件 中 使 用 EditTextExt 的 attr1 属 性, 就 需 要 指 定 命 名 空 间, 代 码 如 下 : <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ext = "http://schemas.android.com/apk/res/mobile.android.yd.interview" android:orientation="vertical" > <mobile.android.yd.interview.edittextext ext:attr1 = /> </LinearLayout> 通 过 xmlns:ext 指 定 了 预 定 义 属 性 的 R.java 文 件 的 位 置 后, 在 使 用 EditTextExt 组 件 时, 如 果 属 性 前 加 ext 命 名 空 间, 就 必 须 指 定 正 确 的 属 性 例 如, 本 例 中 只 定 义 了 一 个 attr1 属 性, 如 果 要 写 成 ext:attr2,adt 在 处 理 布 局 文 件 时 会 抛 出 异 常 答 案 :xmlns:android 是 XML 中 的 命 名 空 间, 为 了 防 止 属 性 冲 突 类 似 于 Java 中 的 package xmlns:android 的 值 不 允 许 任 意 设 置 xmlns:android 的 值 必 须 以 http://schemas.android.com/apk/res 开 头, 后 面 的 部 分 表 示 定 义 属 性 的 R.java 文 件 所 在 的 包 名 在 R.java 文 件 中 包 含 了 属 性 名 的 定 义 例 如, 如 果 使 用 系 统 属 性, 需 要 指 定 系 统 R.java 文 件 的 位 置 该 文 件 位 于 res\android 目 录 中, 因 此, xmlns:android 值 的 最 后 是 android 2.2 布 局 使 用 技 巧 关 于 布 局 的 面 试 题 最 多 的 是 如 何 使 用 布 局 最 常 用 的 布 局 是 FrameLayout LinearLayout 和 RelativeLayout 这 3 个 布 局 常 被 用 来 设 计 复 杂 的 界 面 因 此, 熟 练 掌 握 这 3 个 布 局 的 基 本 技 巧 更 有 利 于 解 答 这 类 面 试 题 11
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 2.2.1 FrameLayout 布 局 面 试 例 题 1:FrameLayout 的 主 要 用 途 解 析 : 这 道 题 主 要 考 查 应 聘 者 对 FrameLayout 的 理 解 程 度 FrameLayout 布 局 中 的 所 有 View 都 会 以 叠 加 的 方 式 摆 放, 最 后 一 个 View 会 在 最 上 层 显 示 如 果 这 些 View 在 位 置 和 尺 寸 上 有 交 集, 就 会 形 成 类 似 Photoshop 的 叠 加 效 果 图 2.1 是 用 Photoshop 做 的 效 果, 包 含 了 3 个 图 层 图 2.1 用 Photoshop 做 的 图 层 效 果 如 果 使 用 FrameLayout, 也 同 样 可 以 做 出 类 似 的 效 果 只 需 要 将 这 3 个 图 层 的 图 像 分 别 保 存 成 3 个 图 像 文 件, 并 显 示 在 ImageView 组 件 中 将 背 景 图 作 为 FrameLayout 的 第 1 个 View, 其 他 两 个 ImageView 的 顺 序 可 以 任 意 排 列 形 成 的 效 果 如 图 2.2 所 示 图 2.2 用 FrameLayout 做 的 图 层 效 果 12
第 2 章 布 局 答 案 :FrameLayout 主 要 用 于 进 行 层 次 结 构 的 布 局 例 如, 想 把 两 个 图 像 叠 加 到 一 起 形 成 一 张 图 像 的 效 果 就 可 以 用 FrameLayout 这 种 叠 加 的 方 式 很 像 Photoshop 的 图 层 面 试 例 题 2: 现 在 有 3 个 按 钮, 如 何 让 这 3 个 按 钮 以 水 平 方 向 分 别 左 对 齐 居 中 对 齐 和 右 对 齐 [ 美 国 某 著 名 通 信 技 术 公 司 2009 年 面 试 题 ] 解 析 :View 的 上 下 左 右 居 中 对 齐 是 界 面 中 经 常 接 触 到 的 布 局 效 果 单 独 某 种 对 齐 方 式 有 很 多 种 方 法 但 同 一 个 方 向 的 各 种 对 齐 布 局,FrameLayout 是 最 容 易 实 现 的 每 个 View 对 应 的 XML 标 签 都 有 一 个 android:layout_gravity 属 性, 通 过 设 置 该 属 性, 可 以 在 FrameLayout 中 实 现 任 何 方 向 的 对 齐 布 局 由 于 FrameLayout 中 的 View 是 层 叠 显 示 的, 因 此, 可 以 单 独 对 待 FrameLayout 中 的 每 一 个 View 这 一 点 与 LinearLayout 差 异 很 大 在 LinearLayout 中 的 View 并 不 是 对 每 一 个 android:layout_gravity 属 性 的 值 都 起 作 用 如 android:orientation 属 性 的 值 为 horizontal,linearlayout 中 的 View 都 会 水 平 排 列, 但 View 的 android:layout_gravity 属 性 只 有 在 垂 直 ( 如 bottom center_vertical 等 ) 方 向 的 值 才 起 作 用 答 案 : 使 用 FrameLayout 和 android:layout_gravity 属 性 可 以 很 容 易 实 现 这 个 布 局, 代 码 如 下 : <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <!-- 左 对 齐 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 按 钮 1" android:layout_gravity="left" /> <!-- 中 对 齐 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 按 钮 2" android:layout_gravity="center_horizontal" /> <!-- 右 对 齐 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 按 钮 3" android:layout_gravity="right" /> </FrameLayout> 面 试 例 题 3:FrameLayout 中 的 View 都 是 层 叠 摆 放 的, 后 一 个 View 会 覆 盖 前 一 个 View, 这 种 说 法 对 吗? 并 说 明 原 因 [ 国 内 某 著 名 电 信 运 行 商 2010 年 面 试 题 ] 答 案 : 不 正 确 FrameLayout 中 的 View 只 有 在 所 有 的 View 同 样 大 小, 并 且 在 同 一 个 位 置 时 才 会 被 覆 盖 否 则,View 是 以 层 叠 方 式 显 示 的, 类 似 Photoshop 中 的 图 层, 未 被 上 一 层 View 覆 盖 的 部 分 会 显 示 出 来 2.2.2 LinearLayout 布 局 面 试 例 题 1: 如 何 获 得 LinearLayout 的 宽 度 和 高 度?[ 国 内 某 金 融 企 业 2011 年 面 试 题 ] 解 析 : 这 个 问 题 从 表 面 看 是 关 于 LinearLayout 的, 实 际 上 也 可 以 扩 展 到 其 他 继 承 于 View 的 组 件 中 很 多 初 学 者 在 回 答 如 何 获 得 组 件 的 宽 度 和 高 度 时 经 常 容 易 犯 错 误 可 能 使 用 过 其 他 编 程 语 言 的 应 聘 者 很 自 然 会 直 接 使 用 View.getWidth 或 View.getHeight 方 法 获 得 宽 度 和 高 度 不 过 很 遗 憾, 13
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 在 Android 程 序 中 这 两 个 方 法 返 回 的 都 是 0 由 于 Android 程 序 的 运 行 机 制 决 定 了 无 法 在 组 件 类 外 部 使 用 getwidth 和 getheight 方 法 获 得 高 度 和 宽 度 ( 在 自 定 义 组 件 类 的 内 容 可 以 通 过 这 两 个 方 法 获 取 当 前 组 件 的 宽 度 和 高 度, 如 在 onsizechanged 方 法 中 可 以 使 用 这 两 个 方 法 获 得 宽 度 和 高 度 ), 必 须 使 用 View.getMeasuredWidth 和 View.getMeasuredHeight 方 法 获 取 当 前 组 件 的 宽 度 和 高 度 在 调 用 这 两 个 方 法 之 前, 必 须 调 用 View.measure 方 法 先 测 量 组 件 的 宽 度 和 高 度 如 果 想 直 接 获 取 在 布 局 文 件 中 定 义 的 组 件 的 宽 度 和 高 度, 可 以 直 接 使 用 View.getLayoutParams(). width 和 View.getLayoutParams().height 当 宽 度 和 高 度 被 设 为 fill_parent match_parent 或 wrap_ content 时, 这 两 个 变 量 会 返 回 MATCH_PARENT FILL_PARENT 和 WRAP_CONTENT 常 量 的 值 答 案 : 由 于 LinearLayout 是 View 的 子 类, 因 此, 可 以 使 用 View.getMeasuredWidth 和 View.get MeasuredHeight 方 法 获 取 组 件 的 宽 度 和 高 度, 代 码 如 下 : View view = getlayoutinflater().inflate(r.layout.main, null); LinearLayout linearlayout = (LinearLayout)view. findviewbyid(r.id.linearlayout); // measure 方 法 的 参 数 值 都 设 为 0 即 可 linearlayout.measure(0, 0); // 获 取 组 件 的 宽 度 int width = linearlayout. getmeasuredwidth(); // 获 取 组 件 的 高 度 int height = linearlayout.getmeasuredheight(); 注 意 如 果 组 件 的 宽 度 或 高 度 设 为 fill_parent 或 match_parent 使 用 getmeasuredwidth 或 getmeasuredheight 方 法 获 取 组 件 宽 度 或 高 度 时, 当 组 件 中 包 含 其 他 子 组 件 时, 所 获 得 的 实 际 值 是 这 些 组 件 所 占 的 最 小 宽 度 和 最 小 高 度 题 ] 面 试 例 题 2: 如 何 在 多 个 LinearLayout 中 添 加 分 隔 线?[ 中 国 台 湾 某 著 名 软 件 公 司 2011 年 面 试 答 案 : 如 果 要 适 合 于 所 有 的 Android 版 本, 可 以 在 多 个 LinearLayout 放 置 用 于 显 示 分 隔 线 的 View, 例 如, 放 一 个 ImageView 组 件, 然 后 将 其 背 景 设 为 分 隔 线 的 颜 色 或 图 形, 分 隔 线 View 的 定 义 代 码 如 下 : <ImageView android:layout_width="fill_parent" android:layout_height="2dp" android:background="#f00" /> 在 Android 3.0 及 以 上 版 本,LinearLayout 支 持 直 接 显 示 分 隔 线 设 置 <LinearLayout> 标 签 的 android:showdividers 属 性 可 以 在 LinearLayout 的 相 应 位 置 显 示 分 隔 线 如 果 有 多 个 LinearLayout, 显 示 效 果 就 和 在 LinearLayout 之 间 加 分 隔 线 是 一 样 的 android:showdividers 属 性 可 以 设 置 如 下 4 个 值 none: 不 显 示 分 隔 线 beginning: 在 LinearLayout 的 开 始 处 ( 顶 边 ) 显 示 分 隔 线 end: 在 LinearLayout 的 结 尾 处 ( 底 边 ) 显 示 分 隔 线 middle: 在 LinearLayout 中 的 每 两 个 组 件 间 显 示 分 隔 线 除 了 需 要 设 置 android:showdeviders 属 性 外, 还 要 设 置 android:divider 属 性, 该 属 性 表 示 分 隔 14
第 2 章 布 局 线 的 图 像, 需 要 一 个 Drawable ID 在 Java 代 码 中 可 以 使 用 下 面 两 个 方 法 设 置 android:showdividers 和 android:divider linearlayout.setshowdividers: 设 置 android:showdividers 属 性 linearlayout.setdividerdrawable: 设 置 android:divider 属 性 面 试 例 题 3: 现 在 有 3 个 按 钮, 如 何 让 这 3 个 按 钮 以 水 平 方 向 分 别 左 对 齐 居 中 对 齐 和 右 对 齐? [ 美 国 某 著 名 通 信 技 术 公 司 2009 年 面 试 题 ] 解 析 : 在 2.2.1 节 的 面 试 例 题 2 中 曾 问 过 这 个 问 题 使 用 FrameLayout 可 以 很 容 易 解 决 这 个 问 题 当 然, 除 了 用 FrameLayout 外, 还 有 其 他 的 解 决 方 案 例 如, 用 嵌 套 的 LinearLayout 由 于 水 平 对 齐 必 须 将 <LinearLayout> 标 签 的 android:orientation 属 性 值 设 为 vertical 因 此, 可 以 在 一 个 水 平 线 性 布 局 中 放 置 三 个 垂 直 线 性 布 局 的 LinearLayout, 并 将 android:layout_weight 属 性 ( 该 属 性 将 在 2.3.1 节 介 绍 ) 值 设 为 1, 最 后 将 android:layout_width 属 性 值 设 为 fill_parent 这 样 3 个 垂 直 线 性 布 局 的 LinearLayout 就 会 水 平 三 等 分 进 行 排 列 然 后 分 别 在 这 3 个 LinearLayout 中 各 放 置 一 个 按 钮, 分 别 左 对 齐 居 中 对 齐 和 右 对 齐 即 可 我 们 可 以 将 这 3 个 LinearLayout 设 置 成 不 同 的 背 景 色, 看 一 下 布 局 后 的 效 果, 如 图 2.3 所 示 一 般 这 类 问 题 应 聘 者 只 需 给 出 一 种 答 案 即 可 当 然, 如 果 时 间 允 许 的 话, 也 可 以 给 出 多 种 答 案, 这 样 应 聘 者 有 可 能 得 到 更 多 的 加 分 图 2.3 使 用 嵌 套 线 性 布 局 的 效 果 答 案 : 可 以 使 用 嵌 套 线 性 布 局 来 解 决 这 个 问 题, 布 局 代 码 如 下 : <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="800dp" android:orientation="horizontal" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_weight="1" android:background="#f00"> <!-- 左 对 齐 的 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 我 的 按 钮 1" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_weight="1" android:background="#0f0"> <!-- 中 心 对 齐 的 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 按 钮 2" android:layout_gravity="center" /> </LinearLayout> 15
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_weight="1" android:background="#00f"> <!-- 右 对 齐 的 按 钮 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 按 钮 3" android:layout_gravity="right" /> </LinearLayout> </LinearLayout> 2.2.3 RelativeLayout 布 局 面 试 例 题 1: 如 图 2.4 所 示 的 布 局 如 何 实 现 (5 个 按 钮 成 梅 花 状 排 列, 并 整 体 水 平 居 中 )?[ 国 内 某 移 动 领 域 创 业 公 司 2010 年 面 试 题 ] 图 2.4 梅 花 布 局 解 析 : 本 题 考 查 对 布 局 的 实 际 应 用, 需 要 写 出 真 实 的 布 局 代 码 一 般 强 调 相 对 位 置 的 布 局 大 多 可 以 使 用 RelativeLayout 布 局 解 决 问 题, 当 然, 很 多 时 候 也 需 要 与 其 他 布 局 配 合 使 用 例 如, 本 题 可 以 先 用 RelativeLayout 布 局 安 排 这 5 个 按 钮 的 位 置, 然 后 将 RelativeLayout 放 到 FrameLayout 或 LinearLayout 中 居 中 显 示 答 案 : 布 局 代 码 如 下 : <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"> <!-- 左 上 角 的 按 钮 --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textsize="20dp" android:text=" 按 钮 1" /> <!-- 中 心 的 按 钮 --> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textsize="20dp" android:text=" 按 钮 2" android:layout_torightof="@id/button1" android:layout_below="@id/button1" /> <!-- 左 下 角 的 按 钮 --> <Button android:id="@+id/button3" android:layout_width="wrap_content" 16
第 2 章 布 局 android:layout_height="wrap_content" android:textsize="20dp" android:text=" 按 钮 3" android:layout_toleftof="@id/button2" android:layout_below="@id/button2" /> <!-- 右 上 角 的 按 钮 --> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textsize="20dp" android:text=" 按 钮 4" android:layout_torightof="@id/button2" android:layout_above="@id/button2" /> <!-- 右 下 角 的 按 钮 --> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textsize="20dp" android:text=" 按 钮 5" android:layout_torightof="@id/button2" android:layout_below="@id/button2" /> </RelativeLayout> </FrameLayout> 面 试 例 题 2: 在 RelativeLayout 中 有 一 个 Button(id 为 button1) 按 钮, 请 确 定 该 按 钮 相 对 于 手 机 屏 幕 的 位 置 坐 标 [ 国 内 某 移 动 领 域 创 业 公 司 2010 年 面 试 题 ] 答 案 : 使 用 View. getlocationonscreen 方 法 可 以 获 取 当 前 View 相 对 于 屏 幕 的 坐 标, 代 码 如 下 : View view = findviewbyid(r.id.button1); // 数 组 长 度 必 须 为 2 int[] locations = new int[2]; view.getlocationonscreen(locations); int x = locations[0]; // 获 取 组 件 当 前 位 置 的 横 坐 标 int y = locations[1]; // 获 取 组 件 当 前 位 置 的 纵 坐 标 面 试 例 题 3: 在 RelativeLayout 布 局 中 可 以 设 置 标 签 的 android:layout_toleftof android:layout_ torightof 等 属 性 确 定 组 件 的 相 对 位 置, 那 么 如 何 用 Java 代 码 来 完 成 这 些 工 作 呢?[ 德 国 某 著 名 软 件 公 司 2011 年 面 试 题 ] 解 析 : 自 从 Android 问 世 以 来, 一 直 有 很 多 人 问 如 何 使 用 Java 代 码 来 完 成 在 布 局 文 件 中 的 工 作, 也 就 是 如 何 用 Java 代 码 设 置 组 件 的 属 性 这 个 问 题 对 于 其 他 的 编 程 语 言 ( 如 C# C++ Pascal 等 ) 可 能 并 不 复 杂, 组 件 类 中 都 提 供 了 相 应 的 设 置 属 性 的 方 法, 但 遗 憾 的 是 Androi SDK 中 的 组 件 类 只 提 供 了 很 少 的 用 于 设 置 属 性 的 方 法, 大 多 数 的 属 性 并 没 有 直 接 对 应 的 获 得 和 设 置 属 性 值 的 方 法 所 以 很 多 初 学 者 刚 一 接 触 Android 会 觉 得 有 些 不 知 所 措 事 实 上, 使 用 Java 代 码 可 以 设 置 所 有 的 组 件 属 性, 所 有 这 一 切 只 需 要 一 个 LayoutParams 对 象 使 用 LayoutParams.addRule 方 法 可 以 设 置 组 件 中 所 有 的 属 性 值 最 后 再 调 用 View. setlayoutparams 方 法 用 刚 才 创 建 的 LayoutParams 对 象 更 新 View 中 的 相 应 属 性 的 值 答 案 : 以 按 钮 为 例, 使 用 Java 代 码 设 置 按 钮 的 android:layout_torightof 和 android:layout_below 属 性 的 代 码 如 下 : // 装 载 一 个 布 局 文 件, 要 向 这 个 布 局 中 动 态 添 加 一 个 Button RelativeLayout relativelayout = (RelativeLayout)getLayoutInflater().inflate(R.layout. main, null); // 装 载 要 动 态 添 加 的 按 钮 布 局 17
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 Button button = (Button)getLayoutInflater().inflate(R.layout.button, null); // 创 建 一 个 LayoutParams 对 象 RelativeLayout.LayoutParams layoutparams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); // R.id.button1 是 RelativeLayout 中 已 经 存 在 的 一 个 按 钮 的 id, 动 态 添 加 的 按 钮 在 该 按 钮 的 右 下 方 // 设 置 android:layout_torightof 属 性 的 值 layoutparams.addrule(relativelayout.right_of, R.id.button1); // 设 置 android:layout_below 属 性 的 值 layoutparams.addrule(relativelayout.below, R.id.button1); // 更 新 Button 按 钮 中 相 应 属 性 的 值 button.setlayoutparams(layoutparams); // 向 RelativeLayout 动 态 添 加 一 个 按 钮 relativelayout.addview(button); 扩 展 知 识 : 动 态 设 置 与 布 局 相 关 的 属 性 Android SDK 中 的 所 有 组 件 都 可 以 通 过 LayoutParams.addRule 方 法 设 置 与 布 局 相 关 的 属 性, 而 且 布 局 类 (RelativeLayout LinearLayout 等 ) 中 都 定 义 了 与 相 应 属 性 对 应 的 常 量 例 如, 下 面 的 代 码 将 Button 组 件 的 android:layout_centerinparent 属 性 值 设 为 true 试 题 ] RelativeLayout.LayoutParams layoutparams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 设 置 android:layout_centerinparent 属 性 layoutparams.addrule(relativelayout.center_in_parent, RelativeLayout.TRUE); button.setlayoutparams(layoutparams); relativelayout.addview(button); 面 试 例 题 4: 如 何 动 态 改 变 RelativeLayout 中 按 钮 的 布 局?[ 国 内 某 著 名 互 联 网 公 司 2010 年 面 解 析 : 这 道 题 与 面 试 例 题 3 属 于 同 一 类 型, 也 就 是 需 要 使 用 Java 代 码 设 置 影 响 组 件 相 对 位 置 的 属 性 ( 如 android:layout_torightof android:layout_below 等 ) 答 案 : 首 先 应 获 得 按 钮 对 象, 然 后 使 用 LayoutParams.addRule 方 法 设 置 相 应 的 属 性 例 如, 下 面 的 代 码 将 按 钮 从 左 上 角 的 位 置 动 态 设 置 到 了 屏 幕 中 心 的 位 置 Button button = (Button)relativeLayout.findViewById(R.id.button1); RelativeLayout.LayoutParams layoutparams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 设 置 android:layout_centerinparent 属 性 layoutparams.addrule(relativelayout.center_in_parent, RelativeLayout.TRUE); // 修 改 按 钮 的 android:layout_centerinparent 属 性 的 值 button.setlayoutparams(layoutparams); 18
第 2 章 布 局 2.2.4 TableLayout 布 局 面 试 例 题 1: 请 描 述 一 下 TableLayout 布 局 的 用 法 [ 国 内 某 著 名 互 联 网 公 司 2010 年 面 试 题 ] 答 案 :TableLayout 布 局 使 用 <TableLayout> 来 表 示 在 <TableLayout> 中 嵌 套 <TableRow> 标 签 来 表 示 表 格 布 局 中 的 每 一 条 <TableRow> 标 签 中 可 以 有 不 定 数 目 的 View 因 此, 每 一 条 中 的 列 数 可 以 不 相 等 例 如, 下 面 是 一 个 TableLayout 布 局 的 例 子 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TableRow> android:text=" 第 1 行 第 1 列 " /> android:text=" 第 1 行 第 2 列 " /> </TableRow> <TableRow> android:text=" 第 2 行 第 1 列 " /> android:text=" 第 2 行 第 2 列 " /> android:text=" 第 2 行 第 3 列 " /> </TableRow> </TableLayout> 面 试 例 题 2:<TableLayout> 标 签 的 stretchcolumns 属 性 的 作 用 是 什 么, 如 何 使 用 stretchcolumns 属 性?[ 国 内 某 著 名 社 交 网 站 2011 年 面 试 题 ] 答 案 :stretchcolumns 属 性 用 于 要 拉 伸 的 列 的 索 引 ( 从 0 开 始 ), 如 果 指 定 多 个 列 索 引, 中 间 用 逗 号 (,) 分 隔 TableLayout 会 在 设 置 完 未 通 过 stretchcolumns 指 定 的 列 宽 度 后, 使 用 stretchcolumns 指 定 的 列 填 充 剩 余 的 宽 度 如 果 stretchcolumns 指 定 了 多 列, 这 些 列 会 平 分 剩 余 的 宽 度 stretchcolumns 属 性 的 演 示 代 码 如 下 : <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchcolumns="1" > <TableRow> android:text=" 第 1 行 第 1 列 " android:layout_column="1" /> android:text=" 第 1 行 第 2 列 " /> </TableRow> <TableRow> android:text=" 第 2 行 第 1 列 " android:layout_column="1" /> 19
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 android:text=" 第 2 行 第 2 列 " /> </TableRow> </TableLayout> 2.2.5 AbsoluteLayout 布 局 面 试 例 题 1: 介 绍 一 下 AbsoluteLayout 布 局 的 用 法 答 案 :AbsoluteLayout 称 为 绝 对 布 局, 也 可 称 为 坐 标 布 局 View 可 以 在 AbsoluteLayout 布 局 中 通 过 坐 标 定 位 下 面 的 代 码 演 示 了 AbsoluteLayout 布 局 的 用 法 试 题 ] <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_x="43px" android:layout_y="64px"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="i love Android" android:layout_x="110px" android:layout_y="120px"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="i love Goolge" android:layout_x="140px" android:layout_y="210px"/> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="i love the world" android:layout_x="170px" android:layout_y="255px"/> </AbsoluteLayout> 面 试 例 题 2: 如 何 动 态 改 变 AbsoluteLayout 布 局 中 View 的 位 置?[ 国 内 某 美 食 网 站 2010 年 面 解 析 : 这 道 题 与 2.2.3 节 中 的 面 试 例 题 3 和 面 试 例 题 4 类 似, 也 需 要 在 代 码 中 动 态 设 置 View 与 布 局 相 关 的 属 性 采 用 的 方 法 是 创 建 LayoutParams 对 象, 并 根 据 实 际 情 况 设 置 相 应 的 属 性 值, 然 后 调 用 View.addLayoutParams 方 法 重 新 设 置 View 的 布 局 答 案 : 动 态 改 变 View 位 置 的 代 码 如 下 : View view = findviewbyid(r.id.imageview); 20
第 2 章 布 局 // 设 置 View 的 坐 标 (LayoutParams 构 造 方 法 的 最 后 两 个 参 数, // 也 可 通 过 LayoutParams.x 和 LayoutParams.y 设 置 ) Layout.LayoutParams layoutparams = new AbsoluteLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 300,300); // 重 新 设 置 View 的 布 局 view.tparams(layoutparams); 注 意 AbsoluteLayout 布 局 已 经 在 高 版 本 的 Android 中 被 声 明 为 @Deprecated, 所 以 除 非 必 要, 应 尽 量 避 免 使 用 AbsoluteLayout 2.2.6 将 布 局 存 成 图 像 可 能 很 多 初 学 者 并 不 知 道 Android 还 允 许 直 接 将 布 局 中 的 View 存 成 图 像 这 个 问 题 虽 然 并 不 常 见, 但 仍 然 可 能 会 出 现 在 Android 的 面 试 题 中 由 于 Android 中 的 所 有 可 视 组 件 都 是 绘 制 在 屏 幕 上 的, 因 此,Android SDK 提 供 了 API 允 许 直 接 将 可 视 组 件 绘 制 在 Bitmap 对 象 上 绘 制 可 视 组 件 主 要 涉 及 到 View.setDrawingCacheEnabled 和 View. getdrawingcache 方 法 在 面 试 题 中 可 以 问 这 两 个 方 法 的 用 法, 也 有 可 能 直 接 问 如 何 将 界 面 中 的 组 件 保 存 成 JPG 图 像, 可 干 脆 给 一 个 界 面 截 图, 并 要 求 应 聘 者 编 写 程 序 截 获 该 界 面, 然 后 将 结 果 保 存 成 图 像 文 件 不 管 面 试 题 如 何 出, 答 案 都 类 似, 只 需 回 答 如 何 使 用 View.setDrawingCacheEnabled 和 View. getdrawingcache 方 法 即 可 面 试 例 题 1: 如 何 将 当 前 界 面 的 可 视 组 件 以 同 样 的 相 对 位 置 和 大 小 保 存 在 png 图 像 文 件 中? 要 求 写 出 实 际 的 代 码 [ 美 国 某 著 名 软 件 公 司 2010 年 面 试 题 ] 解 析 : 本 题 需 要 回 答 两 部 分 内 容 : 截 取 当 前 界 面 的 组 件 和 保 存 成 png 图 像 文 件 首 先 要 调 用 view.setdrawingcacheenabled 方 法 打 开 图 像 缓 存, 然 后 使 用 view.getdrawingcache 方 法 获 取 View 的 Bitmap 对 象 保 存 成 png 图 像 使 用 Bitmap. compress 方 法 即 可 答 案 : 将 当 前 界 面 的 可 视 组 件 以 同 样 的 相 对 位 置 和 大 小 保 存 在 png 图 像 文 件 中 的 代 码 如 下 : View view = getlayoutinflater().inflate(r.layout.main, null); // 打 开 图 像 缓 存 view.setdrawingcacheenabled(true); // 必 须 要 调 用 measure 和 layout 方 法 才 能 成 功 保 存 可 视 组 件 的 截 图 到 png 图 像 文 件 // 测 量 View 的 大 小 view.measure(measurespec.makemeasurespec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); // 发 送 位 置 和 尺 寸 到 View 及 其 所 有 的 子 View view.layout(0, 0, view.getmeasuredwidth(), view.getmeasuredheight()); try { // 获 取 可 视 组 件 的 截 图 Bitmap bitmap = view.getdrawingcache(); // 将 截 图 保 存 在 SD 卡 根 目 录 的 test.png 图 像 文 件 中 FileOutputStream fos = new FileOutputStream("/sdcard/test.png"); // 将 Bitmap 对 象 中 的 图 像 数 据 压 缩 成 png 格 式 的 图 像 数 据, 并 将 这 些 数 据 保 存 在 test.png 文 件 中 bitmap.compress(compressformat.png, 100, fos); 21
Android 高 薪 之 路 Android 程 序 员 面 试 宝 典 // 关 闭 文 件 输 出 流 fos.close(); } catch (Exception e) { } 面 试 例 题 2: 使 用 下 面 的 代 码 可 以 成 功 获 取 布 局 的 Bitmap 对 象 吗? 并 说 明 原 因 [ 国 内 某 手 机 软 件 创 业 公 司 2011 年 面 试 题 ] View view = getlayoutinflater().inflate(r.layout.main, null); view.setdrawingcacheenabled(true); Bitmap bitmap = view.getdrawingcache(); 答 案 解 析 : 本 题 考 查 了 在 什 么 情 况 下 才 能 获 取 布 局 截 图 如 果 看 了 面 试 例 题 1 的 解 答 会 很 快 得 出 答 案 : 不 能 成 功 获 取 布 局 的 Bitmap 对 象 在 调 用 View.getDrawingCache 方 法 之 前 需 要 调 用 measure 和 layout 方 法 才 可 以 成 功 获 取 布 局 的 Bitmap 对 象, 代 码 如 下 : view.measure(measurespec.makemeasurespec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getmeasuredwidth(), view.getmeasuredheight()); 2.2.7 设 置 渐 变 背 景 色 面 试 例 题 1: 如 何 将 Android 应 用 程 序 窗 口 的 背 景 色 设 成 渐 变 色?[ 美 国 某 著 名 软 件 公 司 2010 年 面 试 题 ] 解 析 : 本 题 考 查 了 GradientDrawable 类 的 用 法 虽 然 可 以 使 用 渐 变 色 的 图 像 来 渲 染 窗 口 背 景, 但 面 对 这 样 的 面 试 题 时, 更 合 适 的 回 答 是 使 用 GradientDrawable 类, 因 为 这 样 更 灵 活, 可 以 随 时 变 化 背 景 的 渐 变 色 除 了 可 以 设 置 窗 口 的 渐 变 背 景 色 外, 还 可 以 设 置 View( 如 Button TextView 等 ) 的 背 景 色 答 案 : 使 用 GradientDrawable 类 可 以 设 置 窗 口 的 背 景 色 ( 也 可 以 用 同 样 的 方 法 设 置 Button TextView 等 组 件 的 渐 变 背 景 色 ), 代 码 如 下 : // 设 置 从 上 到 下 的 渐 变 色, 上 方 是 红 色, 下 方 是 黄 色 GradientDrawable gradientdrawable = new GradientDrawable( Orientation.TOP_BOTTOM, new int[] { Color.RED, Color.YELLOW }); // 设 置 当 前 窗 口 的 渐 变 背 景 色 getwindow().setbackgrounddrawable(gradientdrawable); 2.3 布 局 属 性 在 实 际 的 布 局 中 会 涉 及 到 很 多 与 布 局 相 关 的 属 性 对 这 些 属 性 的 合 理 应 用 也 会 体 现 开 发 人 员 对 布 局 的 掌 握 程 度 本 节 会 结 合 这 类 面 试 题 给 出 分 析 和 解 答, 以 便 应 聘 者 可 以 更 好 地 应 对 这 类 问 题 22
第 2 章 布 局 2.3.1 android:layout_weight 属 性 面 试 例 题 1: android:layout_weight 属 性 的 作 用 是 什 么? 请 举 例 说 明 [ 美 国 某 著 名 移 动 软 件 公 司 2010 年 面 试 题 ] 答 案 :android:layout_weight 属 性 用 于 设 置 组 件 的 重 要 程 度 重 要 程 度 越 高, 值 越 低 例 如, 在 水 平 方 向 有 2 个 按 钮, 对 应 的 2 个 <Button> 标 签 的 android:layout_weight 属 性 值 分 别 为 1 和 2, 并 且 android:layout_width 属 性 值 都 为 match_parent, 那 么 第 1 个 按 钮 会 占 2/3 的 水 平 空 间, 而 第 2 个 按 钮 会 占 1/3 的 水 平 空 间 注 意 由 于 这 是 在 解 答 面 试 题 ( 审 阅 卷 纸 的 工 作 人 员 一 般 都 对 Android 比 较 熟 悉 ), 而 不 是 在 向 初 学 者 解 释 如 何 使 用 android:layout_weight, 因 此, 一 般 并 不 需 要 将 android:layout_weight 属 性 的 各 个 方 面 的 技 巧 和 应 该 注 意 的 地 方 回 答 得 面 面 俱 到, 只 需 要 根 据 题 目 回 答 即 可 面 试 例 题 2: 请 根 据 图 2.5 由 Button 和 EditText 组 成 的 界 面 写 出 布 局 代 码 [ 国 内 某 著 名 软 件 公 司 2011 年 面 试 题 ] 图 2.5 由 Button 和 EditText 组 成 的 界 面 解 析 : 可 将 如 图 2.5 所 示 的 界 面 看 成 如 下 3 部 分 1. 界 面 顶 端 的 3 个 按 钮 2. 中 间 的 EditText 23