Random Posts

3/2/16

Part 10: Setting listeners in android


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 QuizActivity.java, add the following code to onCreate(…) just after the variable assignment.
Listing 1.9 Set listener for True button (QuizActivity.java)
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
mTrueButton = (Button) findViewById(R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Does nothing yet, but soon!
}
});
mFalseButton = (Button) findViewById(R.id.false_button);
}
}

(If you have a View cannot be resolved to a type error, try using Option+Return (Alt+Enter) to import the View class.) In Listing 1.9, you set a listener to inform you when the Button known as mTrueButton has been pressed. The setOnClickListener(OnClickListener) method takes a listener as its argument. In particular, it takes an object that implements OnClickListener.
Using anonymous inner classes
This listener is implemented as an anonymous inner class. The syntax is a little tricky, but it helps to remember that everything within the outermost set of parentheses is passed into 
setOnClickListener(OnClickListener). Within these parentheses, you create a new, nameless class and pass its entire implementation.

mTrueButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// Does nothing yet, but soon!}});All of the listeners in this book will be implemented as anonymous inner classes. Doing so puts the implementations of the listeners’ methods right where you want to see them. And there is no need for the overhead of a named class because the class will be used in one place only. Because your anonymous class implements OnClickListener, it must implement that interface’s sole method, onClick(View). You have left the implementation of onClick(View) empty for now, and the compiler is OK with that. A listener interface requires you to implement onClick(View), but it makes no rules about how to implement it. (If your knowledge of anonymous inner classes, listeners, or interfaces is rusty, you may want to review some Java before continuing or at least keep a reference nearby.)
Set a similar listener for the False button.
Listing 1.10 Set listener for False button (QuizActivity.java)
...
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Does nothing yet, but soon!
}
});
mFalseButton = (Button) findViewById(R.id.false_button);
mFalseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Does nothing yet, but soon!
}
});
}

Part9: Wiring Up and Getting references to widgets in Android

Now that the buttons have resource IDs, you can access them in QuizActivity. The first step is to add two member variables. Type the following code into QuizActivity.java. (Do not use code completion; type it in yourself.) After you save the file, it will report two errors.
Listing 1.7 Adding member variables (QuizActivity.java)
public class QuizActivity extends AppCompatActivity {private Button mTrueButton;private Button mFalseButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.activity_quiz);
}
...
}

You will fix the errors in just a second. First, notice the m prefix on the two member (instance) variable names. This prefix is an Android naming convention that we will follow throughout this book. Now mouse over the red error indicators. They report the same problem: Cannot resolve symbol 'Button'.
These errors are telling you that you need to import the android.widget.Button class into QuizActivity.java. 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.) Now you can wire up your button widgets. This is a two-step process: get references to the inflated View objects; set listeners on those objects to respond to user actions
Getting references to widgets
In an activity, you can get a reference to an inflated widget by calling the following Activity method: public View findViewById(int id) This method accepts a resource ID of a widget and returns a View object. In QuizActivity.java, use the resource IDs of your buttons to retrieve the inflated objects and assign them
to your member variables. Note that you must cast the returned View to Button before assigning it.
Listing 1.8 Getting references to widgets (QuizActivity.java)
public class QuizActivity extends AppCompatActivity {
private Button mTrueButton;
private Button mFalseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
mTrueButton = (Button) findViewById(R.id.true_button);
mFalseButton = (Button)findViewById(R.id.false_button);
}
...
}

25/1/16

Part 8: Resources and resource IDs in Android

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_quiz.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_quizTo see the current resource IDs for GeoQuiz, you must first change your project view. By default, Android Studio uses the Android project view (Figure 1.13). This view hides away the true directory structure of your
Android project so that you can focus on the files and folders that you need most often.
Figure 1.13 Changing the project view
Locate the dropdown at the top of the Project tool window and change from the Android project view to the Project view. The Project view will show you the files and folders in your project as they actually are. To see the resources for GeoQuiz, reveal the contents of the app/build/generated/source/r/debug directory. In this directory, find your project’s package name and open R.java within that package. Because this file is generated by the Android build process, you should not change it, as you are subtly warned at the top of the file. After making a change to your resources, you may not see this file instantly update. Android Studio maintains a hidden R.java that your code builds against. The R.java file that you are looking at here is the one that is generated for your app just before it is installed on a device or emulator. You will see this file up date when you run your app.
Listing 1.5 Current GeoQuiz resource IDs (R.java)
/* AUTO-GENERATED FILE. DO NOT MODIFY.
**
This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.bignerdranch.android.geoquiz;
public final class R {
public static final class anim {
...
}

...
public static final class id {
...
}

public static final class layout {
...
public static final int activity_quiz=0x7f030017;
public static final class mipmap {
public static final int ic_launcher=0x7f030000;
public static final class string {
...
public static final int app_name=0x7f0a0010;
public static final int correct_toast=0x7f0a0011;
public static final int false_button=0x7f0a0012;
public static final int incorrect_toast=0x7f0a0013;
public static final int question_text=0x7f0a0014;
public static final int true_button=0x7f0a0015;
}


The R.java file can be large and much of this file is omitted from Listing 1.5.
This is where the R.layout.activity_quiz comes from – it is an integer constant named
activity_quiz within the layout inner class of RYour strings also have resource IDs. You have not yet referred to a string in code, but if you did, it would look like this: setTitle(R.string.app_name);
Android generated a resource ID for the entire layout and for each string, but it did not generate IDs for the individual widgets in activity_quiz.xml. Not every widget needs a resource ID. In this chapter, you will only interact with the two buttons in code, so only they need resource IDs.
Before generating the resource IDs, switch back to the Android project view. Throughout this book, the Android project view will be used – but feel free to use the Project version if you prefer. To generate a resource ID for a widget, you include an android:id attribute in the widget’s definition. In activity_quiz.xml, add an android:id attribute to each button.
Listing 1.6 Adding IDs to Buttons (activity_quiz.xml)
<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"... >
<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"><Buttonandroid:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
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 IDs and only referencing the strings.

Facebook