Android 系列 1.14程序:Tipster,Android操作系统的提示计算器

263 篇文章 2 订阅
164 篇文章 0 订阅
1.14程序:Tipster,Android操作系统的提示计算器


问题
当你和朋友去一家餐馆,并希望分开检查和提示,你可以进行大量的手动计算和分歧。相反,你想使用一个应用程序,让你只需添加提示百分比的总数,除以食客的数量。 Tipster是Android中的一个实现,显示一个完整的应用程序。

这是一个简单的练习,它使用Android中的基本GUI元素,然后将它们与一些简单的计算和一些事件驱动的UI代码捆绑在一起。
讨论
Android使用XML文件来布置小部件。在我们的示例项目中,Eclipse的Android插件为布局生成一个main.xml文件。此文件具有不同小部件及其容器的基于XML的定义。
有一个strings.xml文件,其中包含应用程序中使用的所有字符串资源。为应用程序图标提供了一个default icon.png文件。
然后是R.java文件,它是自动生成的(当对任何XML资源文件进行任何更改时都会更新)。此文件具有为每个布局和窗口小部件定义的常量。不要手动编辑此文件; SDK工具会在您对XML文件进行任何更改时为您执行此操作。在我们的示例中,我们使用Tipster.java作为Activity的主Java文件。
创建一个名为Tipster的新Android项目。最终结果将是一个项目布局,如图1-53所示(这是使用Eclipse完成的;在Androit Studio中,文件布局将略有不同,但文件将大体相同。
创建布局和放置窗口小部件
最终目标是创建类似于图1-53所示的布局。对于此屏幕布局,我们将使用以下布局和小部件:
TableLayout
以表格形式查看组件。与HTML表标签范例相似。
TableRow
这将在TableLayout中定义一行。它就像HTML TR和TD标签结合在一起。
TextView
此视图提供了在屏幕上显示静态文本的标签。
EditText
此视图提供了一个用于输入值的文本字段。
RadioGroup
这将“单选按钮”组合在一起,一次只能按下其中一个
(与汽车收音机上的车站选择按钮类比命名)。
单选按钮
这提供了一个单选按钮,用于组中。
按钮
这是常规按钮。
视图
我们将使用视图创建一个具有一定高度和颜色的可视分隔符
属性。
熟悉这些小部件,因为你将在构建的应用程序中使用这些。当您转到Javadocs的布局和窗口小部件时,查找XML属性。这将帮助您将main.xml布局文件中的用法与访问这些文件的Java代码(Tipster.java和R.java)相关联。
还可以使用IDE中的可视布局编辑器,它允许您通过从调色板中拖放窗口小部件来创建布局,就像任何窗体设计器工具一样。然而,这可能是一个很好的练习,你创建的手动的XML布局,至少在你学习Android的初始阶段。稍后,当您了解XML布局API的所有细微差别时,您可以将任务委派给此类工具。
布局文件main.xml具有布局信息(请参见示例1-9)。 TableRow窗口小部件在TableLayout中创建单个行。所以你使用尽可能多的TableRow作为你想要的行数。在本教程中,我们将使用8个TableRow s-5作为窗口小部件,直到按钮下方的可视分隔符,以及三个用于按钮和分隔符下方的结果区域。

实施例1-9。 /res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Using table layout to have HTML table like control over layout -->
<TableLayout
android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Row 1: Text label placed in column zero, text field placed in column two and allowed to
span two columns. So a total of 4 columns in this row -->
<TableRow>
<TextView
android:id="@+id/txtLbl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl1"/>
<EditText
android:id="@+id/txtAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numeric="decimal"
android:layout_column="2"
android:layout_span="2"
/>
</TableRow>
<!-- Row 2: Text label placed in column zero,
text field placed in column two and allowed to
span two columns. So a total of 4 columns in this row -->
<TableRow>
<TextView
android:id="@+id/txtLbl2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl2"/>
<EditText
android:id="@+id/txtPeople"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numeric="integer"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<!-- Row 3: This has just one text label placed in column zero -->
<TableRow>
<TextView
android:id="@+id/txtLbl3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textLbl3"/>
</TableRow>
<!-- Row 4: RadioGroup for RadioButtons placed at column zero
with column span of three, thus creating one radio button
per cell of the table row. Last cell number 4 has the
textfield to enter a custom tip percentage -->
<TableRow>
<RadioGroup
android:id="@+id/RadioGroupTips"
android:orientation="horizontal"

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_span="3"
android:checkedButton="@+id/radioFifteen">
<RadioButton android:id="@+id/radioFifteen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxt15"
android:textSize="15sp" />
<RadioButton android:id="@+id/radioTwenty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxt20"
android:textSize="15sp" />
<RadioButton android:id="@+id/radioOther"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rdoTxtOther"
android:textSize="15sp" />
</RadioGroup>
<EditText
android:id="@+id/txtTipOther"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="decimal"/>
</TableRow>
<!-- Row for the Calculate and Rest buttons. The Calculate button
is placed at column two, and Reset at column three -->
<TableRow>
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:text="@string/btnReset"/>
<Button
android:id="@+id/btnCalculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="3"
android:text="@string/btnCalculate"/>
</TableRow>
<!-- TableLayout allows any other views to be inserted between
the TableRow elements. So insert a blank view to create a
line separator. This separator view is used to separate
the area below the buttons which will display the
calculation results -->
<View
android:layout_height="2px"
android:background="#DDFFDD"

android:layout_marginTop="5dip"
android:layout_marginBottom="5dip"/>
<!-- Again table row is used to place the result textviews
at column zero and the result in textviews at column two -->
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl4"/>
<TextView
android:id="@+id/txtTipAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl5"/>
<TextView
android:id="@+id/txtTotalToPay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<TableRow android:paddingBottom="10dip" android:paddingTop="5dip">
<TextView
android:id="@+id/txtLbl6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/textLbl6"/>
<TextView
android:id="@+id/txtTipPerPerson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_span="2"/>
</TableRow>
<!-- End of all rows and widgets -->
</TableLayout>

TableLayout和TableRow
在检查main.xml之后,您可以收集TableLayout和TableRow可以直接使用。您创建TableLayout一次,然后插入TableRow。现在,您可以在此TableRow中自由插入任何其他小部件,例如TextView,EditView等。
看看属性,特别是android:stretchColumns,android:layout_column和android:layout_span,它们允许你以和使用普通HTML表格相同的方式放置小部件。我建议你跟随这些属性的链接,并阅读他们如何工作一个TableLayout。
控制输入​​值
控制输入​​值:查看main.xml文件中的EditText小部件。这是输入支票“总金额”的第一个文本字段。我们只需要数字。我们可以接受十进制数,因为真正的餐厅支票可以是美元和美分,而不只是美元。所以我们使用android:numeric属性的值为dec​​imal。这将允许像10这样的整数值和10.12的十进制值,但会阻止任何其他类型的条目。
类似地,使用android:整数,因为你不能吃一半的客人晚餐!
这是一个简单和简洁的方法来控制输入值,从而节省我们在Tipster.java文件中编写验证代码,并确保用户不输入错误的值的麻烦。这种基于XML的约束功能是相当强大和有用的。您应该探索与特定窗口小部件一起使用的所有可能的属性,以从此XML简写设置约束的方法中提取最大的好处。在未来的版本中,除非我在这个版本中完全错过它,我希望Android允许输入android:numeric属性的范围,以便我们可以定义我们希望接受的数字范围。
由于范围目前不可用(据我所知),稍后我们将看到,我们必须检查某些值(如零或空值),以确保我们的提示计算算法不会失败。
检查Tipster.java
现在我们将看看控制我们的应用程序的Tipster.java文件。这是执行布局,事件处理和应用程序逻辑的主类。 Android Eclipse插件使用示例1-10中所示的默认代码在我们的项目中创建Tipster.java文件。

例子 1-10. Code snippet 1 of /src/com/examples/tipcalc/Tipster.java

package com.examples.tipcalc;
import android.app.Activity;
public class Tipster extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Tipster类扩展了android.app.Activity类。活动是用户可以做的一个单一,集中的事情。 Activity类负责创建窗口,然后布局UI。你必须调用setContentView(View view)方法将你的UI放在Activity中。所以认为活动作为一个外框架是空的,你填充你的UI。
现在看看示例1-11中显示的Tipster.java类的代码段。首先,我们将窗口小部件定义为类成员。 (特别是通过引用。)然后我们使用findViewById(int id)方法来定位小部件。当您在Eclipse中清理和构建项目时,在main.xml文件中定义的每个窗口小部件的ID将在R.java文件中自动定义。 (如果您已将Eclipse设置为自动构建,则在更新main.xml时,会立即更新R.java文件。)
每个小部件都派生自View类,并提供特殊的GUI功能。因此,TextView提供了一种在UI上放置标签的方法,而EditText提供了一个文本字段。查看示例1-11中的through。您可以看到findViewById()如何用于定位小部件。
实施例1-11。 /src/com/examples/tipcalc/Tipster.java的代码段2

public class Tipster extends Activity {
// Widgets in the application
private EditText txtAmount;
private EditText txtPeople;
private EditText txtTipOther;
private RadioGroup rdoGroupTips;
private Button btnCalculate;
private Button btnReset;
private TextView txtTipAmount;
private TextView txtTotalToPay;
private TextView txtTipPerPerson;

// For the id of radio button selected
private int radioCheckedId = -1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Access the various widgets by their id in R.java
txtAmount = (EditText) findViewById(R.id.txtAmount);
//On app load, the cursor should be in the Amount field
txtAmount.requestFocus();
txtPeople = (EditText) findViewById(R.id.txtPeople);
txtTipOther = (EditText) findViewById(R.id.txtTipOther);
rdoGroupTips = (RadioGroup) findViewById(R.id.RadioGroupTips);
btnCalculate = (Button) findViewById(R.id.btnCalculate);
//On app load, the Calculate button is disabled
btnCalculate.setEnabled(false);
btnReset = (Button) findViewById(R.id.btnReset);
txtTipAmount = (TextView) findViewById(R.id.txtTipAmount);
txtTotalToPay = (TextView) findViewById(R.id.txtTotalToPay);
txtTipPerPerson = (TextView) findViewById(R.id.txtTipPerPerson);
// On app load, disable the Other Tip Percentage text field
txtTipOther.setEnabled(false);

解决易用性或可用性问题
我们的应用程序必须尝试与任何其他已建立的应用程序或网页一样可用。总之,添加可用性功能将带来良好的用户体验。为了解决这些问题,再次查看示例1-11。
看看我们使用View类的requestFocus()方法的位置。由于EditText小部件是从View类派生的,所以此方法适用于它。这样做,以便当我们的应用程序加载时,总量文本字段将接收焦点,并将光标放置在其中。这类似于流行的Web应用程序登录屏幕,其中光标位于用户名文本字段中。
现在,通过调用Button小部件上的setEnabled(boolean enabled)方法,查看Calculate按钮的禁用位置。这样做是为了使用户在必填字段中输入值之前不能点击它。如果我们允许用户单击计算而不在“总金额”和“人员数”字段中输入值,那么我们必须写入验证码以捕获这些条件。这将需要显示一个警告弹出窗口警告用户关于空值。这增加了不必要的代码和用户交互。当用户看到“计算”按钮被禁用时,很明显,除非输入所有值,否则无法计算提示。
看看例1-11。此处禁用“其他提示百分比”文本字段。这是因为在应用程序加载时默认选择“15%提示”单选按钮。应用程序加载的默认选择是通过main.xml文件完成的。查看main.xml的行,其中以下语句选择“15%提示”单选按钮:
android:checkedButton =“@ + id / radioFifteen”
默认情况下,RadioGroup属性android:checkedButton允许您选择组中的一个RadioButton小部件。
大多数在桌面和Web上使用流行应用程序的用户都熟悉“在某些条件下启用的窗口小部件”范例。添加这样的小便利始终使应用程序更可用,用户体验更丰富。
处理UI事件
像流行的Windows,Java Swing,Flex和其他UI框架,Android还提供了一个事件模型,它允许您监听用户界面中由用户交互引起的某些事件。让我们看看我们如何在我们的应用程序中使用Android事件模型。
首先让我们关注UI中的单选按钮。我们想知道用户选择了哪个单选按钮,因为这将允许我们在我们的计算中确定提示百分比。要“收听”单选按钮,我们使用静态接口OnCheckedChangeListener()。这将通知我们何时收音机的选择状态
按钮更改。
在我们的应用程序中,我们要仅在选择其他单选按钮时启用其他提示百分比文本字段。当选择“15%提示”和“20%提示”按钮时,我们要禁用此文本字段。除此之外,我们想为了可用性添加一些更多的逻辑。正如我们之前讨论的,我们不应该启用计算按钮,直到所有必需的字段都有有效的值。对于三个单选按钮,我们要确保计算按钮在以下两个条件下启用:
•已选择其他单选按钮,“其他提示百分比”文本字段具有有效值。
•选择“15%提示”或“20%提示”单选按钮,并且“总数”和“人数”文本字段具有有效值
看看例1-12,它处理单选按钮。源代码注释是很自明的。
实施例1-12。 /src/com/examples/tipcalc/Tipster.java的代码段3

/*
* Attach an OnCheckedChangeListener to the
* radio group to monitor radio buttons selected by user
*/
rdoGroupTips.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// Enable/disable Other Tip Percentage field
if (checkedId == R.id.radioFifteen
|| checkedId == R.id.radioTwenty) {
txtTipOther.setEnabled(false);
/*
* Enable the calculate button if Total Amount and No. of
* People fields have valid values.
*/
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0);
}
if (checkedId == R.id.radioOther) {
// enable the Other Tip Percentage field
txtTipOther.setEnabled(true);
// set the focus to this field
txtTipOther.requestFocus();
/*
* Enable the calculate button if Total Amount and No. of
* People fields have valid values. Also ensure that user
* has entered an Other Tip Percentage value before enabling
* the Calculate button.
*/
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0);
}
// To determine the tip percentage choice made by user
radioCheckedId = checkedId;
}
});

