Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build an Interactive Story App (Retired) Intents and Multiple Activities Introducing String Resources

Don't see the connection between first name in onClick method and second name in startstory method

First question: Ben said that these two variables are not connected to each other because they were defined in two different methods. So how we transferred the name from one method to another? From on Click method to Start story? What exactly happening here? Second question: We are getting user's name from mNameField and put it into variable name, and then we use the same name (?) to put to start story method, so we can put our name to intent, right? So when are we storing our name in our String.xml file? That is confusing me. Because we just got the name from mNameField and putting it into intent, but how we get it from Strings.xml if we did not put it there, did we? And if we just write <string name = "key_name">name</string it is already been set? But as Ben said the variable is only defined within the method, right? So how xml file is getting it? And how it knows which value of the variable name to take? Sorry for many questions, I am new in coding and still get confused. Thank you very much!

Jon Kussmann
Jon Kussmann
Courses Plus Student 7,254 Points

Can you post the code you're referring to? It's a little difficult to tell what you're trying to ask.

Sorry, I was trying to make my code to look like a code but it did not work.

10 Answers

Jon Kussmann
PLUS
Jon Kussmann
Courses Plus Student 7,254 Points

Okay, so in your code you have:

 mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = mNameField.getText().toString();
                startStory(name);
            }
        });

You are creating a local variable, name, getting the string from your mNameField and storing that value into it. Then you are calling in the method startStory(name)... the name you just created are the one you are passing into startStory and the same.

When startStory is called:

private void startStory(String name){
        Intent intent = new Intent(this,StoryActivity.class);
        intent.putExtra(getString(R.string.key_name), name);
        startActivity(intent);

There is a new variable called name, and you can do stuff with it. The value in this name is the value that was passed in when you called the method, they just happen to have the same "title" in this case. For example you have do this:

mNameField = (EditText) findViewById(R.id.nameEditText);
        mStartButton = (Button) findViewById(R.id.startButton);
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String mySpecialName = mNameField.getText().toString();
                startStory(mySpecialName);
            }
        });
    }
    private void startStory(String name){
        Intent intent = new Intent(this,StoryActivity.class);
        intent.putExtra(getString(R.string.key_name), name);
        startActivity(intent);

In this case the value from mySpecialName is getting passed into startStory... and that value is now stored in the local variable called name of the startStory method. Java knows that it should be the same value because it is of the same type and order that you passed in when calling that method.

Back to the xml stuff:

private void startStory(String name){
        Intent intent = new Intent(this,StoryActivity.class);
        intent.putExtra(getString(R.string.key_name), name);
        startActivity(intent);

Now, in your startStory method, you are calling

getString(R.string.key_name)

This is asking the xml value to find the string with the name "key_name" and get that value, in this case "name" In your xml you have:

<string name="key_name">name</string>

Above the string with the name "key_name" has the value of "name". Java knows to basically "replace"

getString(R.string.key_name)

with "name" because it was stored as a resource, called to be used any time you use that method.

Jon, am I wrong in assuming that when we:

intent.putExtra(getString(R.string.key_name, name);

that this is when the value for name is stored into the string resource, and when the Key and Value are attached to the intent?

Jon Kussmann
Jon Kussmann
Courses Plus Student 7,254 Points

So, when you create and intent, you have the option of putting "Extras" into the intent. The extras come in key-value pairs. The key in this case is:

getString(R.string.key_name))

The value is name, which is what was passed into the startStory method (the value that was in mNameField).

This "name" is not being stored into xml. What you are essentially doing is putting a value you want to pass in the intent, but saving it's "indentifier" (its key) with it, so you can get that value later.

In this case, it's equivalent to say you are calling:

intent.putExtra("name", name);

Now, when you are at your new activity you say:

Intent intent = getIntent();
String thisIsWhatWasInMNameField = intent.getString(getString(R.string.key_name));

What you are saying is, I saved a String value in the intent that called this activity. I want that String back.... I saved it with the key "name", please give the value that corresponds to that key.

As before, this is the same as saying:

Intent intent = getIntent();
String thisIsWhatWasInMNameField = intent.getString("name");

The reason you use resources/xml is so that you don't have to worry about having to type "name" the exact same way each time, it saves you having to worry about typos, etc.

If the second time you had typed:

intent.getString("Name");

You wouldn't get a value back, and you'd wonder where you went wrong.

Yes, I checked it out, and I think this is where some of the confusion exists. The putExtra method for intents acts like a map of a string for the key and a string for the value here. What we're using the string.xml resource for is not to store the name we typed, but the Key value to recall the name we typed, then attaching the name we typed and calling it using the string resource as the string key attached to the value of the name we typed.

Hi Nicolas, Now I think I am getting it. The value of the variable name, for example: Ben, is stored inside the intent, and the key_name is stored in Strings.xml to make sure we do not misspell the key name and will get the right name (Ben) in our second Activity, right? Intent is storing the value for the variable name and the key for the variable name is stored in Strings.xml to recall it when necessary, right?

I think it's connected for you Adilet. Make sure you can track each piece of logic as you read the code now, but I think you know what you're talking about. Good luck, and happy coding!

Nicolas

Jon Kussmann
PLUS
Jon Kussmann
Courses Plus Student 7,254 Points

Hopefully a mod can change the format of the code for you. Try doing this:

Add three ` signs (the symbol to the left of number 1 on your keyboard before and after your code

I added three ``` signs at the beginning of my code and at the end. Didn't work.

 mNameField = (EditText) findViewById(R.id.nameEditText);
        mStartButton = (Button) findViewById(R.id.startButton);
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = mNameField.getText().toString();
                startStory(name);
            }
        });
    }
    private void startStory(String name){
        Intent intent = new Intent(this,StoryActivity.class);
        intent.putExtra(getString(R.string.key_name), name);
        startActivity(intent);

Hooray! I got it!

One line of code added to Strings.xml file:

<string name="key_name">name</string>

Ok, so I looked at what code Adilet left for you, and with a little clean up, this is what I found he left:

// this is still the inside of the onCreate method, that's why 
// we have an onClick listener at the beginning of this code
// ...
mNameField = (EditText) findViewById(R.id.nameEditText); 
mStartButton = (Button) findViewById(R.id.startButton); 

   mStartButton.setOnClickListener(new View.OnClickListener() { 
      @Override public void onClick(View v) { 
         String name = mNameField.getText().toString(); 
         startStory(name); 
      } 
   }); 
}

