接下来就是项目的配置,保持默认的设置点击next。
至此,一个简单的Android app项目创建完毕。
如果开发者完全遵循了使用eclipse IDE创建项目。其包含了一组默认的“Hello World”资源文件,开发者能够在app中立即运行。
开发者可选择在实际的安卓设备中运行app,也可在eclipse中运行。在运行app之前,安卓开发者应该清楚了解安卓项目中的一些文件夹以及文件。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> ... </manifest>
当运行新创建的安卓app是,默认的Activity类执行和layout加载。
无论开发在在eclipse中或者命令行中运行app。首先需要的是创建一个Android Virtual Device。这个AVD运行开发者模拟显示中不同的安卓设备。创建AVD步骤如下:
在eclipse中运行app
Eclipse将会在AVD中实例化项目。
以上就是创建第一个Android app和在模拟设备上运行app的全部内容,翻译自http://developer.android.com/training/basics/firstapp/running-app.htmlhttp://,高手请忽略,接下来是该系列更加精彩的分享。
Android app的图形用户界面使用View和ViewGroup对象创建。View对象一般为UI窗体小部件,例如button、text file;ViewGroup对象为不可见的视图容器,该容器定义了子视图的布局,如网格或者垂直不觉。
对应的View和ViewGroup子类在xml语言中描述。开发者通过在xml中使用UI的层次结构定义app的UI。
Note:一般情况下,app 的UI在XML文件中定义而不是在运行时代码中定义runtime time。这种方式有很多的优点,但最主要的一点就是开发者可以根据不一样的屏幕设备定义相对应的布局。比如创建了两个版本的布局文件,一个在小屏幕设备中使用,另外一个在大屏幕中使用。
在这一部分中,将描述在xml文件中如何text filed和button,下一节将教会读者:点击按钮时,发送text filed中的内容往另外一个activity中。
打开res/layout目录下的activity_main.xml文件。
Note:在eclipse中,当开发者打开布局文件时,首先看到的是图形布局编辑器。这是一个使用了“所见即所得”的工具帮助开发者创建布局的编辑器。然而,这篇文章中都是直接通过xml文件进行设计activity布局。所以,点击activity_main.xml标签进行xml编辑。
在我们开始创建app时,BlankActivity模板已经自动创建了activity_main.xml并且该xml文件中已经生成一个RelativeLayout根视图和TextView子视图。
首先,删除<TextView>元素,把<RelativeLayout>元素改为<LinearLayout>.然后添加一个android:orientation属性,并把该属性值设置为“horizontal”。
<?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:orientation="horizontal" > </LinearLayout>LinearLayout是一个视图组(ViewGroup的子类),通过 android:orientation属性,视图组里面的子视图可以设置为水平或者垂直布局。xml文件中子视图的编写排放的顺序为Android app运行该activity时显示的效果一致。android:layout_width和android:layout_height属性需设置其指定值以便设置其该linearLayout的大小。
在<LinearLayout>中添加一个<EditText>元素,创建一个用户可编辑的文本框。与其他视图对象一样,必须在XML属性中定义EditText对象的属性。所以在<LinearLayout>元素内部写入代码:
<EditText android:id="@+id/edit_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/edit_message" />
上述代码中属性的解释:
android:idNote关于资源对象:一个资源对象是与一个app 资源关联的整型数字,例如bitmap、layout文件或者string。没一个资源都在项目中的gen/R.java文件中定义。开发者可以使用R类中的对象名称引用项目中的资源,例如要为android:hint属性中指定一个string值。同样可以创建一个任意的资源ID,这个资源ID与使用了android:id属性的视图Vierw相关联,以此种方式开发者能在其他代码中引用该视图。更加需要注意的是:R.java文件是在编译app时SDK工具自动生成的。请不要手动更改R.java文件。
android:layout_width和android:layout_height
"warp_content"值设定了视图的大小为视图内容所需要的大小,而不是设定某个为视图某个指定大小。如果不使用match_parent,代码中的ExitText元素将会占满整个设备的屏幕空间,出现这样的结果原因是ExitText的默认大小为其父控件的大小(这段代码中其父控件为LinearLayout)
android:hint
当文本框为空,默认的为android:hint元素中string设置的字符串。“@string/exit_message”值通过引用在另外一个独立的文件(这个独立文件是valves文件目录下的string.xml文件)中string资源代替了硬编码的方式设置string值。因为引用了具体的资源(不是一个标示符,请参考android:id的解释),所以没必要编写一个“+”符号。然而,由于现在还没定义ExitText的string资源,所以编辑器中将会报错,不要担心,下一节的内容会知道读者定义一个string资源。
Note:细心的读者会注意到这段代码中的android:id="@+id/edit_message" 与string资源的android:hint="@string/edit_message"/>都有edit_message一样的名字,然而app在引用资源时能够根据不同的资源类型进行区分(例如id或者string类型)。所以不会因为名字相同而冲突。
在用户界面中添加文本时,开发者应把每一个string定义为一个资源。string资源允许开发者在一个独立的文件中管理用户界面的文本,能够很方便地查找和更新文本。同时通过为string资源创建不同地区语言的string.xml,能够本地化app。
默认Android项目在res/values/string.xml包含了res/values/string.xml文件。在此文件中添加一个命名为exit_message的字符串、值为Enter a message(此时可以删除“hello world”字符串)
同样地在string.xml文件中为接下来的按钮部分添加字符串,名称为“button_send”。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">My First App</string> <string name="edit_message">Enter a message</string> <string name="button_send">Send</string> <string name="action_settings">Settings</string> <string name="title_activity_main">MainActivity</string> </resources>
接下来在布局文件中添加一个<Button>,定义的这个按钮代码放置在<ExitText>元素后面。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" />height和width的值都设置为“wrap_content”,这样子button的外形大小为button中文本名称的长度大小一致。这个button不需要"android:id"属性,因为该按钮在 activity的代码中没被引用。
至今为止,上面的布局代码中设计的ExitText和Button组件仅仅是与其内容的大小一致。如下图所示:
这样的设计在按钮组件中能起到很好的视觉效果,但在文本框中非也。因为用户可能输入更长的文本。所以,把文本框填满整个屏幕剩余的宽度是个不错的设计。在LinearLayout中通过weight属性同样能利用填满剩余屏幕宽度的界面效果。
weight的值是一个数字,这个数字指定了该视图相对于相邻视图所剩余的屏幕空间宽度大小。这就像一份溶液中,水占2分,溶质占1份,意味着溶占了整个溶液的三分之一。以此比喻能映射到这里。我们来举一个例子解释:在一个屏幕中设计水平排放的两个组件,如果把前一个组件的weight值设置为2,后一个组件的weight值设置为1,那么总和为3;所以前者占据整个屏幕宽度的三分之二,后者为剩余的屏幕宽度;如果再添加第三个组件并设置其weight值为1,那么该三个组件占据整个屏幕宽度的比例为2:1:1。
layout_weight的默认值为0,所以当且只有一个视图组件的weight值设置大于1,这个视图组件将把其他组件占据的屏幕宽度剩余的部分填满。可以把这个activity中的ExitText元素填满屏幕的宽度,设置exitText的weight值为1,button没有weight值。
<EditText android:layout_weight="1" ... />
当开发者指定了一个weight值大于0之后,为了增强设计的效果,应把ExitText的width值设置为0px。改变ExitText的weight和width值之后,效果图如下:
至今为止,整个布局文件的全部代码如下:
<?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:orientation="horizontal"> <EditText android:id="@+id/edit_message" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="@string/edit_message" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" /> </LinearLayout>这个布局文件应用于创建项目时SDK工具自动生成的默认Activity类。完成上述内容的操作之后,我们现在可以运行该项目:
按照上述的内容完成操作之后,我们已经创建了一个拥有一个activity的app。这个activity包含了一个文本框和一个按钮。在这一部分内容要求在MainActivity中添加一些代码。当用户点击发送按钮时,启动一个新的activity。
在activity_main.xml布局文件中为<Button>元素添加android:onClick属性。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" android:onClick="sendMessage" />android:onClick属性的value值为“sendMessage”,为activity类中的方法名。当用户点击按钮时,将调用该方法。打开位于src目录下的MainActivity类,添加与android:onClick相对应的方法。
/** Called when the user clicks the Send button */ public void sendMessage(View view) { // Do something in response to button }在sendMessage方法中含有View参数,所以需要在MainActivity中包含:
import android.view.View;小技巧:在Eclipse编辑器中,按住ctrl+Shift+o(字母o) 时自动为开发者把遗漏的类包含进去。
接下来,通过读取文本中的内容以及把文本传送到另外一个activity。
一个Intent是一个在app运行时把两个独立的组件(例如两个activity)绑定在一起。Intent表明了app的“意图”即将要做什么。开发者可以利用intent进行各种各样的任务,但Intent主要被用于启动另外一个activity。
在sendMessage方法创建一个Intent,启动DisplayMessageActivity activity。
Intent intent = new Intent(this, DisplayMessageActivity.class);Intent的构造函数中使用了两个参数:
note:因为还没有DisplayActivity,现在代码中调用DisplayActivity报错误,我们稍后将创建DisplayActivity类,此时请忽略该错误。
一个intent不仅允许启动另外一个activity,同时其能够向目的activity中传递数据。在sendMessage方法中,findViewByID获取EditText元素、把EditText的文本内容添加到intent中。
Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message);
一个Intent中有各种数据类型的容器,作为extras的一个键值对。在putExtra()方法中,第一个参数为名称,第二个参数为值。为了让即将启动的activity查询extra数据,应使用public常量为intent的extra定义键(key)。所以本项目中,在MainActivity类的顶部定义一个EXTRA_MESSAGE
public class MainActivity extends Activity { public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; ... }将包名作为intent extra的值的前缀确保了该值与其他app的intent extra的值。
调用startActivity方法并把intent作为参数即可启动一个activity。系统接收到这个调用之后,启动了intent指定的一个activity的一个实例。senMessage方法的全部代码如下:
/** Called when the user clicks the Send button */ public void sendMessage(View view) { Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); startActivity(intent); }接下来的内容就是创建一个DisplayMessageActivity类
使用Eclipse创建一个新的activity步骤如下:
完成上述四个步骤之后,打开DisplayMessageActivity.java。
由于ActionBar APIs在HONEYCOMB(api 11)的更高版本,开发者必须在getActionBar()方法添加一个判断条件去检查当前设备上系统上的API版本。另外,还需要在onCreate()方法中添加@SupportLint标签避免lint报错。
public class DisplayMessageActivity extends Activity { @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); // Make sure we're running on Honeycomb or higher to use ActionBar APIs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Show the Up button in the action bar. getActionBar().setDisplayHomeAsUpEnabled(true); } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); } }Activity的子类必须重载onCreate()方法。当创建一个activity实例时系统会调用该方法。在onCreate方法里面必须使用setContextView()方法定义activity的布局。并且在onCreate()方法中执行初始化activity组件的设置。 需要引起读者注意的是,Eclipse在创建DisplayMessageActvity.java时已经自动生成了setContextView()需要的activity_display_message.xml布局文件
如果读者使用的时Eclipse,可以跳过这一部分。因为eclipse已经在string.xml文件中为新的activity自动生成了title string。
<resources> ... <string name="title_activity_display_message">My Message</string> </resources>
所有的activity必须在项目的manifest中声明,AndroidManifest.xml,使用了<activity>元素
当开发者使用的是Eclipse创建一个activity,已经自动在AndroidManifrst.xml文件中生成默认值。如果使用的是其他IDE,那么必须在AndroidManifest.xml文件中添加:
<application ... > ... <activity android:name="com.example.myfirstapp.DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity> </application>
所有的activity都是通过Intent被调用,通过调用getIntent()方法启动activity从而获取Intent,在Intent中还可以取回里面包含的数据。在DisplayMessage类中德onCreate()方法,取回从MainActivity传过来的intent和额外的数据信息。
Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
创建一个TextView窗体(textView)在屏幕中显示从MainActivity传过来的文本信息,并使用setText()方法设置文本(message)。然后把textView作为setContextView()方法的参数。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get the message from the intent Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); // Create the text view TextView textView = new TextView(this); textView.setTextSize(40); textView.setText(message); // Set the text view as the activity layout setContentView(textView); }至此,可以运行app了。打开这个app,在文本框中输入信息,点击Send按钮,最后信息出现在第二个activity中。