监视文本字段中的关键活动
如前所述,除非文本字段具有有效值,否则不能启用计算按钮。因此,我们必须确保只有在总金额,人数和其他提示百分比文本字段具有有效值时,才会启用计算按钮。 “其他提示百分比”文本字段仅在选择“其他提示百分比”单选按钮时启用。
我们不必担心值的类型,即用户是否输入负值或字母,因为已经为文本字段定义了android:numeric属性,从而限制了用户可以输入的值的类型。我们必须确保这些价值观是存在的。
所以我们使用静态接口OnKeyListener()。这将在按下一个键时通知我们。通知在实际按键被发送到EditText小部件之前到达我们。
查看示例示例1-13和示例1-14中处理文本字段中关键事件的代码。如例1-12所示,源代码注释是相当自我规范的。
实施例1-13。 /src/com/examples/tipcalc/Tipster.java的代码段4
/ *
*将KeyListener附加到提示金额,人数和其他提示
*百分比文本字段
* /
txtAmount.setOnKeyListener(mKeyListener);
txtPeople.setOnKeyListener(mKeyListener);
txtTipOther.setOnKeyListener(mKeyListener);
请注意,我们只创建一个侦听器,而不是为每个文本字段创建匿名/内部侦听器。我不知道我的风格是更好还是推荐,但我总是写在这种风格,如果听众要执行一些常见的操作。这里所有文本字段的共同关注是它们不应该是空的,并且只有当它们有值时,应该启用计算按钮。
实施例1-14。 KeyListener.java中的代码片段5
/ *
* KeyListener用于总金额,人数和其他提示百分比文本字段。我们需要应用此键监听器来检查以下条件:
*:
* 1)如果用户选择“其他提示百分比”,则“其他提示百分比”文本字段应具有由用户输入的有效提示百分比。仅当用户输入有效值时,才启用计算按钮。
*:
* 2)如果用户未在人数字段的总金额和人数字段中输入值,
*我们无法执行计算。因此,只有当用户输入有效值时,我们才能启用计算按钮。
* /
private OnKeyListener mKeyListener = new OnKeyListener(){

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (v.getId()) {
case R.id.txtAmount:
case R.id.txtPeople:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0);
break;
case R.id.txtTipOther:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0);
break;
}
return false;
}
};

