联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> Java编程Java编程

日期:2025-05-09 11:04

Your First Android Application in Android Studio


Figure 1 – Your Android Application in Android Studio


The application you are going to create is called GeoQuiz. GeoQuiz tests the user’s knowledge of geography. The user presses TRUE or FALSE to answer the question onscreen, and GeoQuiz provides instant feedback.



Figure 2 – The result task


Figure 2 shows the result of a user pressing the TRUE button.

Step 1 App Basics


Your GeoQuiz application will consist of an activity and a layout:

An activity is an instance of Activity, a class in the Android SDK. An activity is responsible for managing user interaction with a screen of information.

You write subclasses of Activity to implement the functionality that your app requires. A simple application may need only one subclass; a complex application can have many.

GeoQuiz is a simple app and will start off with a single Activity subclass named MainActivity. MainActivity will manage the user interface, or UI, shown in Figure 3.

A layout defines a set of UI objects and the objects’ positions on the screen. A layout is made up of definitions written in XML. Each definition is used to create an object that appears onscreen, like a button or some text.

GeoQuiz will include a layout file named activity_main.xml. The XML in this file will define the UI shown in Figure 3.

The relationship between MainActivity and activity_main.xml is diagrammed in Figure 3.



Figure 3 – MainActivity manages what activity_main.xml defines


Figure 4 – Preferences for New Projects (File → Settings)


Back at the Welcome dialog, choose Start a new Android Studio project. If you do not see the dialog, choose File → New → New Project....

Welcome to the Create New Project wizard (Figure 5). Make sure the Phone and Tablet tab is selected, pick Empty Activity, and click Next.



Figure 5 – Choosing a project template

You should now see the Configure your project screen (Figure 6). Enter GeoQuiz as the application name. For package name, enter com.example.geoquiz. For the project location, use any location on your filesystem that you want.

Select Kotlin from the Language drop-down menu. Select a Minimum API level of API 24: Android 7.0. Last, make sure the checkbox next to Use AndroidX artifacts is checked. Your screen should look like Figure 6.



Figure 6 – Configuring your new project


Selecting Kotlin as the language tells Android Studio to include the dependencies, such as Kotlin build tools, necessary to write and build Kotlin code for your app.

Java was the only development language officially supported until May 2017, when the Android team announced official support for Kotlin for Android development at Google I/O. These days, Kotlin is preferred by most developers, ourselves included, which is why this lab uses Kotlin. But if you choose to use Java in your projects outside of this lab, the Android concepts and content you will learn here will still be applicable.

(Android Studio updates regularly, so your wizard may look slightly different from what we are showing you. This is usually not a problem; the choices should be similar. If your wizard looks very different, then the tools have changed more drastically. Do not panic.)

Click Finish. Android Studio will create and open your new project.


Step 2 Navigating in Android Studio


Android Studio opens your project in a window like the one shown in Figure 7. If you have launched Android Studio before, your window configuration might look a little different.



Figure 7 – A fresh project window


The different panes of the project window are called tool windows.

The lefthand view is the project tool window. From here, you can view and manage the files associated with your project.

The view across the bottom is the build tool window. Here you can view details about the compilation process and the status of the build. When you created the project, Android Studio automatically built it. You should see in the build tool window that the process completed successfully.

In the project tool window, click the disclosure arrow next to app. Android Studio automatically opens the files activity_main.xml and MainActivity.kt in the main view, called the editor tool window or just the editor (Figure 8). If this is not your first time opening Android Studio, the editor tool window may have opened automatically when you created the project.



Figure 8 – Editor engaged


Notice the Activity suffix on the class name. This is not required, but it is an excellent convention to follow.

You can toggle the visibility of the various tool windows by clicking on their names in the strips of tool buttons on the left, right, and bottom of the screen. There are keyboard shortcuts for many of these as well. If you do not see the tool button strips, click the gray square button in the lower-left corner of the main window or choose View → Tool Buttons.


Step 3 Laying Out the UI


Click the tab for the layout file, activity_main.xml.

This will open the layout editor in the editor tool window (Figure 9).

