JGallardo
JGallardo

Reputation: 11373

Calling values from an array in the string.xml file in an Android app

I have built a fortune cook app that previously currently has values hardcoded into an array

FortuneActivity.java

package juangallardo.emofortunecookie;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Random;


public class FortuneActivity extends Activity {

  private FortuneBox mFortuneBox = new FortuneBox();

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

    // Declare our View variables and assign them the Views from the layout file
    final TextView fortuneLabel = (TextView) findViewById(R.id.fortuneTextView);
    Button showFortuneButton = (Button) findViewById(R.id.showFortuneButton);
    View.OnClickListener listener = new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          String fortune = mFortuneBox.getFortune();
          // Update the label with dynamic fortune
          fortuneLabel.setText(fortune);
      }
    };
    showFortuneButton.setOnClickListener(listener);

  }
}

FortuneBox.java

package juangallardo.emofortunecookie;

import java.util.Random;

public class FortuneBox {

  public String[] mFortunes = {

        "What is the point?",
        "Sometimes it is best to just sleep in.",
  #98 other fortunes...
};

// Methods (abilities)
public String getFortune() {

    String fortune = "";

    // Randomly select a fortune
    Random randomGenerator = new Random();
    int randomNumber = randomGenerator.nextInt(mFortunes.length);

    fortune = mFortunes[randomNumber];

    return fortune;
  }
}



The problem is that now I want to add a Spanish version. So I realize that i should add that array into the strings.xml.

I looked up string resources on the Android developer page. and it gave me the idea to add this to my code

strings.xml

<string-array name="emo_fortunes">
    <item>What is the point?</item>
    <item>Sometimes it is best to just sleep in.</item>
</string-array>

But now I am stuck on where to add this part that has the part about Resources, etc.

enter image description here

I followed along to a tutorial from Treehouse about strings but my app kept crashing.

Basically the change that I made was to make the original array into

FortuneBox.java

# above unchanged from previous code
public String[] mFortunes;
# below unchanged from previous code

FortuneActivity.java

# same imports as before
public class FortuneActivity extends Activity {

private FortuneBox mFortuneBox = new FortuneBox();

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

    Resources resources = getResources();
    final String[] mFortuneBox = resources.getStringArray(R.array.emo_fortunes);

    // Declare our View variables and assign them the Views from the layout file
    final TextView fortuneLabel = (TextView) findViewById(R.id.fortuneTextView);
    Button showFortuneButton = (Button) findViewById(R.id.showFortuneButton);
    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String fortune = mFortuneBox.getFortune();
            // Update the label with dynamic fortune
            fortuneLabel.setText(fortune);
        }
    };
    showFortuneButton.setOnClickListener(listener);

  }
}

These were my errors, but not sure where to go from here as I am new to Android and I have not touched Java since college.

log

enter image description here

FortuneActivity.java

enter image description here

FortuneBox.java

enter image description here

Upvotes: 0

Views: 851

Answers (3)

Ben Jakuben
Ben Jakuben

Reputation: 3237

Mikki has the right answer, but it is a little confusing. In your code above, you are using the same name for two different variables: mFortuneBox. This is the root of your trouble:

private FortuneBox mFortuneBox = new FortuneBox();
...
final String[] mFortuneBox = resources.getStringArray(R.array.emo_fortunes);

Change the second one to a different name, like this, and the errors go away:

final String[] fortunes = resources.getStringArray(R.array.emo_fortunes);

However, you still aren't using these fortunes from the array anywhere. You can actually delete fortunes from your Activity and move it to your FortuneBox class instead. This is slightly tricky, though, as you need to know what the context is to get a string array resource in your other class. The context is the Activity, so you need to pass this along as a parameter when you create your FortuneBox object.

I'd recommend a slight restructuring. Below are the two files that should work for you:

FortuneActivity.java

public class FortuneActivity extends Activity {

    private FortuneBox mFortuneBox;

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

        mFortuneBox = new FortuneBox(this);

        // Declare our View variables and assign them the Views from the layout file
        final TextView fortuneLabel = (TextView) findViewById(R.id.fortuneTextView);
        Button showFortuneButton = (Button) findViewById(R.id.showFortuneButton);
        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String fortune = mFortuneBox.getFortune();
                // Update the label with dynamic fortune
                fortuneLabel.setText(fortune);
            }
        };
        showFortuneButton.setOnClickListener(listener);

    }
}

FortuneBox.java

public class FortuneBox {

    public String[] mFortunes;

    public FortuneBox(Context context) {
        Resources resources = context.getResources();
        mFortunes = resources.getStringArray(R.array.emo_fortunes);
    }

    // Methods (abilities)
    public String getFortune() {

        String fortune = "";

        // Randomly select a fortune
        Random randomGenerator = new Random();
        int randomNumber = randomGenerator.nextInt(mFortunes.length);

        fortune = mFortunes[randomNumber];

        return fortune;
    }
}

Upvotes: 1

Mikki
Mikki

Reputation: 138

The mFortuneBox variable in the previous way you have used is an object of FortuneBox class and hence this call mFortuneBox.getFortune() works. In the later changed code, you have made mFortuneBox variable a reference to an Array of strings. But still tried calling mFortuneBox.getFortune(). 'getFortune()' is a method of FortuneBox class right, so you can call it with an object of Forune Box class itself.

Try doing this: final String[] fortuneArray = resources.getStringArray(R.array.emo_fortunes); and private FortuneBox mFortuneBox = new FortuneBox(); Now call mFortuneBox.getFortune(fortunearray) sending it this array to the getfortune method. Now let the getFortune() method randomly pick one from this array passed and return the random string picked

Upvotes: 1

Junior Buckeridge
Junior Buckeridge

Reputation: 2085

Your problem is simple. You can not access a non-final from an inner class (in this case your OnClickListener).

final String[] mFortuneBox = resources.getStringArray(R.array.emo_fortunes);

Try just changing the line to look like this one above.

Hope it helps.

Upvotes: 1

Related Questions