课程实践 2: 制作 Court Counter App

编程入门 行业动态 更新时间:2024-10-25 00:32:44

<a href=https://www.elefans.com/category/jswz/34/1770049.html style=课程实践 2: 制作 Court Counter App"/>

课程实践 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。下图为应用最终布局图。

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

  1. 画 Views 层级图,即树状图

  1. 写XML草稿,清晰条理
<RelativeLayout...><LinearLayout...><LinearLayout...><TextView... /><TextView... /><Button.../><Button.../><Button.../></LinearLayout><View... /><LinearLayout...><TextView... /><TextView... /><Button... /><Button... /><Button.../></LinearLayout></LinearLayout><Button... />
</RelativeLayout>
复制代码
  1. 代码实现

In activity_main.xml

<RelativeLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"tools:context="com.example.android.courtcouter.MainActivity"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:fontFamily="sans-serif-medium"android:gravity="center_horizontal"android:padding="16dp"android:text="Team A"android:textColor="#616161"android:textSize="14sp" /><TextViewandroid:id="@+id/team_a_score"android:layout_width="match_parent"android:layout_height="wrap_content"android:fontFamily="sans-serif-light"android:gravity="center_horizontal"android:paddingBottom="24dp"android:text="0"android:textColor="#000000"android:textSize="56sp" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addThreeForTeamA"android:text="+3 Points" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addTwoForTeamA"android:text="+2 Points" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addOneForTeamA"android:text="Free Throw" /></LinearLayout><Viewandroid:layout_width="1dp"android:layout_height="match_parent"android:layout_marginTop="16dp"android:background="@android:color/darker_gray" /><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:fontFamily="sans-serif-medium"android:gravity="center_horizontal"android:padding="16dp"android:text="Team B"android:textColor="#616161"android:textSize="14sp" /><TextViewandroid:id="@+id/team_b_score"android:layout_width="match_parent"android:layout_height="wrap_content"android:fontFamily="sans-serif-light"android:gravity="center_horizontal"android:paddingBottom="24dp"android:text="0"android:textColor="#000000"android:textSize="56sp" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addThreeForTeamB"android:text="+3 Points" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addTwoForTeamB"android:text="+2 Points" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:layout_marginLeft="24dp"android:layout_marginRight="24dp"android:onClick="addOneForTeamB"android:text="Free Throw" /></LinearLayout></LinearLayout><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="8dp"android:layout_marginLeft="22dp"android:layout_marginRight="22dp"android:onClick="resetScore"android:text="reset" />
</RelativeLayout>
复制代码
  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 的主色调改为橙色。

<resources><!-- Base application theme. --><style name="AppTheme" parent="Theme.AppCompat.Light"><!-- Customize your theme here. --><item name="colorPrimary">#FF9800</item><item name="android:colorButtonNormal">#FF9800</item></style></resources>
复制代码

最后通过 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;@Overrideprotected 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 的基础上稍作修改,达到如下图的效果。

这次项目提交上去由导师审阅后,给出了关于 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

本文发布于:2024-02-25 09:20:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1698505.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:课程   Court   App   Counter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!