If you do not see a tab for activity_main.xml, do not worry. Expand app/res/layout/ in the project tool window. Double-click activity_main.xml to open the file. If activity_main.xml opens but shows XML instead of the layout editor, click the Design tab at the bottom of the editor tool window.



Figure 9 – Layout editor


By convention, a layout file is named based on the activity it is associated with: Its name begins with activity_, and the rest of the activity name follows in all lowercase, using underscores to separate words (a style called “snake_case”). So, for example, your layout file’s name is activity_main.xml, and the layout file for an activity called SplashScreenActivity would be named activity_splash_screen. This naming style is recommended for layouts as well as other resources that you will learn about later.

The layout editor shows a graphical preview of the file. Select the Text tab at the bottom to see the backing XML.

Currently, activity_main.xml holds the default activity layout template. The template changes frequently, but the XML will look something like Listing


Listing 1 Default activity layout (res/layout/activity_main.xml)


<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout

   xmlns:android="http://schemas.android.com/apk/res/android"

   xmlns:app="http://schemas.android.com/apk/res-auto"

   xmlns:tools="http://schemas.android.com/tools"

   android:id="@+id/main"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   tools:context=".MainActivity">


   <TextView

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="Hello World!"

       app:layout_constraintBottom_toBottomOf="parent"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>


The default activity layout defines two Views: a ConstraintLayout and a TextView.

Views are the building blocks you use to compose a UI. Everything you see on the screen is a view. Views that the user can see or interact with are called widgets. Some widgets show text. Some widgets show graphics. Others, like buttons, do things when touched.

The Android SDK includes many widgets that you can configure to get the appearance and behavior you want. Every widget is an instance of the View class or one of its subclasses (such as TextView or Button).

Something has to tell the widgets where they belong onscreen. A ViewGroup is a kind of View that contains and arranges other views. A ViewGroup does not display content itself. Rather, it orchestrates where other views’ content is displayed. ViewGroups are often referred to as layouts.

In the default activity layout, ConstraintLayout is the ViewGroup responsible for laying out its sole child, a TextView widget. You will learn more about layouts and widgets and about using ConstraintLayout soon.

Figure 10 shows how the ConstraintLayout and TextView defined in Listing 1 would appear onscreen.



Figure 10 – Default views as seen onscreen


But these are not the widgets you are looking for. The interface for MainActivity requires five widgets:

a vertical LinearLayout

a TextView

a horizontal LinearLayout

two Buttons

Figure 11 shows how these widgets compose MainActivity’s interface.



Figure 11 – Planned widgets as seen onscreen


Now you need to define these widgets in your layout XML. Edit the text contents of activity_main.xml to match Listing 2. The XML that you need to delete is struck through, and the XML that you need to add is in bold font. This is the pattern we will use throughout this book.

Do not worry about understanding what you are typing; you will learn how it works next. However, do be careful. Layout XML is not validated, and typos will cause problems sooner or later.

You will see errors on the three lines that start with android:text. Ignore these errors for now; you will fix them soon.


Listing 2 Defining widgets in XML (res/layout/activity_main.xml)


<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout

….

</androidx.constraintlayout.widget.ConstraintLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   android:id="@+id/main"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:gravity="center"

   android:orientation="vertical">


   <TextView

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:padding="24dp"

       android:text="@string/question_text" />


   <LinearLayout

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal">


       <Button

           style="?android:attr/buttonStyle"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/true_button" />


       <Button

           style="?android:attr/buttonStyle"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/false_button" />

   </LinearLayout>

</LinearLayout>



Compare your XML with the UI shown in Figure 11. Every widget has a corresponding XML element, and the name of the element is the type of the widget.

Each element has a set of XML attributes. Each attribute is an instruction about how the widget should be configured.

To understand how the elements and attributes work, it helps to look at the layout from a hierarchical perspective.



Step 4 The view hierarchy


Your widgets exist in a hierarchy of View objects called the view hierarchy. Figure 12 shows the view hierarchy that corresponds to the XML in Listing 2.



Figure 12 – Hierarchical layout of widgets and attributes


The root element of this layout’s view hierarchy is a LinearLayout. As the root element, the LinearLayout must specify the Android resource XML namespace.

