I want to update TextView from another class which is not an activity, but the app keeps crushing..
I hope you can help
This is the class where I want to update text after knowing game result
public class GameLogic {
...
public void gameResult() {
OnePlayerGameActivity gameActivity = new OnePlayerGameActivity();
TextView result = (TextView) gameActivity.findViewById(R.id.game_result_textView);
getPlayerChoice();
int computer = computerChoice();
if (mPlayerChoice == computer) {
mPlayerStat += 0;
mOpponentChoice += 0;
} else if (mPlayerChoice == 1) { //ROCK
switch (computer) {
case 1: //ROCK
break;
case 2: //PAPER
mOpponentStat ++;
result.setText("LOST");
break;
...
all code can be found on my GitHub
You are creating just a dummy instance of your activity which has no relation with the one in memory, instead pass the activity instance using
// in your OnePlayerGameActivity.java
// inside some method
GameLogic obj = new GameLogic (); // instance of GameLogic for demo
obj.gameResult(OnePlayerGameActivity.this); // pass instance
and change the methods signature as
public void gameResult(OnePlayerGameActivity gameActivity ) {
TextView result = (TextView) gameActivity.findViewById(R.id.game_result_textView);
Related
I am writing tic tac toe game in which i am calling imageTapped when image is tapped to change its image to cross and then it calling aiturn to find valid move and change its image to circle. Now my question is how did calling non static method aiturn from non static method imageTapped works without creating its object.
package com.example.kapil.tictactoe;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private GameLogic gameLogic;
LinearLayout linearLayout;
TextView label;
public void imageTapped (View view) {
ImageView image = (ImageView) view;
label = findViewById(R.id.label);
String pos = image.getTag().toString();
//if button is already tapped
if (! gameLogic.setImage(Integer.valueOf(pos)))
return;
image.setImageResource(R.drawable.cross);
//return 1 for win 2 for draw otherwise 0
int win = gameLogic.logic();
if (win == 1) {
label.setText("You Win!!");
gameLogic.gameOver();
return;
} else if (win == 2) {
label.setText("Game Draws!!");
return;
}
aiturn();
}
public void aiturn () {
int move = gameLogic.aiMove();//return best move between 0 to 8
int rowNum = move/3;
int colNum = move%3;
if (rowNum == 0) {
linearLayout = findViewById(R.id.line1);
} else if (rowNum == 1) {
linearLayout = findViewById(R.id.line2);
} else if (rowNum == 2) {
linearLayout = findViewById(R.id.line3);
}
((ImageView) linearLayout.getChildAt(colNum)).setImageResource(R.drawable.circle);
label = findViewById(R.id.label);
//return 1 for win 2 for draw otherwise 0
int win = gameLogic.logic();
if (win == 1) {
label.setText("AI wins!!");
gameLogic.gameOver();
} else if (win == 2) {
label.setText("Game Draws!!");
}
}
//if play again button is pressed
public void Reset (View view) {
gameLogic.reset();
TextView label = findViewById(R.id.label);
label.setText("");
int ids[] = {R.id.line1,R.id.line2,R.id.line3};
for (int k=0;k<ids.length;k++) {
LinearLayout linearLayout = findViewById(ids[k]);
for (int i = 0; i < linearLayout.getChildCount(); i++) {
((ImageView) linearLayout.getChildAt(i)).setImageResource(R.mipmap.ic_launcher);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gameLogic = new GameLogic();
}
}
This works because the Android framework creates the instances of Activities.
Now my question is how did calling non static method aiturn from non static method imageTapped works without creating its object.
Android apps are not launched using a public static void main(...) method like a classic Java app.
Instead, when your app is launched, the Android framework automatically creates instances of your app's Activity classes, and wires them up to the user interface (as per the XML file).
Then, when the user "taps", the framework calls the imageTapped method on the (existing) activity object. That then calls aiturn on the same object.
Or at least, I think that is the intent of the person who wrote that code. In reality, the imageTapped method doesn't appear to be an API method in the superclass hierarchy of your MainActivity class. So I suspect that it won't be called.
I'm not sure what you are actually trying to do, but maybe you should override onTouchEvent(...)
Hi I have 2 lines each with a name textfield, 2 buttons and a textfield to show the amount. There will be more lines later.
I want 1 button to add 1 to the amount and the other to decrease the amount by 1.
But I don't know how to get the ID from the button I press. I have gotten this far.
I hope someone can let me know. How I can get the indexvalue depending on which button is pressed.
public class MainActivity extends AppCompatActivity {
private ArrayList<Integer> ButtonUp;
private ArrayList<Integer> Amount;
private ArrayList<Integer> ButtonDown;
int ArrayIndex = 0;
int Value = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButtonUp();
Amount();
ButtonDown();
}
// ArrayList ButtonUp
public void ButtonUp(){
ButtonUp.add(R.id.Bup1);
ButtonUp.add(R.id.Bup2);
}
// ArrayList Amount
public void Amount(){
Amount.add(R.id.Aantal1);
Amount.add(R.id.Aantal2);
}
// ArrayList ButtonDown
public void ButtonDown() {
ButtonDown.add(R.id.Bdown1);
ButtonDown.add(R.id.Bdown2);
}
// Get position ArrayList on press
// Publish new Value
public void buttonPress(View v) {
switch (v.getId()) {
case R.id.Bup1:
SetAmountUp(id);
displayQuantity(Value);
break;
case R.id.Bup2:
SetAmountUp(R.id.Bup2);
displayQuantity(Value);
break;
case R.id.Bdown1:
SetAmountDown(R.id.Bdown1);
displayQuantity(Value);
break;
case R.id.Bdown2:
SetAmountDown(R.id.Bdown1);
displayQuantity(Value);
break;
}
}
public void SetAmountUp(int indexNumberUp){
Value = Amount.get(ButtonUp.indexOf(indexNumberUp));
Value++;
Amount.set(ArrayIndex,Value);
}
public void SetAmountDown(int indexNumberDown){
Value = Amount.get(ButtonDown.indexOf(indexNumberDown));
Value--;
Amount.set(ArrayIndex,Value);
}
// Publish number
private void displayQuantity(int NewAmount) {
int ID = Amount.get(ArrayIndex);
TextView quantityTextView = (TextView) findViewById(ID);
quantityTextView.setText(NewAmount);
}
}
In the layout, declare an unique id to each button, then add android:onClick="increment" to each button.
In your class, create the method
public void increment(View view) {
switch (view.getId()){
case R.id.yourbuttonid1:
// do what you whant
break;
case R.id.yourbuttonid2:
// do with second editext
break
// ....
}
}
Same approach to decrease method.
It will be much easier for you if you used a recyclerView for that
When I get the value of the arraylist, I get size = 0. I boot the ArrayList in Class Screen1, but I can not get the value of the Class Screen2 cont.
public class Variables {
public Variables() {
}
private int cont = 0;
private int correct = 0;
public int getCont(){
return cont;
}
public void setCont(int cont){
this.cont = cont;
}
public int getCorrect(){
return correct;
}
public void setCorrect(int correct){
this.correct = correct;
}}
Class Screen1
public class Screen1 extends ActionBarActivity {
Variables variables = new Variables();
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
public int cont;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen1);
variables.setCorrect(1);
variables.setCont(1);
variablesArrayList.add(variables);
}
public void sendTela1(View view){
cont = variables.getCont();
cont++;
variablesArrayList.get(0).setCont(cont);
}
}
Class Screen 2
This class I'm trying to get the value of ArrayList
public class Screen2 extends ActionBarActivity {
Variables variables = new Variables();
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
int cont;
ImageView progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen2);
progressbar = (ImageView) findViewById(R.id.progressbar);
//this line, the arraylist is returning size = 0
cont = variablesArrayList.get(1);
switch (cont){
case 1:
progressbar.setImageResource(R.drawable.progressbar1);
break;
case 2:
progressbar.setImageResource(R.drawable.progressbar2);
break;
case 3:
progressbar.setImageResource(R.drawable.progressbar3);
break;
case 4:
progressbar.setImageResource(R.drawable.progressbar4);
break;
case 5:
progressbar.setImageResource(R.drawable.progressbar5);
break;
}}
You're getting a return size of 0 because in screen2 activity you are creating a new list when you do: ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
To fix this, you need to pass the arraylist you created in screen1 into screen2. You will have to implement parcelable, but that will allow you to pass the data using intents and bundles.
If you create a new object as you are doing in your screen2 with the line
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
you will of course receive an empty arrayList. There are multiple ways of sending data from one Activity to another. I suggest you look into bundles and using putExtras and later getExtras via Intents. However, since you have a model class why not use that?
In your model class add
private static ArrayList<Variables> variablesArrayList;
Now add some setters and getters to update and retrieve your list
// getter
public static ArrayList<Variables> getList() {
return variablesArrayList;
}
// setter
public static void setList(ArrayList<Variables> varArryList) {
this.variablesArrayList = varArryList;
}
Now on screen1 set your arrayList and in screen2 (or 3, or 4, or 5, ect) retrieve it! Cheers!
I have this app, it's basically a 'make fun' app I made with a person's face and the ability to either shoot it with a pistol, automatic rifle, or grenade (more weapons to come :-)).
I have a Weapon class, with the following code. (I'm pretty new to java so forgive me if I failed to follow proven ways, or do things as efficiently as I should)
public class Weapon {
// Parent
public static MainActivity ma;
// Constants
public static final int BULLET_WIDTH = 97;
public static final int BULLET_HEIGHT = 92;
public static final int EXPLOD_WIDTH = 299;
public static final int EXPLOD_HEIGHT = 237;
public static final int PISTOL = 0;
public static final int RIFLE = 1;
public static final int GRENADE = 2;
protected static int[] position = {0, 0};
protected static RelativeLayout rl = null;
protected static MediaPlayer mp;
// Protected stuff
// Object variables.
protected int type;
protected int drawableEffect;
protected int soundEffect;
// Functionals
protected ImageView effectImage;
public void equipWeapon() {
// Clear any existing listeners and assign a new one.
MainActivity.mainImage.setOnTouchListener(null);
MainActivity.mainImage.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Which weapon are we using?
switch (type) {
case Weapon.PISTOL:
case Weapon.GRENADE:
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Fire the weapon.
fireWeapon(v, event);
}
case Weapon.RIFLE:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE: // This doesn't work ???
// Fire the weapon.
fireWeapon(v, event);
}
}
// perfomClick needed.
return v.performClick();
}
});
}
public void fireWeapon(View v, MotionEvent event) {
// Reference the layout.
Weapon.rl = (RelativeLayout)Weapon.ma.findViewById(R.id.relativeLayout);
// Define properties.
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
// Get the touch position.
Weapon.position[0] = (int)event.getX() - ((type == Weapon.PISTOL || type == Weapon.RIFLE) ? Weapon.BULLET_WIDTH:Weapon.EXPLOD_WIDTH);
Weapon.position[1] = (int)event.getY() - ((type == Weapon.PISTOL || type == Weapon.RIFLE) ? Weapon.BULLET_HEIGHT:Weapon.EXPLOD_HEIGHT);
// Set the position.
lp.setMargins(Weapon.position[0], Weapon.position[1], 0, 0);
effectImage.setLayoutParams(lp);
// Add the view to the layout.
Weapon.rl.addView(effectImage, lp);
// Play the sound.
Weapon.mp.seekTo(0);
Weapon.mp.start();
// Reload
reload();
}
public void reload() {
// Create the ImageView
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
And I have a Pistol class which extends Weapon
public class Pistol extends Weapon {
public Pistol() {
// First save the type.
this.type = Weapon.PISTOL;
// Fetch the sound effect and image.
this.soundEffect = R.raw.gunshot;
this.drawableEffect = R.drawable.bullet_hole1;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = null;
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
As well as a Rifle class extending Weapon
public class Rifle extends Weapon {
public Rifle() {
// First save the type.
this.type = Weapon.RIFLE;
// Fetch the sound effect and image.
this.soundEffect = R.raw.gunshot;
this.drawableEffect = R.drawable.bullet_hole1;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = null;
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
finally, I have a Grenade class extending, yep you guessed it, Weapon as well.
public class Grenade extends Weapon {
public Grenade() {
// First save the type.
this.type = Weapon.GRENADE;
// Fetch the sound effect and image.
this.soundEffect = R.raw.grenade;
this.drawableEffect = R.drawable.boom;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
I have buttons in the main view which I have registered onClick listeners to so you can switch weapons to your liking.. Here is one for example:
grenadeButton = (ImageButton)findViewById(R.id.grenadeButton);
grenadeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (MainActivity.this.weapon != Weapon.GRENADE) {
// Change the background color.
resetButtons();
v.setBackgroundResource(R.drawable.background_selected);
// Change weapons.
MainActivity.this.currentWeapon = equipWeapon(Weapon.GRENADE);
}
}
});
and the equip weapon method in MainActivity.
public Weapon equipWeapon(int type) {
Weapon weapon = null;
switch (type) {
case Weapon.PISTOL:
weapon = new Pistol();
break;
case Weapon.RIFLE:
weapon = new Rifle();
break;
case Weapon.GRENADE:
weapon = new Grenade();
break;
}
// Play a sound and save changes.
MainActivity.this.weapon = type;
MainActivity.mp.seekTo(0);
MainActivity.mp.start();
return weapon;
}
Now, I appreciate you taking the time to review all this code. I know that's a lot to digest for what I'm assuming is a simple issue. I'm also aware of the rules of this forum and I have attempted to search for this issue already, but I'm not sure if I was using the right queries, as I did not find anything related to this issue.
Here we go:
When you start the app, the pistol is automatically equipped so you can start shooting immediately. It shoots fine, I get a bullet noise, and bullet holes all over the picture of the person's face ^_^. The rifle works fine as well (but it uses the same noise and graphic as the pistol, so it could very well be failing as well. Refer below).
When I switch to the grenade, I here a lovely explosion sound, but the image displayed is still a bullet hole and not an explosion.. I have no earthly idea how to fix this and I am stumped..
When I create the grenade object I specifically assign the drawable resource to the instance variable...
this.drawableEffect = R.drawable.boom;
Yet it still displays R.drawable.bullet_hole1....
Please let me know if you need more information and ask any questions you need to..
Thank you for your time..
I'm so stupid.....
MainActivity.equipWeapon
wasn't calling
Weapon.equipWeapon....
So the weapon wasn't changing... Oy' vey...
I have a single OnClickListener instance to direct clicks to multiple other handler methods, generally:
void onClick(View v) {
switch (v.getId()) {
case R.id.viewA:
handleButtonA();
break;
case R.id.viewB:
handleButtonB();
break;
default:
handleDefaultCondition();
break;
}
}
When I click view A, handleButtonA() is called. When I click view B, nothing happens. When I click any other view it calls handleDefaultCondition(). I had the same behavior with a series of if/else if statements, so I don't think the problem is related to my use of switch.
Here is the complete code:
public class MyClickListener implements View.OnClickListener {
public void onClick(View view) {
int viewId = view.getId();
switch (viewId) {
case R.id.time_frag_mark_button:
handleMarkButton(); //just calls dummy method with a Log statement inside for testing
break;
case R.id.finalize_entry_button:
handleFinalizeButton(); //just calls dummy method with a Log statement inside for testing
break;
default:
openTimePickerDialog(view.getId()); //just calls dummy method with a Log statement inside for testing
break;
}
}
}
And an excerpt from my R file:
public static final class id {
public static final int action_settings=0x7f08000e;
public static final int finalize_entry_button=0x7f08000d;
public static final int separator=0x7f080002;
public static final int time_frag_current_time=0x7f080003;
public static final int time_frag_date_string=0x7f080001;
public static final int time_frag_in_label=0x7f08000b;
public static final int time_frag_in_picker=0x7f08000c;
public static final int time_frag_mark_button=0x7f080004;
}
As requested, the code to initialize the listeners:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myClickListener = new MyClickListener();
myTimeFilter = new IntentFilter(Intent.ACTION_TIME_TICK);
myTimeTicker = new MyTimeTicker();
getApplicationContext().registerReceiver(myTimeTicker, myTimeFilter);
systemTime = (TextView) findViewById(R.id.time_frag_current_time);
systemTime.setText(sdf.format(new Date()));
systemDate = (TextView) findViewById(R.id.time_frag_date_string);
outTimeView = (TextView) findViewById(R.id.time_frag_out_picker);
outTimeView.setOnClickListener(myClickListener);
offTimeView = (TextView) findViewById(R.id.time_frag_off_picker);
offTimeView.setOnClickListener(myClickListener);
onTimeView = (TextView) findViewById(R.id.time_frag_on_picker);
onTimeView.setOnClickListener(myClickListener);
inTimeView = (TextView) findViewById(R.id.time_frag_in_picker);
inTimeView.setOnClickListener(myClickListener);
markButton = (Button) findViewById(R.id.time_frag_mark_button);
markButton.setOnClickListener(myClickListener);
//should error check this, only open a new one if one is not in progress
//need to start saving the Entry to disk during onPause() and move this check to onStart() or something
currentEntry = new LogEntry();
}
Have you tried looking to see what ID is output when you press the R.id.finalize_entry_button to see if it is what you expect?
Also, can you post the code that hooks up the OnClick handler to your controls?