课程实践 2: 制作 Court Counter App

这是 Android 开发(入门)课程 的第一部分《布局和交互》的第二次课程实践,导师是 Lyla Fujiwara,主要内容是变量练习和 Court Counter App。

变量练习

这节课通过代码找茬来练习变量的使用,可总结出两种类型的错误:编译期错误和逻辑错误。

编译期错误
Android Studio 能够识别并字体标红,右侧红色方块指示错误位置,在声明和初始化变量时常犯。

声明变量可理解为创建一个新变量,如

int total;

初始化变量则为新变量设定一个初始值,如

total = 10;

通常习惯将声明和初始化变量写在一起,如

int total = 10;

这两项操作有严格的格式规范:

数据类型 变量名 = 初始值;
  1. 数据类型应与系统设定完全相同,如整型 int 不能是 Integer、integer 和 INT,字符串 String 首字母大写。数据类型在 Android Studio 中默认为蓝色。

  2. 数据类型与变量名之间的空格不能省略,也不允许其他任何字符,如 _ 或 - 。

  3. 变量名应遵循命名规则,可 Google 搜索 "variable names java" 找到 Oracle 的说明文档 。通常变量名不能太长也不能短到一两个字母;若是一个单词则全小写;若是多个单词则用小驼峰命名法。变量名不能与数据类型相同,也不能有符号和空格。

  4. 初始值要与数据类型匹配,如字符串的值应在双引号内,不允许出现

     int total = “10”;
    
  5. 分号结束。

逻辑错误
非 XML 或 Java 语法错误,而是代码功能无法实现的错误,所以 Android Studio 无法识别。可关注以下几点:

  1. 运算符优先级,可 Google 搜索 "arithmetic operators java" 找到 Oracle 的说明文档 。例如乘除的优先级比加减的高,逻辑与的比逻辑或的高。若无法确定运算符优先级时用小括号分隔,如

     // 最先做加法,然后乘法,最后减法
     total = 1 * ( 2 + 3 ) - 5; 
    
  2. 变量仅在赋值时改变值,运算不会。

  3. 局部变量在 method 内声明,只在 method 内部有效,在 Android Studio 中为黑色。
    全局变量在 method 外声明,在 method 之间有效,可以保存数据,在 Android Studio 中为紫色。
    若变量不跨 method 使用时用局部变量即可。

  4. 代码按从上到下的顺序运行,先前执行过的代码不会受后面的影响。

Court Counter App

首先构建布局,按步骤进行:分解 Views→画 Views 层级图→写 XML 草稿→代码实现。

  1. 分解 Views。下图为应用最终布局图。
课程实践 2: 制作 Court Counter App_第1张图片

这里用到了嵌套ViewGroups,有两对水平对称的 TextView 和三个 Button,每对垂直排列,通过 vertical 的 LinearLayout 实现;中间有一个 View 呈垂直线条状,三者用 horizontal 的 LinearLayout 能实现;底部居中一个 Button,因此根 Views 应为 RelativeLayout。

  1. 画 Views 层级图,即树状图
课程实践 2: 制作 Court Counter App_第2张图片
  1. 写XML草稿,清晰条理

    
        
            
            
            
            
            
        
        
        
            
            
            
            
            
        
    
    

  1. 代码实现

In activity_main.xml



   

       

           

           

           
  1. 写完代码后可在 activity_main.xml 文件的 Design 标签下的 component Tree 验证嵌套 ViewGroups 层次是否正确。
  2. TextView 中的文字使用了 gravity 属性实现居中对齐,这种方式使得在 LinearLayout 中实现类似 RelativeLayout 中的对齐布局。TextView 的边界较大时效果更明显。
  3. 两个第二层 LinearLayout 使用了 layout_weight 属性实现水平平分宽度,注意此时双方的初始宽度应为 0dp,否则不为零的一方将多占一部分宽度。
  4. 中间的垂直线条可用宽度为 1dp 的 Views 来实现。
  5. 注意内边距 padding 与外边距 margin 的区别。padding 会使 Views 内的内容距离指定位置有间隔,而 margin 会使子 Views 距离父 Views 中的指定位置有间隔,不会改变子 Views。