LinearLayout inherits from ViewGroup, which, as we said earlier, is a subclass of View that contains and arranges other views. You use a LinearLayout when you want views arranged in a single column or row. Other ViewGroup subclasses that you will meet later include ConstraintLayout and FrameLayout.

When a view is contained by a ViewGroup, that view is said to be a child of the ViewGroup. The root LinearLayout has two children: a TextView and another LinearLayout. The child LinearLayout has two Button children of its own.


Step 5 Widget attributes

Let’s go over some of the attributes that you have used to configure your widgets.

android:layout_width and android:layout_height


The android:layout_width and android:layout_height attributes are required for almost every type of widget. They are typically set to either match_parent or wrap_content:

match_parentview will be as big as its parent

wrap_contentview will be as big as its contents require

For the root LinearLayout, the value of both the height and width attributes is match_parent. The LinearLayout is the root element, but it still has a parent – the view that Android provides for your app’s view hierarchy to live in.

The other widgets in your layout have their widths and heights set to wrap_content. You can see in Figure 11 how this determines their sizes.

The TextView is slightly larger than the text it contains due to its android:padding="24dp" attribute. This attribute tells the widget to add the specified amount of space to its contents when determining its size. You are using it to get a little breathing room between the question and the buttons.


android:orientation

The android:orientation attribute on the two LinearLayout widgets determines whether their children will appear vertically or horizontally. The root LinearLayout is vertical; its child LinearLayout is horizontal.

The order in which children are defined determines the order in which they appear onscreen. In a vertical LinearLayout, the first child defined will appear topmost. In a horizontal LinearLayout, the first child defined will be leftmost. (Unless the device is set to a language that runs right to left, such as Arabic or Hebrew. In that case, the first child will be rightmost.)


android:text

The TextView and Button widgets have android:text attributes. This attribute tells the widget what text to display.

Notice that the values of these attributes are not literal strings. They are references to string resources, as denoted by the @string/ syntax.

A string resource is a string that lives in a separate XML file called a strings file. You can give a widget a hardcoded string, like android:text="True", but it is usually not a good idea. Placing strings into a separate file and then referencing them is better because it makes localization easy.

The string resources you are referencing in activity_main.xml do not exist yet. Let’s fix that.


Step 6 Creating string resources

Every project includes a default strings file named res/values/strings.xml.

Open res/values/strings.xml. The template has already added one string resource for you. Add the three new strings that your layout requires.



Listing 3 Adding string resources (res/values/strings.xml)

<resources>

<string name="app_name">GeoQuiz</string>

<string name="question_text">Canberra is the capital of Australia.</string>

<string name="true_button">True</string>

<string name="false_button">False</string>

</resources>


(Depending on your version of Android Studio, you may have additional strings. Do not delete them. Deleting them could cause cascading errors in other files.)

Now, whenever you refer to @string/false_button in any XML file in the GeoQuiz project, you will get the literal string “False” at runtime.

The errors in activity_main.xml about the missing string resources should now be gone. (If you still have errors, check both files for typos.)

Although the default strings file is named strings.xml, you can name a strings file anything you want. You can also have multiple strings files in a project. As long as the file is located in res/values/, has a resources root element, and contains child string elements, your strings will be found and used.

Step 7 Previewing the layout


Your layout is now complete. Switch back to activity_main.xml and preview the layout in the Design pane by clicking the tab at the bottom of the editor tool window (Figure 13).



Figure 13 – Previewing activity_main.xml in the Design pane


Figure 13 shows the two kinds of preview available. You can select from the preview types using a menu that drops down from the blue diamond button leftmost in the top toolbar. You can show either kind of preview individually or both together, as shown here.

The preview on the left is the Design preview. This shows how the layout would look on a device, including theming.

The preview on the right is the Blueprint preview. This preview focuses on the size of widgets and the relationships between them.

The Design pane also allows you to see how your layout looks on different device configurations. At the top of the pane, you can specify the type of device, the version of Android to simulate, the device theme, and the locale to use when rendering your layout. You can even pretend your current locale uses right-to-left text.

