What does R.drawable.image return? - java

public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView ballDisplay = (ImageView)findViewById(R.id.image_eightBall);
final int[] ballArray = {R.drawable.ball1,
R.drawable.ball2,
R.drawable.ball3,
R.drawable.ball4,
R.drawable.ball5};//*******What integer is that???????????
Button myButon = (Button)findViewById(R.id.askButton);
myButon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Random randomNumberGenerator = new Random();
int number = randomNumberGenerator.nextInt(5);
ballDisplay.setImageResource(ballArray[number]);
}
});
}
}
What is the value stored in that intger?

Your Drawables data type isn't an int; your reference to it is an int, which you can see in R.java.
final int[] ballArray =
{R.drawable.ball1,
R.drawable.ball2,
R.drawable.ball3,
R.drawable.ball4,
R.drawable.ball5};
so here your are only storing reference.

You probably don't really need to know the actual value of R.drawable.ball5 as it is determined during the build.... but I won't second guess your question-- the actual value of R.drawable.ball5 can be found in the file R.java in the build folder that's created during the build.
To find it in Android Studio, after you've done a build you can right-click on R.drawable.ball5 in the editor, then Go To -> Implementation(s) and you'll see the generated R.Java file as well as the number that is assigned to this resource for this build. It looks like:
public static final int ball5=0x7f080093;
Programmatically, you can just log Integer.toString(R.drawable.ball5).
That's the answer to the question you asked. But I think you'd be better off looking at R.id.ball5 for example to explicitly name the resource or reference the drawable by the name "ball5" and refer to it with that variable name. You shouldn't really care about what value R.drawable.ball5 actually is as it will likely change as you add or remove other resources.
Something like this might work better insofar as I can guess what you're trying to do:
public void onClick(View v) {
Random randomNumberGenerator = new Random();
int number = randomNumberGenerator.nextInt(5);
ballDisplay.setImageDrawable(this,
getDrawable(ballArray[number]));
}
If you want to get the drawable using a method that supports older APIs, try:
ballDisplay.setImageDrawable(
this.getResources()
.getDrawable(ballArray[number]);

R.drawable.image stores a resource id which will return an int.

There is no need to know what value it returns because you already know how to access it, and, you cannot know it initially because the value is determined during the build time, all you can know at the start is that it is a number in hexa decimal
Still if you want to know after the build completes go to R.java file there you will find it.

R.drawable.image means the drawable resource, in this case image. Drawable means graphic which can be drawn. Every drawable is stored in res/drawable folder. Your ballArray is the array of drawables.

Related

Android Runtime error on passing info between activities

I have 2 activities in my assignment: MainActivity and Country_Activity.
I'm trying to pass 2 inputs the user puts in MainActivity:
int counter
String Country
But the app always crashes here: (this is Country_Activity)
private void Update(){
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("intCounter", 0);
String country = mIntent.getStringExtra("country");
counterTextView.setText(intValue);
countryTextView.setText(country);
if (country.equals("canada")){
flagView.setImageResource(R.drawable.canada);
}
else if (country.equals("us")){
flagView.setImageResource(R.drawable.us);
}
}
Specifically on the lines "setText" for each variable.
Everything else works. I can't figure out why they wouldn't.
Thanks!
Usually the extras that are passed from one activity to another are read inside on onCreate() where all the needed initialization of variables and views is made.
In your case I see that you get the extras inside another method (maybe it's called inside onCreate()?).
So you forgot to initialize the textviews:
TextView counterTextView = findViewById(R.id.countersomething);
TextView countryTextView = findViewById(R.id.countrysomething);
also another error that you will encounter later is this:
counterTextView.setText(intValue);
change it to:
counterTextView.setText(String.ValueOf(intValue));
Don't pass an integer value inside setText() because it will be treated as the id of a resource.

EditText to integer in android

i checked this web site on how to convert from string to integer type in java(android).... one of suggestion was to use (integer.parseint) i used it and when i run my application it says my app has stopped working my code below .
public void clickable (View view){
EditText mytext = (EditText) findViewById(R.id.Creat);
int number = Integer.parseInt(mytext.getText().toString());
Toast.makeText(getApplicationContext(), number ,Toast.LENGTH_LONG).show();
}
i cant figure out what is the problem with the code ?!
Declare EditText mytext variable as a global variable and then initialize it in Oncreate() method of your Activity. Then your clickable method looks like this:
public void clickable (View view){
int number = Integer.parseInt(mytext.getText().toString());
Toast.makeText(getApplicationContext(), mytext.getText().toString(), Toast.LENGTH_LONG).show();
}
Obeserve Toast.makeText() method's second argument is the resource id of the string resource to use or it can be formatted text. In your code you have passed an integer as a resource id which does not exist. So you get ResourcesNotFoundException.
What string are you passing into the Integer.parseInt()? If it's not an integer, your program will experience a NumberFormatException. I'm not sure if that's the issue here, but I'm not sure what you're passing into the Integer.parseInt().
There are many implementations of Toast.makeText. As you are passing an int as the second argument, the following implementation will execute:
Toast makeText(Context context, #StringRes int resId, #Duration int duration)
This implementation will throw a ResourcesNotFoundException if it cannot find a resource with the id of resId.
To output number as a String you need to convert it:
Toast.makeText(getApplicationContext(), String.valueOf(number), Toast.LENGTH_LONG).show();

Most efficient way to fill a Map in Java

I am new to Java and I'm coding a simple "Positive Quotes" app. (using Android Studio) that lets you press on a button, that will display a positive quote (randomly selected) from a Map.
The code itself is rather basic:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Sets the right TextView / Button to each object
final TextView textView = (TextView)findViewById(R.id.textView);
final Button button1 = (Button)findViewById(R.id.button);
// Implement listener for your button so that when you click the
// button, android will listen to it.
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Map<Integer, String> quotes = new HashMap<Integer, String>();
// Generate your quotes Map
quotes = createQuotesMap();
Random generator = new Random();
Object[] values = quotes.values().toArray();
Object randomValue = (String) values[generator.nextInt(values.length)];
// Perform action on click
textView.setText(randomValue.toString());
} });
}
But my question comes from where I fill up my quotes map:
public Map<Integer, String> createQuotesMap() {
Map<Integer, String> quotes = new HashMap<Integer, String>();
quotes.put(1, "Correction does much, but encouragement does more.");
quotes.put(2, "Keep your face to the sunshine and you cannot see a shadow.");
quotes.put(3, "Once you replace negative thoughts with positive ones, you'll start having positive results.");
quotes.put(4, "Positive thinking will let you do everything better than negative thinking will.");
quotes.put(5, "Pessimism leads to weakness, optimism to power.");
quotes.put(6, "The thing that lies at the foundation of positive change, the way I see it, is service to a fellow human being.");
quotes.put(7, "In every day, there are 1,440 minutes. That means we have 1,440 daily opportunities to make a positive impact.");
quotes.put(8, "Attitude is a little thing that makes a big difference.");
return quotes;
}
Would there be a more efficient way of filling up my Map, or a better container for such a basic application? Could you also point out bad coding habits from the chunk of code that I have shared?
EDIT:
My app. is now complete - I create an array of quotes (only once and not at every click like before) and display one, randomly chosen.
Hint: the main performance aspects here are:
You do not want to create a new map for each new users. The quotes will be be the same all the time, right; so the one and only thing worth worrying about is: how to make sure that you create the map exactly once. So instead of using a local variable, you could create a single static class-wide map.
Why do you want to use a map? You know, when you want to have a sequence of ints to be your key; why don't you just use an List?
In other words: when "optimizing" always try think about the big picture. But your question implies that you are very much thinking from the opposite side of things. You spent your time worrying about the cost of a single operation; instead of looking at your application at a hole ...
Same thing for the map versus list thing. There is absolutely no point in using a map ... to then use it like an list.
Firstly, in terms of efficiency, instead of generating the map every time you click the button, consider making it a field of your Activity and initiating it in your onCreate(). You can then use that field in your onClickListener as such:
//Class field
private Map<Integer, String> quotes;
protected void onCreate(Bundle savedInstanceState) {
// Generate your quotes Map
quotes = createQuotesMap();
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Random generator = new Random();
Object[] values = quotes.values().toArray();
//etc
}
});
}
Secondly and most importantly, this really doesn't warrant the use of a Map. You are better off using a simple array or an ArrayList.
You can still access random elements from them by using array[myRandomIndex] or arrayList.get(myRandomIndex) depending on how you wish to implement it.
Just be mindful that initialising these arrays should not be done in an OnClickListener as it would run that code every time the button is clicked.
String[] quotes = {
"Correction does much, but encouragement does more.",
"Keep your face to the sunshine and you cannot see a shadow.",
"Once you replace negative thoughts with positive ones, you'll start having positive results.",
};
public void onClick(View v){
...
Random r = new Random();
selectedQuote = r.nextInt(quotes.length);
textView.setText(selectedQuite);
...
}
I hope this helps you solve yout problem
String[] stringQuotes = {
"Correction does much, but encouragement does more.",
"Keep your face to the sunshine and you cannot see a shadow.",
"Once you replace negative thoughts with positive ones, you'll start having positive results.",
"Positive thinking will let you do everything better than negative thinking will."
};
for(int i = 0; i < stringQuotes.length; i++){
quotes.put(i, stringQuotes[i]);
}
It is faster to use a for-loop, but it requires that all strings are saved in a string[] array which makes the initialization faster
You can create an array once using the method createQuotes(). And you don't need a map, because you only need to obtain a random string among the given strings. As for the key in the map, it transforms perfectly into the array's index. So I suggest you use the below :
public class YourClass {
private static final String[] QUOTES = createQuotes();
private Random generator = new Random();
protected void onCreate(Bundle savedInstanceState) {
// ...
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String randomValue = QUOTES[generator.nextInt(QUOTES.length)];
textView.setText(randomValue);
}
});
}
private static String[] createQuotes() {
String[] quotes = new String[] {
"Correction does much, but encouragement does more.",
"Keep your face to the sunshine and you cannot see a shadow.",
"Once you replace negative thoughts with positive ones, you'll start having positive results.",
"Positive thinking will let you do everything better than negative thinking will.",
"Pessimism leads to weakness, optimism to power.",
"The thing that lies at the foundation of positive change, the way I see it, is service to a fellow human being.",
"In every day, there are 1,440 minutes. That means we have 1,440 daily opportunities to make a positive impact.",
"Attitude is a little thing that makes a big difference."
}
return quotes;
}
}
I can't test the code. Please edit me if there's any error.