在示例1-14中,我们检查视图的ID。记住每个小部件都有一个唯一的ID,因为我们在main.xml文件中定义它。这些值然后在生成的R.java类中定义。
在和时,如果键事件发生在总金额或人数字段中,我们检查在字段中输入的值。我们确保用户没有将这两个字段留空。
在我们检查用户是否已选择其他单选按钮,然后我们确保其他文本字段不为空。我们还会再次检查总金额和人数字段是否为空。
所以我们的KeyListener的目的现在是明确的:确保所有文本字段不为空,然后启用计算按钮。
收听按钮点击
现在我们来看看计算和重置按钮。当用户单击这些按钮时,我们使用静态接口OnClickListener(),这将让我们知道什么时候点击按钮。
正如我们对文本字段做的,我们只创建一个监听器,在其中我们检测哪个按钮被点击。根据单击的按钮,调用calculate()或reset()方法。例1-15显示了如何将点击监听器添加到按钮。

例子 1-15. Code snippet 6 of /src/com/examples/tipcalc/Tipster.java
/* Attach listener to the Calculate and Reset buttons */
btnCalculate.setOnClickListener(mClickListener);
btnReset.setOnClickListener(mClickListener);
Example 1-16 shows how to detect which button is clicked by checking for the ID of
the  View that receives the click event.
Example 1-16. Code snippet 7 of /src/com/examples/tipcalc/Tipster.java
/**
* ClickListener for the Calculate and Reset buttons.
* Depending on the button clicked, the corresponding
* method is called.
*/
private OnClickListener mClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.btnCalculate) {
calculate();
} else {
reset();
}
}
};