In addition to previewing, you can also build your layouts using the layout editor. On the left there is a palette that contains all of the built-in widgets (Figure 14). You can drag these widgets from the palette and drop them into your view. You can also drop them into the component tree in the bottom left to have more control over where the widget is placed.

Figure 14 shows the preview with layout decorations – the device status bar, app bar with GeoQuiz label, and virtual device button bar. To see these decorations, click the eyeball button in the toolbar just above the preview and select Show Layout Decorations.



Figure 14 – Graphical layout editor


You will find this graphical editor especially valuable when working with ConstraintLayout.


Step 8 From Layout XML to View Objects

How do XML elements in activity_main.xml become View objects? The answer starts in the

MainActivity class.

When you created the GeoQuiz project, a subclass of Activity named MainActivity was created for you. The class file for MainActivity is in the app/java directory of your project.

A quick aside about the directory name before we get into how layouts become views: This directory is called java because Android originally supported only Java code. In your project, because you configured it to use Kotlin (and Kotlin is fully interoperable with Java), the java directory is where the Kotlin code lives. You could create a kotlin directory and place your Kotlin files there, but you would have to tell Android that the new folder includes source files so they would be included in your project. In most cases, separating your source files based on their language provides no benefit, so most projects just place their Kotlin files in the java directory.

MainActivity.kt may already be open in a tab in the editor tool window. If it is not, locate the app/ java directory in the project tool window and click on it to reveal its contents, then click to reveal the contents of the com.bignerdranch.android.geoquiz package. (Not one of the packages with the name shaded green – those are the test packages. The production package is unshaded.) Open the MainActivity.kt file and take a look at its contents.


Listing 4 Default class file for MainActivity (MainActivity.kt)


package com.example.geoquiz


import android.os.Bundle

import androidx.activity.enableEdgeToEdge

import androidx.appcompat.app.AppCompatActivity

import androidx.core.view.ViewCompat

import androidx.core.view.WindowInsetsCompat


class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {

       super.onCreate(savedInstanceState)

       enableEdgeToEdge()

       setContentView(R.layout.activity_main)

       ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->

           val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())

           v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)

           insets

       }

   }

}


(Wondering what AppCompatActivity is? It is a subclass of Android’s Activity class that provides compatibility support for older versions of Android.

If you are not seeing all of the import statements, click the + symbol to the left of the first import statement to reveal the others.

This file has one Activity function: onCreate(Bundle?).

The onCreate(Bundle?) function is called when an instance of the activity subclass is created. When an activity is created, it needs a UI to manage. To give the activity its UI, you call Activity.setContentView(layoutResID: Int).

This function inflates a layout and puts it onscreen. When a layout is inflated, each widget in the layout file is instantiated as defined by its attributes. You specify which layout to inflate by passing in the layout’s resource ID.


Step 9 Resources and resource IDs


A layout is a resource. A resource is a piece of your application that is not code – things like image files, audio files, and XML files.

Resources for your project live in a subdirectory of the app/res directory. In the project tool window, you can see that activity_main.xml lives in res/layout/. Your strings file, which contains string resources, lives in res/values/.

To access a resource in code, you use its resource ID. The resource ID for your layout is R.layout.activity_main.

To see the current resource IDs for GeoQuiz, you must bravely explore into the world of auto- generated code – code that the Android build tool writes on your behalf. First, run the build tool by clicking the green hammer icon in the toolbar at the top of the Android Studio window.

By default, Android Studio displays the Android project view in the project tool window. This view hides the true directory structure of your Android project so that you can focus on the files and folders that you need most often. To see the files and folders in your project as they actually are, locate the dropdown at the top of the project tool window and change from the Android view to the Project view (Figure 15).



Figure 15 – Project tool window: Android view vs Project view


Listing 5 Adding IDs to Buttons (res/layout/activity_main.xml)


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout ... >


   <TextView

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:padding="24dp"

       android:text="@string/question_text" />


   <LinearLayout

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal">


       <Button

           style="?android:attr/buttonStyle"

           android:id="@+id/true_button"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/true_button" />


       <Button

           style="?android:attr/buttonStyle"

           android:id="@+id/false_button"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/false_button" />

   </LinearLayout>

</LinearLayout>

Notice that there is a + sign in the values for android:id but not in the values for android:text. This is because you are creating the resource IDs and only referencing the strings.

Before moving on, change the project tool window from the Project view to the Android view. Throughout these labs, the Android view will be used – but feel free to use the Project version if you prefer. Also, close R.java by clicking the x in its editor tab.


Step 10 Wiring Up Widgets


You are ready to wire up your button widgets. This is a two-step process:

1)get references to the inflated View objects