Adding an array of views crashes an android app

I have some part of an android app here which crashes for no apparent reason.
RL0 happens to be some LinearLayout defined in XML which already contains some other irrelevant stuff. To be honest with you, I've mostly worked with C++ so I might not initially know much about why some things are done significantly different in android, but I'm putting effort. Any help on how I can fix that crash?
Error message states NullPointerException.
Thanks.
public class Osteoporoza extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_osteoporoza);
LinearLayout RL0=(LinearLayout)findViewById(R.id.RL0);
page[] pages=new page[10];
RL0.addView(pages[0].pageLL0);//doesn't crash without this line, yet i need to have some way of adding n objects that follow a pattern, i.e. a class.
class page
{
public LinearLayout pageLL0;
public ScrollView pageUpperScroll1;
public TextView pageTextView2;
public ScrollView pageLowerScroll1;
public LinearLayout pageAnswerButtonLL2;
public Button AnswerButton3_1;
public Button AnswerButton3_2;
public Button AnswerButton3_3;
public Button AnswerButton3_4;
page()
{
pageAnswerButtonLL2.addView(AnswerButton3_1);
pageAnswerButtonLL2.addView(AnswerButton3_2);
pageAnswerButtonLL2.addView(AnswerButton3_3);
pageAnswerButtonLL2.addView(AnswerButton3_4);
pageLowerScroll1.addView(pageAnswerButtonLL2);
pageUpperScroll1.addView(pageTextView2);
pageLL0.addView(pageUpperScroll1);
pageLL0.addView(pageLowerScroll1);
}
}
All elements in an Object array are null by default.
I.e. when you create the array:
page[] pages = new page[10];
you are only setting the size of the array but not setting any instances within the array itself so every element will be null. To instantiate each element you need to use:
for (int i=0; i < pages.length; i++) {
pages[i] = new page();
}
Note Java naming conventions show that class names start with an uppercase letter, for example
Page[] pages = new Page[10];
- You have declared the Array but didn't initialize it.
Eg:
page[] pages = new page[10]; // Tell that this is an Array of page of length 10
- You will need to Initialize it,
Eg:
for (page p : pages){
p = new page();
}
- Please use the Collection like ArrayList instead of Array, as its far more flexible than using an Array.
- ArrayList can hold null values, and unlike Array, its size can increased.
ArrayList<page> p = new ArrayList<page>();
- Always make the 1st letter of a class, enum , interface as Capital.
Eg:
It should Not page but Page