重置应用程序
当用户单击重置按钮时,应清除文本字段,应选择默认的“15%提示”单选按钮,并应清除计算的任何结果。 例1-17显示了reset()方法。

例 1-17. Code snippet 8 of /src/com/examples/tipcalc/Tipster.java
/**
* Resets the results text views at the bottom of the screen as well as
* resets the text fields and radio buttons.
*/
private void reset() {
txtTipAmount.setText("");
txtTotalToPay.setText("");
txtTipPerPerson.setText("");
txtAmount.setText("");
txtPeople.setText("");
txtTipOther.setText("");
rdoGroupTips.clearCheck();
rdoGroupTips.check(R.id.radioFifteen);
// set focus on the first field

txtAmount.requestFocus();
}

验证输入以计算提示
如前所述,我们限制用户可以在文本字段中输入的值的类型。但是,用户仍然可以在“总金额”,“人员数”和“其他提示百分比”文本字段中输入零值,从而导致错误条件,例如我们提示计算中的除以零。
如果用户输入0,我们必须显示一个警告,要求用户输入非零值。我们使用一个名为showErrorAlert(String errorMessage,final int fieldId)的方法来处理这个问题,但我们稍后会详细讨论这个问题。首先,看看示例1-18,其中显示calculate()方法。注意用户输入的值如何解析为双精度值。现在注意,我们检查零值。如果用户输入0,我们将显示一个警告弹出以警告用户。接下来,查看其他提示百分比文本字段已启用,因为用户选择了其他单选按钮。在这里,我们也必须检查尖端百分比为零。
当应用程序加载时,默认情况下选择“15%提示”单选按钮。如果用户更改选择,我们将所选单选按钮的ID分配给成员变量radioCheckedId,如例1-12所示,在OnCheckedChangeListener中。
但是如果用户接受默认选择,radioCheckedId将具有默认值-1。总之,我们永远不知道选择了哪个单选按钮。当然,我们知道默认情况下选择哪一个,并且逻辑编码略有不同,如果radioCheckedId的值为-1,则假定为15%。但是如果你引用API,你会看到我们可以在RadioGroup上调用方法getCheckedRadioButtonId(),而不是在单个单选按钮上。这是因为OnCheckedChangeListener很容易向我们提供所选单选按钮的ID。
显示结果
计算提示很简单。如果没有验证错误,布尔标志isError将为false。查看例1-18中的简单提示计算。接下来,将计算的值设置为从到的TextView小部件。
实施例1-18。 /src/com/examples/tipcalc/Tipster.java的代码段9