2)set listeners on those objects to respond to user actions

Getting references to widgets

Now that the buttons have resource IDs, you can access them in MainActivity. Type the following code into MainActivity.kt (Listing 6). (Do not use code completion; type it in yourself.) After you save the file, it will report two errors. You will fix the errors in just a second.


Listing 6 Accessing view objects by ID (MainActivity.kt)


class MainActivity : AppCompatActivity() {


   private lateinit var trueButton: Button

   private lateinit var falseButton: Button


   override fun onCreate(savedInstanceState: Bundle?) {

       super.onCreate(savedInstanceState)

       enableEdgeToEdge()

       setContentView(R.layout.activity_main)

       ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->

           val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())

           v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)

           insets

       }


       trueButton = findViewById(R.id.true_button)

       falseButton = findViewById(R.id.false_button)

   }

}


An activity, you can get a reference to an inflated widget by calling Activity.findViewById(Int). This function returns the corresponding view. Rather than return it as a View, it is cast to the expected subtype of View. Here, that type is Button.

In the code above, you use the resource IDs of your buttons to retrieve the inflated objects and assign them to your view properties. Since the view objects are not inflated into and available in memory until after setContentView(…) is called in onCreate(…), you use lateinit on your property declarations to indicate to the compiler that you will provide a non-null View value before you attempt to use the contents of the property. Then, in onCreate(…), you look up and assign the view objects the appropriate properties. You will learn more about onCreate(…) and the activity lifecycle.

Now let’s get rid of those pesky errors. Mouse over the red error indicators. They both report the same problem: Unresolved reference: Button.

These errors are telling you that you need to import the android.widget.Button class into MainActivity.kt. You could type the following import statement at the top of the file:


import android.widget.Button


Or you can do it the easy way and let Android Studio do it for you. Just press Option-Return (or Alt- Enter) to let the IntelliJ magic under the hood amaze you. The new import statement now appears with the others at the top of the file. This shortcut is generally useful when something is not correct with your code. Try it often!

This should get rid of the errors. (If you still have errors, check for typos in your code and XML.) Once your code is error free, it is time to make your app interactive.


Setting listeners


Android applications are typically event driven. Unlike command-line programs or scripts, event-driven applications start and then wait for an event, such as the user pressing a button. (Events can also be initiated by the OS or another application, but user-initiated events are the most obvious.)

When your application is waiting for a specific event, we say that it is “listening for” that event. The object that you create to respond to an event is called a listener, and the listener implements a listener interface for that event.

The Android SDK comes with listener interfaces for various events, so you do not have to write your own. In this case, the event you want to listen for is a button being pressed (or “clicked”), so your listener will implement the View.OnClickListener interface.

Start with the TRUE button. In MainActivity.kt, add the following code to onCreate(Bundle?) just after the variable assignments.


Listing 7 Setting a listener for the TRUE button (MainActivity.kt)


override fun onCreate(savedInstanceState: Bundle?) {

   super.onCreate(savedInstanceState)

   enableEdgeToEdge()

   setContentView(R.layout.activity_main)

   ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->

       val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())

       v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)

       insets

   }


   trueButton = findViewById(R.id.true_button)

   falseButton = findViewById(R.id.false_button)


   trueButton.setOnClickListener { view: View ->

       // Do something in response to the click here

   }

}


(If you have an Unresolved reference: View error, try using Option-Return [Alt-Enter] to import the View class.)

In Listing 8, you set a listener to inform you when the Button known as trueButton has been pressed. The Android framework defines View.OnClickListener as a Java interface with a single method, onClick(View). Interfaces with a single abstract method are common enough in Java that the pattern has a pet name, SAM.