Android Java - Putting all file names from R.raw into array without manually specifying each

There are 2 parts to my question but both are related. I have searched all over the place but cannot find a way to put in an array, all file names from R.raw, such as MP3s in string format.
I also want to create new buttons on the fly in Java, as opposed to using the XML files to lay out buttons.
psuedocode:
array[] = put all file names from R.raw into this array with file name;
count = count num of rows in array[];
//I want to be able to do this with that array
for (int i = 0; i < count; i++) {
create new button and assign it a sound(onclick);
this.button should be placeable anywhere i want without using XML for layout
}
Thanks in advance to any help anyone can provide!
Short answer: You can't.
Long answer: R.raw and the likes are generated at build time, thus static in your code (you can't dynamically add entries to these objects from your app). Basically, R is just a class that looks something like:
package com.yourapp;
public class R {
public class raw {
public static final int file_1 = 123456; // where 123456 is the address where that file will be found
public static final int file_2 = 789012;
// ...
}
}
Thus, there's no way (that I know of) of getting an array of these attributes.
I recommend you use the assets/ directory instead of R.raw. This way, you'll be able to use AssetManager.list() to get a list of files (and the other AssetManager functions for actually working with the files).
You can use reflection:
Field [] f=R.raw.class.getFields();
for (Field field : f) {
field.getName();
}

Categories