大多数应用都需要以某种方式响应用户,怎样让你的应用更有交互性,就是这篇文章的内容。
你将看到如何让应用响应用户,另外如何让活动和布局像好朋友一样交谈。在这个过程中还会介绍R,带你更深入地了解Android具体如何工作,R就像是个神秘的宝贝,可以把所有这些连接在一起。
构建一个啤酒推荐师应用,在这个应用中,用户可以选择他们喜欢的啤酒类型,然后单击一个按钮,得到一个列表。
这个应用的结构如下:
1、布局三个GUI组件:
一个值下拉列表,这称为spinner,允许用户选择他们想要的啤酒类型;
一个按钮,按下这个按钮会返回根据类型选择的啤酒;
一个文本域,用来显示啤酒类型。
2、文件string.xml包括布局所需的所有字符串资源,例如布局中指定的按钮标签和啤酒类型
3、活动指定应用如何与用户交互,活动得到用户选择的啤酒类型,利用这个信息显示用户可能感兴趣的一组啤酒。这里要借助于一个定制Java类。
这个定制Java类包含应用的应用逻辑,它包括一个方法,这个方法取啤酒类型作为参数,返回这种类型的一个啤酒列表。活动会调用这个方法,传入啤酒类型,然后使用得到的响应。
一、创建工程
1、打开AS,选择Start a new Android Studio project。
2、输入应用名Beer Adviser,域名hfad.com,使得包名为com.hfad.beeradviser。不要包含C++选项
3、选择最低的SDK为API 19,另外确保选中Phone and Tablet。如此一来可以在大多数手机和平板上运行。
4、选择一个空活动作为默认活动,将活动命名为FindBeerActivity。相应的布局名为activity_find_beer。确保勾选生成布局的选项,另外不要选Backwards Compatibility选项。
5、单击Finish后,AS会创建一个工程其中包含名为FindBeerActivity.java的活动和一个名为activity_find_beer.xml的布局。下面修改这个xml文件成下面这个样子。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
tools:context="com.hfad.beeradviser.FindBeerActivity"
>
<Spinner
android:id="@+id/color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_gravity="center"
android:layout_margin="16dp"
android:entries="@array/beer_colors"
/>
<Button
android:id="@+id/find_beer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:text="@string/find_beer"
android:onClick="onClickFindBeer"
/>
<TextView
android:id="@+id/brands"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:text="@string/brands"
/>
</LinearLayout>
相比直接编辑xml文件,设计编辑器还提供了一种更直观的方式来编辑布局代码,可以直接从组件面板上拖入设计编辑器,相应的代码编辑器中的代码也会自动生成对应的代码。
下面简单介绍一下xml中的组件及其一些属性。
按钮和文本视图是同一个Android View类的子类。
按钮和文本视图之所以会有共同的属性,原因在于它们都继承了同一个Android View类。
1、android:id 为组件指定一个标识名,利用id属性,可以通过活动代码控制组件要做的工作:
android:id = "@+id/button"
2、android:layout_width
3、android:layout_height 这两个属性指定了组件的宽度和高度,“wrap_content”表示它要足够大,刚好能放下全部内容。”match_parent“表示它要与包含这个组件的布局有同样的高度。
4、android:text会告诉组件所显示的文本。
5、LinearLayout元素告诉布局中的各个GUI组件要在一行或一列上相邻显示。用android:orientation属性指定方向,
6、Spinner是下拉列表,Button是按钮,TextView是文本值。
若使用android:text属性硬编码设置文本视图中显示的文本,比如android:text = ”Hello World!“ />,这样一来全局修改文本会很困难,于是我们应该把文本放在字符串资源文件string.xml中。
如此一来只需要修改string.xml文件便可修改应用中的文本。下面是string.xml文件的格式。
<resources>
<string name="app_name">Beer Adviser</string>
<string name="find_beer">Find Beer!</string>
<string name="brands">No beers selected</string>
<string-array name="beer_colors">
<item>light</item>
<item>amber</item>
<item>brown</item>
<item>dark</item>
</string-array>
</resources>
在布局代码中使用字符串资源时
android:text=“@string/find_beer” />
其中@string就是告诉Android要从一个字符串资源文件中查找一个文本值,然后再找到名为find_beer的值。
下面要让按钮做点事情。我们希望应用能完成以下工作。
①用户从spinner选择一个啤酒类型
②用户单击Find Beer按钮,布局指定活动中要调用的方法
③活动中这个方法获取spinner中选择的啤酒类型值,把它传递给Java类BeerExpert的getBrands()方法。
④BeerExpert的getBrands()方法查找与这个啤酒类型匹配的啤酒品牌,然后作为一个String ArrayList返回给活动
⑤活动得到布局中文本视图的一个引用,将这个文本视图的文本值设置为与类型匹配的啤酒列表。
让按钮调用一个方法,需要修改布局文件activity_find_beer.xml,指定单击按钮时调用活动中的哪个方法,需要修改活动文件FindBeerActivity.java编写所调用的方法。
在xml文件中为button增加一个**android:onClick = “method_name”**表示单击这个按钮时就会调用method_name的方法。下面是FindBeerActivity.java
package com.hfad.beeradviser;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.List;
public class FindBeerActivity extends Activity {
private BeerExpert expert = new BeerExpert();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_beer);
}
//单击按钮时调用
public void onClickFindBeer(View view) {
//获取对文本视图的引用
TextView brands = (TextView) findViewById(R.id.brands);
//获取对下拉框的引用
Spinner color = (Spinner) findViewById(R.id.color);
//在下拉框中获取所选项
String beerType = String.valueOf(color.getSelectedItem());
//从啤酒专家类中获取建议
List<String> brandsList = expert.getBrands(beerType);
StringBuilder brandsFormatted = new StringBuilder();
for (String brand : brandsList) {
brandsFormatted.append(brand).append('\n');
}
//展示啤酒
brands.setText(brandsFormatted);
}
}
这个类继承了android.app.Activity,而且实现了一个onCreate方法。所有活动都必须扩展Activity类或它的一个子类,Activity类包含一组方法,正是这组方案为你的Java类赋予了android生命,把它从一个普通的Java类变成一个完备的真正的Android活动。
另外所有活动都需要实现onCreate方法,创建活动对象时会调用onCreate方法,这个方法用来完成一些基本设置,如这个活动与哪个布局关联。这需要setContentView(R.layout.activity_find_beer)
告诉android这个活动会使用activity_find_beer作为它的布局。
我们之前为按钮增加了一个onClick属性,并指定值为onClickFindBeer。现在要为活动增加这个方法,使得单击按钮能调用这个方法。
如果希望一个方法对按钮单击做出响应,它必须是一个公共方法,要有一个void返回类型,而有一个View参数
R是一个特殊的Java类,利用这个类可以获取应用中资源的引用。
完整的工程文件:https://github.com/dogriffiths/HeadFirstAndroid2ndEdition/tree/master/chapter02/BeerAdviser