Android Studio第2部分:探索和编写应用程序

        在之前Android Studio第1部分介绍中,您在开发环境中设置了Android Studio,并了解了用户界面。现在,在第2部分中,您将编写第一个应用程序的代码。

这个手机应用程序包含一个activity,该activity展示了Google的Android机器人角色以及为该角色设置动画的按钮。单击按钮会使角色逐渐从绿色变为红色,再变为蓝色,然后再变为绿色。尽管该应用不是特别有用,但编写它可以帮助您熟悉使用Android Studio。在第3部分中,您将使用Android设备模拟器和Kindle Fire平板电脑构建并运行该应用程序。

请注意,此系列已针对Android Studio 3.2.1进行了更新。

Android Studio的项目和编辑器窗口

我在第1部分末尾介绍了Android Studio的主窗口。该窗口分为几个区域,其中包括一个Project窗口(用于标识应用程序的资源文件)和各种编辑器窗口(用于编写代码并指定移动应用程序的资源)。在Android Studio中。Project窗口和一个编辑器窗口如图1所示。

图1

图1. Android Studio的Project窗口和一个编辑器窗口

Project窗口突出显示W2A,这是应用程序W2A.java源文件的名称(尽管未显示.java文件扩展名)。与W2A对应的是一个编辑器窗口,可通过在Project窗口中双击W2A来打开。编辑器窗口显示文件的当前内容,在本例中为该应用程序主要activity的Java源代码。

每个编辑器窗口都与一个选项卡关联。例如,W2A的编辑器窗口与W2A.java选项卡相关联。第二个选项卡标识为main.xml(该应用的主要activity默认基于XML的布局)。通过单击窗口的选项卡,可以从一个编辑器窗口移至另一窗口。

下载示例源码

下载Android示例应用程序的源代码:W2A.java

Android示例应用

示例应用程序(W2A.java)包含一个主要activity,该活动显示Android机器人角色和一个按钮。当用户按下按钮时,机器人会通过一系列颜色设置动画。在本节中,我们将探索活动的源代码和资源。

探索并编写Android示例应用程序

activity的源代码存储在下面代码1所示的W2A.java文件中

代码1: W2A.java

package javajeff.example.w2a;

import android.app.Activity;

import android.graphics.drawable.AnimationDrawable;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;
import android.widget.ImageView;

public class W2A extends Activity
{
   AnimationDrawable androidAnimation;

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      ImageView androidImage = (ImageView) findViewById(R.id.android);
      androidImage.setBackgroundResource(R.drawable.android_animate);
      androidAnimation = (AnimationDrawable) androidImage.getBackground();
      final Button btnAnimate = (Button) findViewById(R.id.animate);
      View.OnClickListener ocl;
      ocl = new View.OnClickListener()
      {
         @Override
         public void onClick(View v)
         {
            androidAnimation.stop();
            androidAnimation.start();
         }
      };
      btnAnimate.setOnClickListener(ocl);
   }
}

W2A.java文件以_package语句_开头,该语句命名了W2A类的包名。接下来是针对各种Android API类型的一系列import语句。代码描述了W2A继承的类android.app.Activity

W2A首先声明一个类型为android.graphics.drawable.AnimationDrawableandroidAnimation实例字段。AnimationDrawable对象类型描述了逐帧动画,其中,当前可绘制对象将替换为动画序列中的下一个可绘制对象。

什么是可绘制对象?

可绘制对象是可以绘制的东西,例如图片。AnimationDrawable间接继承了抽象的android.graphics.drawable.Drawable类,该类是可绘制对象的常规抽象。

onCreate()方法

应用程序的所有工作都在W2A的重写onCreate(Bundle)方法中进行:不需要其他方法,这有助于使该应用程序更简洁。

onCreate(Bundle) 首先调用其同名的父类方法,所有重写的activity方法都必须遵循该规则。

然后执行setContentView(R.layout.main)方法以建立应用程序的用户界面。R.layout.main是驻留在单独文件中的应用程序资源的标识符(ID)。下面是ID的详细说明:

  • R是在构建应用程序时生成的类的名称。此类之所以被命名R,是因为其内容标识了各种应用程序资源,包括布局,图像,字符串和颜色。
  • layout是嵌套在R中的类的名称。其ID存储在此类中的应用程序资源描述了特定的布局资源。每种应用程序资源都与类似方式命名的嵌套类相关联。例如,string标识字符串资源。
  • main是在布局内声明的基于int的常量的名称。此资源ID标识主布局资源。具体来说,main是指main.xml存储主要activtiy的布局信息的文件。mainW2A的唯一布局资源。

R.layout.main传递给Activityvoid setContentView (int layoutResID)方法将指示Android使用存储在main.xml中的布局信息创建用户界面屏幕。在后台,Android创建了main.xml中描述的用户界面组件,并将它们放置在设备屏幕上,由main.xml的布局数据所指定。