private void calculate() {
Double billAmount = Double.parseDouble(
txtAmount.getText().toString());
Double totalPeople = Double.parseDouble(
txtPeople.getText().toString());
Double percentage = null;
boolean isError = false;
if (billAmount < 1.0) {
showErrorAlert("Enter a valid Total Amount.",
txtAmount.getId());
isError = true;
}
if (totalPeople < 1.0) {
showErrorAlert("Enter a valid value for No. of People.",
txtPeople.getId());
isError = true;
}
/*
* If the user never changes his radio selection, then it means
* the default selection of 15% is in effect. But it's
* safer to verify
*/
if (radioCheckedId == -1) {
radioCheckedId = rdoGroupTips.getCheckedRadioButtonId();
}
if (radioCheckedId == R.id.radioFifteen) {
percentage = 15.00;
} else if (radioCheckedId == R.id.radioTwenty) {
percentage = 20.00;
} else if (radioCheckedId == R.id.radioOther) {
percentage = Double.parseDouble(
txtTipOther.getText().toString());
if (percentage < 1.0) {
showErrorAlert("Enter a valid Tip percentage",
txtTipOther.getId());
isError = true;
}
}
/*
* If all fields are populated with valid values, then proceed to
* calculate the tips
*/
if (!isError) {
Double tipAmount = ((billAmount * percentage) / 100);
Double totalToPay = billAmount + tipAmount;
Double perPersonPays = totalToPay / totalPeople;
txtTipAmount.setText(tipAmount.toString());
txtTotalToPay.setText(totalToPay.toString());

txtTipPerPerson.setText(perPersonPays.toString());
}
}