Kotlin has special support for this pattern as part of its Java interoperability layer. It lets you write a function literal, and it takes care of turning that into an object implementing the interface. This behind- the-scenes process is called SAM conversion.

Your on-click listener is implemented using a lambda expression. Set a similar listener for the FALSE button.


Listing 8 Setting a listener for the FALSE button (MainActivity.kt)


override fun onCreate(savedInstanceState: Bundle?) {

...

trueButton.setOnClickListener { view: View ->

// Do something in response to the click here

}


falseButton.setOnClickListener { view: View ->

// Do something in response to the click here

}

}

Step 11 Making Toasts


Now to make the buttons fully armed and operational. You are going to have a press of each button trigger a pop-up message called a toast. A toast is a short message that informs the user of something but does not require any input or action. You are going to make toasts that announce whether the user answered correctly or incorrectly (Figure 16).



Figure 16 – A toast providing feedback


First, return to strings.xml and add the string resources that your toasts will display.


Listing 9 Adding toast strings (res/values/strings.xml)

<resources>

<string name="app_name">GeoQuiz</string>

<string name="question_text">Canberra is the capital of Australia.</string>

<string name="true_button">True</string>

<string name="false_button">False</string>

<string name="correct_toast">Correct!</string>

<string name="incorrect_toast">Incorrect!</string>

</resources>


Next, update your click listeners to create and show a toast. Use code completion to help you fill in the listener code. Code completion can save you a lot of time, so it is good to become familiar with it early.

Start typing the code shown in Listing 10 in MainActivity.kt. When you get to the period after the Toast class, a pop-up window will appear with a list of suggested functions and constants from the Toast class.

To choose one of the suggestions, use the up and down arrow keys to select it. (If you wanted to ignore code completion, you could just keep typing. It will not complete anything for you if you do not press the Tab key, press the Return key, or click on the pop-up window.)

From the list of suggestions, select makeText(context: Context, resId: Int, duration: Int). Code completion will add the complete function call for you.

Fill in the parameters for the makeText(…) function until you have added the code shown in Listing 10.


Listing 10 Making toasts (MainActivity.kt)


override fun onCreate(savedInstanceState: Bundle?) {

...

trueButton.setOnClickListener { view: View ->

// Do something in response to the click here

Toast.makeText(

this,

R.string.correct_toast,

Toast.LENGTH_SHORT)

.show()

}

false.setOnClickListener { view: View ->

// Do something in response to the click here

Toast.makeText(

this,

R.string.incorrect_toast,

Toast.LENGTH_SHORT)

.show()

}

}


To create a toast, you call the static function Toast.makeText(Context!, Int, Int). This function creates and configures a Toast object. The Context parameter is typically an instance of Activity (and Activity is a subclass of Context). Here you pass the instance of MainActivity as the Context argument.

The second parameter is the resource ID of the string that the toast should display. The Context is needed by the Toast class to be able to find and use the string’s resource ID. The third parameter is one of two Toast constants that specify how long the toast should be visible.

After you have created a toast, you call Toast.show() on it to get it onscreen.

Because you used code completion, you do not have to do anything to import the Toast class. When you accept a code completion suggestion, the necessary classes are imported automatically.

Now, let’s see your app in action.


Step 12 Running on the Emulator


To run an Android application, you need a device – either a hardware device or a virtual device. Virtual devices are powered by the Android emulator, which ships with the developer tools.

To create an Android virtual device (or AVD), choose Tools → AVD Manager. When the AVD Manager appears, click the +Create Virtual Device... button in the lower-left corner of the window.

In the dialog that appears, you are offered many options for configuring a virtual device. For your first AVD, choose to emulate a Pixel 2, as shown in Figure 17. Click Next.


Figure 17 – Choosing a virtual device


Finally, you can review and tweak properties of the emulator. You can also edit the properties of an existing emulator later. For now, name your emulator something that will help you to identify it later and click Finish (Figure 18).


Figure 18 – Choosing a system image


Once you have an AVD, you can run GeoQuiz on it. From the Android Studio toolbar, click the run button (it looks like a green “play” symbol) or press Control-R (Ctrl-R). In the Select Deployment Target box that appears, choose the AVD you just configured and click OK. Android Studio will start your virtual device, install the application package on it, and run the app.