private void startStory(String name){ 
   Intent intent = new Intent(this,StoryActivity.class); 
   intent.putExtra(getString(R.string.key_name), name); 
   startActivity(intent);
}

The onClick method that's still inside the onCreate method above has stored the name put into the name field and passed that perimeter to the startStory method (it added getText because that text window actually creates a EditText object, and we had to convert that to a string). The startStory method takes that string as a perimeter, then creates an intent. Intents are how we move from activity to activity, or from window to window in the android app. The two perimeters used to create the intent are the starting window and the window we're going to end up on, this being the context of the current window we are on, and StoryActivity.class being the window we a going to, which has a different layout. In order to pass our information to the StoryActivity window, intents actually can store more information than where we're coming and going, however, and we add and access this information by getting and putting extras onto the intent. That's what the second line in the startStory method is all about. We're adding the name we took from the text window in the first activity and passing that information to the second. These extras are passed like map data, the first perimeter being the key, and the second being the value to be stored. By replacing the key value "name" with getString(R.string.key_name), we're saying that we're going to store the value name into the resourse R.string.key_name into the xml file as a string resourse, then pass it attached to the intent we just made. A lot happened on that one line, and part of that reason is that Ben used the Android studio shortcut to create that string resource. After that, we run startActivity with that intent to pass the name string with the intent we created to the new window. So I understand your confusion, and I think this helped me a lot too to work through this. Let me know if this helped.

Nicolas

Thank you very much Gentlemen! You have explained everything really well! Much appreciated! I just did not know that the method itself (in our case startStory) can also carry some values. I always thought that only variables could carry values. Now I know. So the value inside the method startStory can be transferred in both directions? I mean it is getting the value from first "name" it got from mNameField (startStory(name)) and transferring the value to the second "name" within its own method (startStory(name)){ ?

And another one with

intent.putExtra(getString(R.string.key_name), name); 

Yes, there are a lot going on just in one line. As far as I understand "R.string.key_name" writes the value of the name to Strings.xml file. So we don't have to write something like "setString.R.string.key_name" to put value into Strings.xml file? (Sorry if it is not really used that way, it was just an example.)

And then we are getting String value and putting it into intent as extra information to carry.

Adilet

Ok, mNameField is the text we're getting from the EditText box. That becomes an EditText variable.

Then we getText mNameField and store it as a String to the String variable name so we can work with it as a string.

We pass that string to the startStory method.

We create a new intent that will direct us to the next activity.

Then we attach information to that intent with putExtra.

putExtra works like a map. A string is used for the key and a string is used for the value. The KEY is what we're storing in the strings.xml resource, so R.strings.key_name the KEY of the map inside the intent. If we were working with a map, then getKey(R.strings.key_name) would return the value attached to the key (which is also a string) in the map. putExtra is just making a new entry into the map built into the intent method. The key we use to recall the value will be R.strings.key_name, and the value associated with that key will be the name variable we got from the EditText box. With that small map made, we pass the intent to the next activity so it can get the value by using the string resource as the Key.

Questions?

You may ask why we don't just store the value directly into the string resources, but the way the app development is designed, if we only refer to the key, then those strings.xml files can be switched out and the code will work the same. That way, we can have different strings.xml files for different languages, since other information not entered by the user is in that file strings.xml, like page titles and page summaries.

Thank you very much Nicolas for your time and help!