该屏幕基于视图(用户界面组件的抽象)和视图组(对相关用户界面组件进行分组的视图)。视图是android.view.View类的子类的类的实例,类似于AWT / Swing组件。视图组是抽象类android.view.ViewGroup的子类的类的实例,类似于AWT / Swing容器。Android将特定的视图(例如按钮或微调器)称为小部件。

继续,onCreate(Bundle)执行ImageView androidImage =(ImageView)findViewById(R.id.android)。 该语句首先调用ViewView findViewById(int id)方法来查找在main.xml中声明并标识为android的android.widget.ImageView元素。 它实例化ImageView并将其初始化为main.xml文件中声明的值。 然后,该语句将该对象的引用保存在局部变量androidImage中。

ImageView和AnimationDrawable

接下来,该androidImage.setBackgroundResource(R.drawable.android_animate)语句调用ImageView的Inherited(from View)void setBackgroundResource(int resID)方法,将视图的背景设置为标识的资源resID。该R.drawable.android_animate参数标识一个名为android_animate.xml(稍后介绍)的XML文件,该文件存储有关动画的信息,并存储在resdrawable子目录中。该setBackgroundResource()调用将androidImage视图链接到所描述的图像序列,这些图像android_animate.xml将绘制在该视图上。此方法调用的结果是绘制了初始图像。

ImageView允许应用通过调用AnimationDrawable方法为一系列可绘制对象设置动画。在应用执行此操作之前,必须先获取ImageViewAnimationDrawable。接下来的androidAnimation = (AnimationDrawable) androidImage.getBackground()赋值语句通过调用ImageView的Inherited(from View)Drawable getBackground()方法来完成此任务。此方法返回AnimationDrawable给定的ImageView,随后将其分配给该androidAnimation字段。该AnimationDrawable实例用于启动和停止动画,我将在稍后描述该过程。

最后,onCreate(Bundle)创建动画按钮。它调用findByViewId(int)从中获取按钮信息main.xml,然后实例化android.widget.Button该类。

然后,它使用View类的嵌套onClickListener接口创建侦听器对象。void onClick(View v)每当用户单击按钮时,都会调用该对象的方法。侦听器Button通过调用Viewvoid setOnClickListener(AdapterView.OnClickListener listener)方法向其对象注册。

停止动画时,Animate的Click侦听器将调用,androidAnimation.stop();启动动画时调用androidAnimation.start();stop()start()确保后续单击动画按钮会导致在开始新动画之前,调用此方法。

更新并保存您的代码

在继续之前,用代码1中的代码替换W2A.java选项卡中的代码。按Ctrl + S 保存此窗口的内容,或者从File菜单中选择Save All

编码Android应用程序的main.xml

该应用程序的主要活动与基于XML的布局相关联,该布局存储在文件main.xml中,如代码2所示。

代码2:main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:gravity="center"
              android:background="#ffffff">
   <ImageView android:id="@+id/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginBottom="10dip"/>
   <Button android:id="@+id/animate"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/animate"/>
</LinearLayout>

在XML声明之后,代码2声明了一个LinearLayout元素,该元素指定一个布局(一个视图组以某种方式在Android设备的屏幕上排列所包含的视图),用于在屏幕上水平或垂直地排列所包含的小部件(包括嵌套的布局)。