Starting up the emulator can take a while, but eventually your GeoQuiz app will launch on the AVD that you created. Press buttons and admire your toasts.

If GeoQuiz crashes when launching or when you press a button, useful information will appear in the Logcat tool window. (If Logcat did not open automatically when you ran GeoQuiz, you can open it by clicking the Logcat button at the bottom of the Android Studio window.) Type MainActivity into the search box at the top of the Logcat tool window to filter the log messages. Look for exceptions in the log; they will be an eye-catching red color (Figure 19).


Figure 19 – An example NullPointerException


Compare your code with the code in the lab to try to find the cause of the problem. Then try running again.

Keep the emulator running – you do not want to wait for it to launch on every run.

You can stop the app by pressing the Back button on the emulator. The Back button is shaped like a left-pointing triangle (on older versions of Android, it looks like an arrow that is making a U-turn). Then rerun the app from Android Studio to test changes.

The emulator is useful, but testing on a real device gives more accurate results. Next you will also give GeoQuiz more geography questions with which to test the user.


Step 13 For the More Curious: The Android Build Process


By now, you probably have some burning questions about how the Android build process works. You have already seen that Android Studio builds your project automatically as you modify it, rather than on command. During the build process, the Android tools take your resources, code, and AndroidManifest.xml file (which contains metadata about the application) and turn them into an .apk file. This file is then signed with a debug key, which allows it to run on the emulator. (To distribute your .apk to the masses, you have to sign it with a release key. There is more information about this process in the lections.)

How do the contents of activity_main.xml turn into View objects in an application? As part of the build process, aapt2 (the Android Asset Packaging Tool) compiles layout file resources into a more compact format. These compiled resources are packaged into the .apk file. Then, when

setContentView(…) is called in MainActivity’s onCreate(Bundle?) function, MainActivity uses the

LayoutInflater class to instantiate each of the View objects as defined in the layout file (Figure 20).


Figure 20 – Inflating activity_main.xml


(You can also create your view classes programmatically in the activity instead of defining them in XML. But there are benefits to separating your presentation from the logic of the application. The main one is taking advantage of configuration changes built into the SDK.)


Android build tools

All of the builds you have seen so far have been executed from within Android Studio. This build is integrated into the IDE – it invokes standard Android build tools like aapt2, but the build process itself is managed by Android Studio.

You may, for your own reasons, want to perform builds from outside of Android Studio. The easiest way to do this is to use a command-line build tool. The Android build system uses a tool called Gradle.

(You will know if this section applies to you. If it does not, feel free to read along but do not be concerned if you are not sure why you might want to do this or if the commands below do not seem to work. Coverage of the ins and outs of using the command line is beyond the scope of this book.)

To use Gradle from the command line, navigate to your project’s directory and run the following command:

$ ./gradlew tasks

On Windows, your command will look a little different:

> gradlew.bat tasks

This will show you a list of available tasks you can execute. The one you want is called installDebug. Make it so with a command like this:

$ ./gradlew installDebug

Or, on Windows:

> gradlew.bat installDebug

This will install your app on whatever device is connected. However, it will not run the app. For that, you will need to pull up the launcher and launch the app by hand.

Step 14 Challenge: Customizing the Toast


To protect the integrity of your current project, we recommend you make a copy and work on challenges in the new copy.

In your computer’s file explorer, navigate to the root directory of your project. Copy the GeoQuiz folder and paste a new copy next to the original (on macOS, use the Duplicate feature). Rename the new folder GeoQuiz Challenge. Back in Android Studio, select File → Import Project.Inside the import window, navigate to GeoQuiz Challenge and select OK. The copied project will then appear in a new window ready for work.

For this challenge, customize the toast to show at the top instead of the bottom of the screen. To change how the toast is displayed, use the Toast class’s setGravity function. Use Gravity.TOP for the gravity value.


Step 15 Individual Task


Personalize your app. Add on main screen of application text with your Russian (in English) name and id number.


相关文章

【上一篇】:到头了
【下一篇】:没有了

版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp