I am working through a Udemy course and we're building a basic "Higher or Lower" app. My app essentially works, however the random number it chooses for us to guess is always the same no matter how many times I destroy and relaunch the activity.
My MainActivity.java:
//mad import statements here
public class MainActivity extends AppCompatActivity {
int correctNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int correctNumber = generateNum();
}
protected int generateNum(){
Random rand = new Random();
int randNum = rand.nextInt(100);
return randNum;
}
protected void numberEval(View view) {
EditText enteredNumber = (EditText) findViewById(R.id.numberEntry);
String numberString = enteredNumber.getText().toString();
Button pressMe = (Button) findViewById(R.id.button);
int numToEval = Integer.parseInt(numberString);
String result;
TextView showWinLose = (TextView) findViewById(R.id.winLoseText);
if (numToEval > correctNumber) {
result = "Too high!";
} else if (numToEval < correctNumber) {
result = "Too Low!";
}else {
result = "You guessed it!";
}
showWinLose.setText(result);
}
}
Super super basic, yes? Originally, my numberEval() method called generateNum(), but then I realized it was generating a new number to guess every time I pressed the button. So I set it the way it was here, where onCreate() generates correctNumber only once and correctNumber is now a class variable. Now it doesn't generate a new number every button click, but it won't seem to generate a new number at all. It's stuck at 0 no matter how any times I launch, close, relaunch, etc. the app.
How can I fix this? Thanks in advance.
public class MainActivity extends AppCompatActivity {
int correctNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int correctNumber = generateNum();
}
// ...
}
The last line in onCreate() declares a local variable named correctNumber. This hides the class field with the same name and is only available inside onCreate(). To fix the problem, remove int from this line so that you use the class field instead.
Related
I am still a beginner and this is my first post here on the forum, sorry if the format of the question is not the right one.
I have an array of Resources in a class called DatabaseTagWalk that I use to find the id of a button in the MainActivity class.
This is the class where I store the id (in the activity_main.xml file i have created 6 buttons and assigned to them the same names as down here
public class DatabaseTagWalk {
int[] iconWalkId;
public DatabaseTagWalk(){
iconWalkId = new int[6];
iconWalkId[0] = R.id.topsightswalk;
iconWalkId[1] = R.id.literarypariswalk;
iconWalkId[2] = R.id.secretpassageswalk;
iconWalkId[3] = R.id.picnictimewalk;
iconWalkId[4] = R.id.joggitwalk;
iconWalkId[5] = R.id.deluxegardenswalk;
}
}
And this is the main activity class where I look for the id of the button to set a specific text and to specify the parameters used when the button is clicked
public class MainActivity extends AppCompatActivity {
DatabaseWalks listofwalks;
DatabaseTagWalk tagWalk;
Button[] buttons;
int buttonClicked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listofwalks = new DatabaseWalks();
tagWalk = new DatabaseTagWalk();
for (int i = 0; i < listofwalks.walkList.length; i++) {
buttons[i] = (Button) findViewById(tagWalk.iconWalkId[i]);
buttons[i].setText(listofwalks.walkList[i].returnWalk());
setOnClick(buttons[i], tagWalk.iconWalkId[i]);
}
}
public void setOnClick(Button button, final int buttonTag ){
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonClicked = buttonTag;
Intent startingGame = new Intent("android.intent.action.SECONDACTIVITY");
startingGame.putExtra("buttonTag", buttonClicked);
startActivity(startingGame);
}
});
}
}
When i run the app I get the error:
"Attempt to write to null array" in the MainActivity at the line:
buttons[i] = (Button) findViewById(tagWalk.iconWalkId[i]);
You did not initialize your buttons list. You told that this variable exist, but you did not assign any value.
Change your line:
Button[] buttons;
to (if you know size - e.g. 10):
Button[] buttons = new Button[10];
or if wyou would like base on walkList size:
// After this line
listofwalks = new DatabaseWalks();
// Add new line, because here you know the list size
buttons = new Button[listofwalks.walkList.length];
I have list with multiple choice. Application must calculate the average of whole list's positions.
In first activity
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
Button button_1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_1 = (Button) findViewById(R.id.button_1);
button_1.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_1:
Intent intent = new Intent(this, Main3Activity.class);
startActivity(intent);
break;
}
}
}
In second activity each position must have int variable ( Uruguay - 3444000, Paraguay - 6725000 e.t.c) In result, in third activity must be displayed average of each position.
public class Main3Activity extends AppCompatActivity {
Button button2
\button2 direct to third activity
String[] countries = { "Urugay", "Paraguay", "Jamaica", "Peru", "Mexico"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView countriesList = (ListView) findViewById(R.id.countriesList);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_multiple_choice, countries);
countriesList.setAdapter(adapter);
}
}
The countries displayed in second activity without variables. But after picked by user, average displayed in third activity.
Need your advice, Or some code )
Just like this array:
String[] countries = { "Urugay", "Paraguay", "Jamaica", "Peru", "Mexico"};
create another one:
int[] positions = { 3444000, 6725000, 0, 0, 0};
then with a loop you find the average:
int sum = 0;
for (i = 0; i < positions.length; i++) {
sum += positions[i];
}
int average = sum / positions.length;
Is it that you need to calculate the average? You do that by adding all the points an divide them by the number of entries. So in this case, add the points of the two countries an divide them by two.
Keep in mind that dividing mostly has a result with a fraction (something behind the decimal point), so be sure to get a floating point type variable and, if needed, round appropriately to an int afterwards.
This class extends my main Activity.
public class Numbers extends MainActivity{
public ArrayList<ImageView> getNumbers () {
ArrayList<ImageView> numbers = new ArrayList<>();
ImageView one = (ImageView) findViewById(R.id.one);
numbers.add(one);
return numbers;
}
And I've done some digging but can figure out why my variable "one" is coming back null.
My MainActivity has a ContentView set.
This is the content of my onCreate in MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView start = (ImageView) findViewById(R.id.start);
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);
questionView = findViewById(R.id.questionView);
startView = findViewById(R.id.startView);
gameOverView = findViewById(R.id.gameOver);
animSlide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide);
animSlide.setAnimationListener(this);
animZoom = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.zoom_fade);
animZoom.setAnimationListener(this);
set.addTransition(new Fade())
.addTransition(new Slide(Gravity.RIGHT));
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getQuestion();
TransitionManager.beginDelayedTransition(sceneRoot, set);
startView.setVisibility(View.GONE);
questionView.setVisibility(View.VISIBLE);
}
});
}
public void getQuestion (){
time = (TextView) findViewById(R.id.timeBar);
time.startAnimation(animSlide);
}
I don't call getNumbers() until after start has been clicked and the animation has started.
public void onAnimationStart(Animation animation){
if(animation == animSlide) {
final Questions questions = new Questions();
Numbers n = new Numbers();
for (int i = 0; i < n.getNumbers().size(); i++) {
n.getNumbers().get(i).setVisibility(View.GONE);
n.getNumbersTen().get(i).setVisibility(View.GONE);
}
n.getNumbers().get(0).setVisibility(View.VISIBLE);
EDIT:
If anyone was wondering, I got it to work by extending the class as a Fragment instead of my MainActivity. Then I just used the fragment in my xml.
Because you extended an Activity class doesn't mean setContentView gets called for that class also. It will only do so if properly started and you call super.onCreate(bundle) from your own implementation of onCreate within Numbers
Basically, you should never new any Activity. It has no life-cycle, and therefore no content view, so findViewById just won't work.
Numbers n = new Numbers();
You could not extend anything and have a data-only class around your list of images.
public class Numbers {
private List<ImageView> numbers = new ArrayList<ImageView>();
public Numbers() {}
public void addNumber(ImageView v) { numbers.add(v); }
public List<ImageView> getNumbers() { return numbers; }
}
And from MainActivity you can find and add as you want.
Number n = new Numbers();
n.addNumber((ImageView) findViewById(R.id.one));
However, I don't know if that is useful, really...
Maybe a Fragment would serve a better purpose if you want a "sub-view" of your Activity, but it's hard to tell.
i don't know if this is possible or if they is a better programming practice but i'd like to know how to use a varible declared in the main activity in another activity. Source code snippet example is given like so...
public class MainActivity extends ActionBarActivity {
private int a, b;
private EditText first, second;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
first = (EditText) findViewById(R.id.first_entry);
second = (EditText) findViewById(R.id.second_entry); }
public void doMath(View view) throws Exception {
try {
if (!first.getText().toString().equals("")) {
a = Integer.parseInt(first.getText().toString());
}
else {
a = 0;
}
if (!second.getText().toString().equals("")) {
b = Integer.parseInt(gpa_credits1.getText().toString());
}
else {
b = 0;
}
int sum = a + b; }catch (Exception e) {}
now, i would like to create a new activity to use the variable "sum" to do some math like...
public class first_year_second_semester extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newActivity);
int blah = 5;
private TextView soln;
soln = (TextView) findViewById(R.id.the_soln);
soln = (blah / sum) //i.e sum from the previous activity...please i need this
}
You can pass the value from one to other activity using intent or using shared preferences.
Intent intent=new Intent(MainActivity.this,year_second_semester.class);
intent.putExtras("sum",sum);
startActivity(intent);
Then in next activity you can get this value.
Or using shared preferences:
Inside class:
SharedPreferences shared;
Inside onCreate:
shared=getSharedPreferences("app",Context.MODE_PRIVATE);
After computing the sum I.e. after doing sum=a+b;
Editor edit=shared.edit();
edit.putString("sum",sum);
edit.commit();
And in the next activity:
Inside the class:
SharedPreferences shared;
Inside oncreate:
shared=getSharedPreferences("app",Context.MODE_PRIVATE);
Wherver you want:
String yourvalue=shared.getString("sum","default value");
Here your value will be the sum from the main activity.
Create a public static variable in your main activity (where the do math method is) like so:
public static int SUM;
Then in the do math function set that value to the one calculated.
int sum = a+b;
SUM = sum;
Then you can access it via:
MainActivity.SUM
Can anyone help me work out where I'm going wrong here. On the button click the media player plays one of the mfiles at random and I'm trying to set a textview depending on which file was played. Currently the setText if statements only match the audio playing half the time. Really not sure where I'm going wrong here.
private final int SOUND_CLIPS = 3;
private int mfile[] = new int[SOUND_CLIPS];
private Random rnd = new Random();
MediaPlayer mpButtonOne;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mfile[0] = R.raw.one;
mfile[1] = R.raw.two;
mfile[2] = R.raw.three;
//Button setup
Button bOne = (Button) findViewById(R.id.button1);
bOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, mfile[rnd.nextInt(SOUND_CLIPS)]);
if (mpButtonOne==null){
//display a Toast message here
return;
}
mpButtonOne.start();
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[0]){
textOne.setText("one");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[1]){
textOne.setText("two");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[2]){
textOne.setText("three");
}
mpButtonOne.setOnCompletionListener(new soundListener1());
{
}
So just to clarify the problem I am having is that the setText only matches the audio occasionally, not on every click. The rest of the time it displays the wrong text for the wrong audio.
You are choosing another random file
mfile[rnd.nextInt(SOUND_CLIPS)]
set that to a variable in onClick() then check against that variable in your if statement
public void onClick(View v) {
int song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);
if (song == mfile[0]){
textOne.setText("one");
}
Edit
To make it a member variable so you can use it anywhere in the class, just declare it outside of a method. Usually do this before onCreate() just so all member variables are in the same place and it makes your code more readable/manageable.
public class SomeClass extends Activity
{
int song;
public void onCreate()
{
// your code
}
then you can just initialize it in your onClick()
public void onClick(View v) {
song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);