<LinearLayout>标签指定用于控制这种线性布局几个属性。这些属性包括:

  • orientation将线性布局标识为水平或垂直。包含的小部件水平或垂直放置,默认方向为水平。"horizontal"并且"vertical"是可以分配给该属性的唯一合法值。
  • layout_width标识布局的宽度。合法值包括"fill_parent"(与父级一样宽)和"wrap_content"(足够宽以包含内容)。(请注意,该名称fill_parent已在Android 2.2中重命名为match_parent,但仍受支持并广泛使用。)
  • layout_height标识布局的高度。合法值包括"fill_parent"(与父级一样高)和"wrap_content"(足够高以包含内容)。
  • gravity标识布局相对于屏幕的放置方式。例如,"center"指定布局应在屏幕上水平和垂直居中。
  • background标识背景图像,渐变或纯色。为简单起见,我对十六进制颜色标识符进行了硬编码,以表示纯白色背景(#ffffff)。(颜色通常会存储在colors.xml文件中并从该文件中引用。)

LinearLayout元素封装了ImageViewButton元素。这些元素中的每一个都指定一个id属性,该属性标识该元素,以便可以从代码中引用它。分配给该属性的资源标识符(以@开头的特殊语法)以@+id前缀开头。 例如,@+id/androidImageView元素标识为android; 通过指定R.id.android从代码中引用此元素。

这些元素还指定layout_widthlayout_height属性,以确定其内容的布局方式。每个属性都分配了wrap_content,以便该元素以其自然大小显示。

ImageView指定layout_marginBottom属性,以标识其自身与垂直跟随的按钮之间的空格。该空间指定为10个倾角或与密度无关的像素。这些是虚拟像素,应用程序可使用这些虚拟像素以与屏幕密度无关的方式表示布局尺寸/位置。

密度无关像素

与密度无关的像素(dip)等效于160 dpi屏幕上的一个物理像素,基线密度由Android假定。在运行时,Android会根据使用中的屏幕的实际密度透明地处理所需的下垂单位的任何缩放比例。通过以下公式将独立像素单位转换为屏幕像素:像素=屏幕独立像素值*(屏幕密度/ 160)。例如,在240 dpi屏幕上,1度独立像素值等于1.5个物理像素。Google建议使用独立像素单位来定义应用程序的用户界面,以确保在不同设备屏幕上正确显示用户界面。

选择并保存新布局

您可能还记得,在第1部分中设置应用程序时,我们选择了空的活动模板。事实证明,此模板提供的XML布局不适合我们的应用程序。要选择新的布局,请先单击main.xml选项卡。Android Studio会显示一个用户友好的布局编辑界面:

图2

图2. Android Studio的布局编辑器

在继续之前,请单击main.xml选项卡底部的文本选项卡(默认显示设计选项卡)。用代码2中的代码替换模板XML,然后保存该窗口的内容。

编码Android应用程序的strings.xml

W2A依靠strings.xml来存储从其他位置引用的字符串数据。 返回代码2,您会注意到标记包含android:text = “@ string/animate” 属性。 该属性通过@string/animate引用按钮的文本,该字符串引用存储在strings.xml中的名为animate的字符串资源。 代码3展示了该文件的内容。

代码3:strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">W2A</string>
   <string name="animate">Animate</string>
</resources>

以及animate,代码3还显示了标识为app_name的字符串资源。 此资源ID标识应用程序的名称,并从应用程序的AndroidManifest.xml文件(通常是从应用程序元素开始标签的label属性)引用。

国际化移动应用

将字符串直接存储在strings.xml其他地方并从其他地方引用这些资源是一个好习惯,而不是在源文件和其他资源文件中对字符串进行硬编码。遵循这种做法可以使应用更容易适应其他国际市场,从而有可能增加您的创收潜力。

保存strings.xml

在Project窗口中,res子分支的values子分支包括一个strings.xml子分支。双击该子分支以显示strings.xml选项卡,然后将其内容替换为代码3并保存更改。

编码Android应用的animate.xml

最后,W2A依赖于android_animate.xml,它存储可绘制项目的动画列表。代码4展示了该文件的内容。

代码4。 android_animate.xml

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                android:oneshot="true">
   <item android:drawable="@drawable/android0" android:duration="500" />
   <item android:drawable="@drawable/android1" android:duration="500" />
   <item android:drawable="@drawable/android2" android:duration="500" />
   <item android:drawable="@drawable/android0" android:duration="500" />
</animation-list>

代码4从animation-list描述可绘制序列的元素开始。此元素的oneshot属性确定动画是循环循环(分配时"false")还是仅执行一次(分配时"true")。将"true"分配给时oneshot,必须先调用AnimationDrawable()stop()方法,然后再使用其start()方法来生成另一个oneshot动画序列。

嵌套在animation-list元素内部的是一系列item元素。 每个item元素通过其drawable属性在动画序列中标识一个可绘制对象。 @drawable/androidx资源参考(其中x的范围是0到2)标识了一个以android开头的图像文件。 duration属性标识显示下一个项目元素的可绘制对象之前必须经过的毫秒数。

保存animate.xml

在Project窗口中,右键单击res子分支的drawable子分支。图3显示了出现的弹出菜单。

[图3

图3.添加android_animate.xml作为新的可绘制资源

从弹出菜单中选择“ 新建 ”,然后选择**“** 文件”。图4显示了出现的**“选择目标目录”**对话框。

图4

图4.在drawable和drawable-v24之间选择

经典的可绘制资源(例如图像)存储在drawable文件夹中。相反,矢量可绘制对象存储在中drawable-v24。对于此项目,保留可绘制默认值,然后单击确定。现在,您应该看到“ **新建文件”**对话框。

图5

图5.输入android_animate.xml

键入android_animate.xml输入新的文件名的文本字段,然后单击确定。(您将在drawable子分支下看到一个android_animate.xml子分支。)然后,用代码4(上面)中的代码替换生成的android_animate.xml选项卡的内容,并保存更改。

您还需要复制android0.pngandroid1.pngandroid2.png文件从这篇文章到相关的源代码(代码4中引用)绘制的分支。假设您使用Windows工作,请从Windows资源管理器中选择这些文件并将其粘贴到android_animate.xml分支中(右键单击分支名称,然后选择粘贴)。

第2部分的结论

在第2部分中,您首先看了Android Studio的Project和Editor窗口。您已经探究了Android应用程序的一般体系结构,并编写了一个简单的动画Android移动应用程序。准备好构建并运行动画的Android应用程序时,请转到第3部分。

猜你喜欢

转载自blog.csdn.net/zenglintao/article/details/106270969