显示警报
显示警报Android提供AlertDialog类以显示警报弹出窗口。
这使我们可以显示一个对话框,最多三个按钮和一条消息。
示例1-19显示了showErrorAlert方法,它使用此AlertDialog显示错误消息。 注意,我们传递两个参数到这个方法:String errorMessage和int fieldId。 第一个参数是我们要向用户显示的错误消息。 fieldId是导致错误条件的字段的ID。 在用户关闭警报对话框后,此字段ID将允许我们请求对该字段的焦点,因此用户知道哪个字段有错误。
实施例1-19。 /src/com/examples/tipcalc/Tipster.java的代码段10

/**
* Shows the error message in an alert dialog
*
* @param errorMessage
* String for the error message to show
* @param fieldId
* the Id of the field which caused the error.
* This is required so that the focus can be
* set on that field once the dialog is
* dismissed.
*/
private void showErrorAlert(String errorMessage,
final int fieldId) {
new AlertDialog.Builder(this).setTitle("Error")
.setMessage(errorMessage).setNeutralButton("Close",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
findViewById(fieldId).requestFocus();
}
}).show();
}

当所有这一切放在一起,它应该看起来像图1-53。


图1-53。 行动中的Tipster
结论
为Android操作系统开发与为任何其他UI工具包开发,包括Microsoft Windows,X Windows,Java Swing或Adobe Flex没有太大的区别。 当然Android有它的差异,总体来说,一个非常好的设计。 XML布局范例对于使用简单的XML构建复杂的UI非常有用。 此外,事件处理模型是简单,功能丰富,并且直观的在代码中使用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值