65.9K
CodeProject 正在变化。 阅读更多。
Home

如何使用生成可用 XML 和 Java 的 Android 布局模拟工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (14投票s)

2014年6月5日

CPOL

11分钟阅读

viewsIcon

40980

downloadIcon

830

无需编写任何代码即可为 Droidio(Android Studio)生成可用的布局 XML 和 Java。

生成 Android 布局 XML 的另一种方法

注意:最新的源代码和 .exe 中现在提供“暗黑模式”,选择它会将背景设为黑色,TextView 文本设为黄色,Button 文本设为白色,EditText “内部”设为白色。

在 Eclipse 的早期,创建 Java 应用的 GUI/View 部分非常困难。后来出现了 Droidio(也称为“Android Studio”),它使创建 Android 布局变得更加容易。你只需在 Design 模式下打开一个布局(XML)文件,然后将控件拖放到设计界面上。

然而,仍然需要进行大量调整才能使布局达到你想要的外观——添加容器(这些容器通常需要复制粘贴到某些控件的上方或下方,然后你还需要将控件复制粘贴到容器内部,接着还有要设置的属性,例如宽度和高度等等,没完没了)。

因此,一旦我确定了通常情况下我想要的典型布局(当然,这取决于你个人需求!),即使用一个外部垂直 LinearLayout 包含多个内部水平 LinearLayout,我决定创建一个(用 C# 编写的)实用工具,以便能够轻松创建我心中所想的 Android 布局模型,至少能生成一个不错的 XML 起始点。

回归测试

为了生成正确的 Layout XML,你首先需要将一些辅助 XML 文件添加到你的 drawables 文件夹中。当然,你只需要做一次,所以当你选择“Generate XML for Layout...”按钮时,它不会生成这个;相反,在那之前,当你启动该实用工具时,你可以从“Generated XML”选项卡复制粘贴你需要的内容到相应的位置。

注意:当你选择“Generate XML...”按钮后,这些辅助 XML 会被覆盖,所以如果你想要它,必须在此之前(任何时候启动该实用工具时)获取它。

其他“辅助”XML 值

遵循关注点分离 (SOC)不要重复自己 (DRY) 原则,strings 也被放置在它们应有的位置(而不是直接作为原始值放在控件属性中)。因此,这些也作为实用工具 XML 生成过程的一部分生成,并且必须在你的布局外观正常且功能正常之前复制粘贴到相应的位置。但我有点说得太快了——我们稍后会讲到。让我们一步步来完成使用我的实用工具创建 Android 布局文件的过程。

承认过错,羞愧难当

在向你展示实用工具之前,我必须承认:它如果不是“比一袋烂棉絮丑 9 倍”*,也绝无可能获得任何美学奖项。它很朴素,有点笨拙,完全不打算精确还原你在 Android 中实际看到的样子。换句话说,它并非一个“相当合理的仿制品”;或许是模糊仿制品的半合理仿制品——如果你眯起眼睛,并宽宏大量地评价它的着装实际效果。

* 抱歉/赞美 Eddie J. Nelson,据我所知,他原创了这种描述性说法。

不祥的第一印象

勇敢的读者,请看,当实用工具启动时所呈现的朴素而简约的外观。

预期结果

在你开始创建模型之前,你需要知道最终结果应该是什么样子。无论是画在一张纸上、现有“布局”的截图,甚至是仅仅“在脑海中”,你都需要有一个目标。在本例中,我们将尝试(大体上)复制这个艺术设计的奇迹。

基本规则

由于我使用的是 LinearLayout,我“看到”这种形式是一系列行,即:

  • 第一、第二和第三行(行 0..2)== LabelTextBox(在 Android 语境中是“TextView”和“EditText”)
  • 第四和第五行(行 3,4)== TextViewComboBox(在 Android 语境中是“Spinner”)
  • 第六和第八行(行 5,7)== TextView
  • 第七和第九行(行 6,8)== RadioGroup,其中包含三个 RadioButtons
  • 第十行(行 9)== Checkbox 和两个 Buttons

理解实用工具的世界观

你的布局的每一行都在实用工具的独立选项卡上创建。每行最多可以添加六个控件,尽管通常只会有一个或两个。这里的“六个”是一个“极端”情况,但如果你愿意,可以更改它,因为我提供了代码。行数也类似——我设置了上限为 12 行,但你可以更改(实际上,可以双向更改)。

每次完成一行后,你应该选择“Show Mockup of Current Row”按钮;这会在底部的 FlowLayoutPanel(就在实用工具底部按钮行之上)中显示你选择的控件的“Windows”版本,并对它们在 Android 布局中的外观有一个(非常)大致的 ধারণা。

你可以随时进行更改并重新选择按钮。对于“Show Mockup of All Rows”按钮也是如此,当你选择它时,它会激活“Mockup”选项卡,你将看到你到目前为止所做的内容。“Mockup”选项卡显示的是来自每个“Row”选项卡底部 FlowLayoutPanels 中的图像(不是真实的控件)。

请注意!在选择“Generate XML for Layout and Java for Activity”按钮之前,你必须为设计过的每一行选择“Show Mockup of Current Row”按钮,因为每个“Row”选项卡底部 FlowLayoutPanels 上的行模型会“截图”显示在“Mockup”选项卡上。

如果你想要一次“Mulligan”(重来)的机会,请按“Clear All”按钮,行模型将被销毁。

现在让我们开始吧

所以,对于第一行,我选择一个 TextView 并为其赋值“Invoice #”

...然后是一个 EditText,并为其指定一个合适的名称。

请注意,我还为它选择了一个橙色边框(参见上面“回归测试”部分)。

迫不及待

我知道你们迫不及待地等待着(不是“诱惑”着,好像你要去钓鱼一样),所以现在让我们按下“Show Mockup of Current Row”按钮。这便是呈现出来的令人振奋的景象。

回到绘图板

现在我添加下一行的值(“Date”和“Total Amt $”);由于它们与第一行非常相似,我将不再展示;就当完成了吧(记住要移动到每一行的相应选项卡)。但请注意(这是一个改进的领域),Android 有一个“Date”文本字段和一个“Number(Decimal)”字段,它们比我的实用工具生成的通用 EditText 更具体。实用工具可以增强以生成这些更具体的控件,或者你可以在事后,在 Droidio 编辑器中,通过 EditTextinputType 属性进行调整(它有无数种不同的选项,包括电子邮件地址、密码、电话号码等等)。

对于 row3,我们需要一个 TextView 和一个 Spinner。当在行中选择 Spinner 作为第二个控件时,你看到的就是这样。

...然后选择“Show Mockup of Current Row”按钮,并在 FlowLayoutPanel 上下拉组合框。

第 4 行(“Site #”)非常相似。视为已完成。

第 5 行是 Label/TextView(“Edit List”)。视为已完成。

第 6 行是一个 RadioGroup,包含三个 Radio Buttons。为此,请在“Row 6”选项卡上的第一个 comboBox 中选择“Radio Group”,然后输入这些值。

第 7 行是 Label/TextView(“Redemptions”)。视为已完成。

第 8 行与第 6 行相似。视为已完成。

对于最后一行,即第 9 行,添加一个 CheckBox

...然后是两个按钮。

(这里只显示了添加的第一个按钮。)

你的想象力有多好?

现在我们已经添加了 Layout 的所有行,我们可以按下“Show Mockup of All Rows”按钮。这就是我们看到的结果(梵高,吃你的心吧)。

正如你所见,这并没有真正让你对布局的最终外观有一个好的了解。它只是一个非常粗略的 ধারণা。它更像一个“健全性检查”,以便你可以验证所有你打算放置的组件都在那里,并且它们位于正确的行上。在生成 XML 和 Java 之前,你随时可以“重做”任何一行。

奏响乐曲、敲响鼓点、营造期待的停顿

现在,一旦你基本确定已经准备好生成代码,你就可以按下“Generate XML for Layout and Java for Activity”按钮。你将看到类似这样的内容。

只需按照“注释”中的说明进行操作(将字符串复制到 strings.xml,将字符串数组复制到 arrays.xml,然后将布局 XML 复制到 Droidio 中的相应布局 XML 文件中)。你必须按此顺序(从上到下)进行操作,否则布局 XML 会因缺少 strings 而报错。

注意:如果你间接创建了一个值已存在于 strings.xml 文件中的字符串(例如,如果你有两个“OK”按钮),那么该条目已存在于 strings.xml 中,并且不允许重复。因此,如果你复制粘贴了一个重复项,你必须删除其中一个(除非你喜欢项目无法编译的宁静)。

对于 arrays.xml 中的字符串数组也是如此——你不能有多个同名的字符串数组。如果你出现这种情况,要么删除其中一个,要么如果它们包含不同的值集,就更改其中一个的名称(并确保更新布局 XML 中使用这些值的控件的引用)。

我想要牵你的手

所以,为了把事情说得一清二楚,请遵循以下步骤(在你做过一次之后,它应该会变得自然而然,并显得显而易见)。

复制字符串(在“// Add these strings to [appName]\app\src\main\res\values\strings.xml ”下面),并将它们追加到你的 Strings.xml 文件中。

复制字符串数组(在“// Add these strings to [appName]\app\src\main\res\values\arrays.xml ”下面),并将它们追加到你的 arrays.xml 文件中。

复制“// Add the rest to the appropriate layout file ([appName]\app\src\main\res\layout\?.xml ) ”下面的所有内容到你的布局 XML 文件中,覆盖其中的任何内容(你可能想先备份它,或者至少复制到文本文件中)。

如果你需要知道如何在 Droidio 中添加布局文件,请阅读我这里的文章。

如果一切顺利,现在你应该看到类似这样的内容。

正如你所见,最后一行只显示了部分内容;在这种情况下(屏幕上会有很多内容),你可以勾选“Enclose Layout in ScrollViewer element (you will want this if your Layout may overflow the screen)”复选框,它会将 Layout XML 包装在 ScrollView 元素中,让你可以在“运行时”(实际上是“模拟运行时”)向下滚动,并像这样查看 Layout 的其余部分。

……然后在向下滚动后。

至少在当前版本的 Droidio(当时是 0.59 版本)中,当你向 Layout 添加 ScrollView 时,它不再显示设备,而只显示设计界面。

这样做的优点是,你现在可以看到所有控件。

另外,还有可选的 Java 代码已经生成。转到“Generated Java”选项卡访问它。你应该看到类似这样的内容。

// Add the following to the Activity's onCreate() event
EditText _edttxtInvoiceNum = (EditText) findViewById(R.id.edttxtInvoiceNum);
EditText _edttxtDate = (EditText) findViewById(R.id.edttxtDate);
EditText _edttxtTotalAmt = (EditText) findViewById(R.id.edttxtTotalAmt);
Spinner _spnrspinnerVendorID = (Spinner) findViewById(R.id.spnrspinnerVendorID);
Spinner _spnrspinnerSiteNum = (Spinner) findViewById(R.id.spnrspinnerSiteNum);
CheckBox _ckbxAllow_New_Items = (CheckBox) findViewById(R.id.ckbxAllow_New_Items);
Button _btnOK = (Button) findViewById(R.id.btnOK);

_btnOK.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
        // TODO: Finish
    }
});

Button _btnCancel = (Button) findViewById(R.id.btnCancel);

_btnCancel.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
        // TODO: Finish
    }
});

如果你将此 Java 代码复制到相应的 Activity 的 onCreate() 事件中,你将已经拥有对相应控件的引用,并且为你添加的任何按钮设置了“Click”(很可能更像是“Tap”)事件处理程序。有关如何在事件处理程序中添加 Toasts 作为“健全性检查”的说明,请参阅这个技巧

有时文章只是一个粒子

请记住,这个实用工具是一个“正在进行中的工作”,功能非常有限。它只创建 LinearLayout 类型的布局,不考虑不同的方向,也不理解设备尺寸的差异。换句话说,它是一个“快速简便”的工具,而不是一个功能丰富、性能卓越、奇迹般的 Nth 产品。话虽如此,它可能仍然对你有价值——或者也许你可以增强它,让它“更好”。

感谢所有在编码方面提供帮助的人;如果你查看源代码,你会看到几个链接到 StackOverflow 的答案,它们帮助了这个实用工具的实现。

© . All rights reserved.