styles.xml 文件能控制 App 的基本样式,统一修改布局。文件在左侧 Project 标签 Android 视图中 app→res→values 路径下。以下代码将 Court Counter App 的主色调改为橙色。



   
   


最后通过 Button 的 android:onClick 属性连接 XML 与 Java,在 Java 中通过 method 实现功能。

In MainActivity.java

package com.example.android.courtcouter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


   int scoreTeamA = 0, scoreTeamB = 0;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
   }

   /**
    * Increase the score for Team A by 3 points.
    */
   public void addThreeForTeamA(View view) {
       scoreTeamA = scoreTeamA + 3;
       displayForTeamA(scoreTeamA);
   }

   /**
    * Increase the score for Team A by 2 points.
    */
   public void addTwoForTeamA(View view) {
       scoreTeamA = scoreTeamA + 2;
       displayForTeamA(scoreTeamA);
   }

   /**
    * Increase the score for Team A by 1 points.
    */
   public void addOneForTeamA(View view) {
       scoreTeamA = scoreTeamA + 1;
       displayForTeamA(scoreTeamA);
   }

   /**
    * Increase the score for Team B by 3 points.
    */
   public void addThreeForTeamB(View view) {
       scoreTeamB = scoreTeamB + 3;
       displayForTeamB(scoreTeamB);
   }

   /**
    * Increase the score for Team B by 2 points.
    */
   public void addTwoForTeamB(View view) {
       scoreTeamB = scoreTeamB + 2;
       displayForTeamB(scoreTeamB);
   }

   /**
    * Increase the score for Team B by 1 points.
    */
   public void addOneForTeamB(View view) {
       scoreTeamB = scoreTeamB + 1;
       displayForTeamB(scoreTeamB);
   }

   /**
    * Increase the score for Team B by 1 points.
    */
   public void resetScore(View view) {
       scoreTeamA = 0;
       scoreTeamB = 0;
       displayForTeamA(0);
       displayForTeamB(0);
   }

   /**
    * Displays the given score for Team A.
    */
   public void displayForTeamA(int score) {
       TextView scoreView = (TextView) findViewById(R.id.team_a_score);
       scoreView.setText(String.valueOf(score));
   }

   /**
    * Displays the given score for Team B.
    */
   public void displayForTeamB(int score) {
       TextView scoreView = (TextView) findViewById(R.id.team_b_score);
       scoreView.setText(String.valueOf(score));
   }
}
  1. 用全局变量保存两队的总分。
  2. 打开 "Add unambiguous imports on the fly" 功能,在发现未知量时立即添加清晰的 imports,通常导入 Java 的库或包。
  3. 在 Android Studio 中变量名默认为紫色。
  4. 养成写注释的习惯。

课程至此,我做了第二个实战项目——计分器应用。这同样是个简单练习,在 Court Counter App 的基础上稍作修改,达到如下图的效果。

课程实践 2: 制作 Court Counter App_第3张图片

这次项目提交上去由导师审阅后,给出了关于 App 资源文件相关的优化建议,如

  1. 将 sp & dp 等尺寸相关的声明放入 dimens.xml 内,而不是将 Views 的高度和宽度,以及字体的大小硬编码 (hard coding);
  2. 将字符串变量放入了 strings.xml 内,方便应用内多处引用,在翻译应用时也可以大大减少工作量。
  3. 将 color 颜色值放入 colors.xml 内,统一管理颜色资源,而不是对颜色硬编码;
  4. 将样式重复的 TextView、Button、LinearLayout 在 styles.xml 封装调用,使 XML 代码简洁易读。

对 Android App 资源文件的介绍会在以后的课程中出现,在此先有个概念,不多作解释。

你可能感兴趣的:(课程实践 2: 制作 Court Counter App)