I have a game activity and using an sqlite database I populate some buttons, randomly without repetition, and when the game gets finished I popup an alert dialog with OK button an some info. Now, I need when I press OK, to close that popup and in that game activity reload some other data to my buttons, without repetition. This I need to happen twice. I do this in my other game but that popup does not have OK button, it pops up for 3 seconds and using handler closes and my activity reloads with new data without repetition, and that works like a charm. In this game, only OK button is a difference, and it does not work. And I need that OK button. Two problems I have with this.
I successfuly reload my activity but with repetition, which tells me that my activity loads from scratch.
When the activity loads for the second time, when I press back button I can see previous game activity, which again tells me that I get one activity loaded twice. I only need it once with new data every time.
Also, my counter does not work, cause after second load, I get 3rd, 4th and so on.
Here are my game and popup activity:
public class ToploHladno extends Activity implements View.OnClickListener{
Button b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, bIzlaz, bDalje;
String mButtonText1, mButtonText2, mButtonText3, mButtonText4, mButtonText5, mButtonText6,
mButtonText7, mButtonText8, mButtonText9, mButtonText10, opis, odgovorNormalized;
MediaPlayer buttonClicks, buttonFinal, buttonBack;
public boolean music;
final Context context = this;
Editable ukucanRezultat;
String tacanRezultat, ukucanRezultatVelikaSlova;
int brojPoena;
int counter = 0;
LinkedList<Long> mAnsweredQuestions = new LinkedList<Long>();
private String generateWhereClause(){
StringBuilder result = new StringBuilder();
for (Long l : mAnsweredQuestions){
result.append(" AND _ID <> " + l);
}
return result.toString();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
addListenerOnButton();
nextQuestion();
}
private void addListenerOnButton() {
b1 = (Button) findViewById(R.id.button1);
b2 = (Button) findViewById(R.id.button2);
b3 = (Button) findViewById(R.id.button3);
b4 = (Button) findViewById(R.id.button4);
bIzlaz = (Button) findViewById(R.id.bIzlaz);
bDalje = (Button) findViewById(R.id.bDalje);
}
public void nextQuestion() {
counter++;
TestAdapter mDbHelper = new TestAdapter(this);
mDbHelper.createDatabase();
try{
mDbHelper.open();
Cursor c = mDbHelper.getTestData(generateWhereClause());
mAnsweredQuestions.add(c.getLong(0));
mButtonText1 = c.getString(2);
mButtonText2 = c.getString(3);
mButtonText3 = c.getString(4);
mButtonText4 = c.getString(5);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
b4.setOnClickListener(this);
if(counter < 3){
b1.setText("30 poena");
b2.setText("25 poena");
b3.setText("22 poena");
b4.setText("20 poena");
}else{
finish();
}
}
finally{
mDbHelper.close();
}
}
Popup:
public class Popup_opis extends Activity implements OnClickListener{
TextView tvOpis;
int brojPoenaPrimljeno;
Button OK;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.popup_opis);
initVariables();
}
private void initVariables() {
OK = (Button) findViewById(R.id.bOK);
tvOpis = (TextView) findViewById(R.id.tvOpis);
OK.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
finish();
Intent intent = new Intent(Popup_opis.this, ToploHladno.class);
//intent.putExtra("myMethod", "nextQuestion"); //I tried also this
startActivity(intent);
}
});
}
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
If I understand you correctly, you are restarting your ToploHladno Activity from your Popup_opis Activity using an Intent. If the ToploHladno Activity hasn't been finished, which I don't think it has been, then no need for Intent. You can call invalidate() on the Views that you want to be repopulated in onResume() after calling setText() on them or whatever changes you need to make to those Views
#Override
public void onResume()
{
// change your Buttons however you need in here then say you have btn1
btn1.invalidate();
}
Your first Activity isn't being finished so you don't need or probably even want to start it with an Intent. You will just return to it after closing your Dialog Activity and onResume() will be called so you can do what you need in there. This will keep you from redrawing the whole Layout by not creating a new instance of your Activity.Let me know if this works for what you need or not
Invalidate
startActivityForResult() example:
Intent intent = new Intent(ToploHladno .this, Popup_opis .class);
intent.putExtra("counter", counter);
startActivityForResult( intent, 0 ); //second param is a request code. You will need this later
then in pop up activity
public class Popup_opis extends Activity implements OnClickListener{
TextView tvOpis;
int brojPoenaPrimljeno;
Button OK;
int counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.popup_opis);
//Get intent
Intent recIntent = getIntent();
counter = recIntent.getIntExtra("counter"); //get counter variable from previous activity
OK.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
counter++;
Intent intent = new Intent(Popup_opis.this, ToploHladno.class);
intent.putExtra("counter", counter); //SEND BACK COUNTER
setResult(RESULT_OK, intent); // send result
finish();
then in your previous activity
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
// would use REQUEST CODE sent earlier if more than one activity sends back intents here
if (resultCode == RESULT_OK)
{
counter = data.getInteExtra("counter", 0); // get updated counter variable
}
}
More about startActivityForResult in Docs
Related
I want to let users choose background colors with animation in BackgroundActivity and saving that changed background color into MainActivity.
When a user clicks backgroundChange button on MainActivity, it moves to BackgroundActivity. Then there are a few different colors to choose. After a user click Save button after choosing color on BackgroundActivity, it is going back to MainAcitivity. My problem is I don't know how to save that changed background color from BackgroundAcivity to MainAcivity.
As a beginner, I cannot understand well how to use SharedPreferences.
I checked several videos and searching many questions for hours about it, but still, I cannot figure out how to use SharedPreferences correctly on my own code.
BackgroundAcivity is really long that I will only put the first part. Could you tell me how to save this background change?
MainActivity
public class MainActivity extends AppCompatActivity {
Button backgroundChange;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
backgroundChange = findViewById(R.id.backgroundChange);
backgroundChange.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, BackgroundActivity.class);
startActivity(intent);
}
});
}
}
BackgroundActivity
public class BackgroundActivity extends AppCompatActivity {
Button btn_blue, btn_purple, btn_orange, btn_save;
View holderBg, dynamicBg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_background);
btn_save = findViewById(R.id.btn_save);
btn_save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(BackgroundActivity.this, MainActivity.class);
startActivity(intent);
}
});
btn_blue = findViewById(R.id.btn_blue);
btn_purple = findViewById(R.id.btn_purple);
btn_orange = findViewById(R.id.btn_orange);
holderBg = findViewById(R.id.holderBg);
dynamicBg = findViewById(R.id.dynamicBg);
//set the first-time background
holderBg.setBackgroundResource(R.drawable.bg_blue);
holderBg.setScaleY(3);
holderBg.setScaleX(3);
//set the scale of button clicked
btn_blue.setScaleY(1.5f);
btn_blue.setScaleX(1.5f);
btn_blue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//scale animation
btn_blue.animate().translationY(20).scaleX(1.5f).scaleY(1.5f).setDuration(800).start();
//default the scale buttons
btn_purple.animate().translationY(0).scaleX(1).scaleY(1).setDuration(350).start();
btn_orange.animate().translationY(0).scaleX(1).scaleY(1).setDuration(350).start();
//change the background
dynamicBg.animate().scaleX(3).scaleY(3).setDuration(800).start();
dynamicBg.setBackgroundResource(R.drawable.bg_blue);
//change color of button
btn_save.setTextColor(Color.parseColor("#3498db"));
//timer for change the holderbg
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
holderBg.setScaleX(3);
holderBg.setScaleY(3);
holderBg.setBackgroundResource(R.drawable.bg_blue);
dynamicBg.setScaleX(0);
dynamicBg.setScaleY(0);
}
}, 850);
}
});
}
}
You can use a bundle to transfer your data across Activity.
Saving data
Intent intent = new Intent(context, YourActivity.class);
intent.putExtra(KEY, "your value here");
startActivity(intent);
Then to retrieve data.
Intent intent = getIntent();
if (intent != null ) { //Null Checking
String strData= intent.getStringExtra(KEY);
// do your work with `strData`
}
Sorry if this is poor etiquette but I have now re-written my entire question as the original question I asked didn't actually relate to my problem as I have just realised. I am having trouble updating the code in an activity after I return to it. The first activity contains a bunch of imageButtons which relate to levels. When the app is first run only the level one button is enabled. When that button is clicked it sends the user to a new activity where they must spell a set amount of words to unlock the next level. This is the code for my level select activity.
public class QuizLevelSelect extends AppCompatActivity {
private static int myLevel;
ImageButton level1, level2, level3, level4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_level_select);
TextView title = (TextView) findViewById(R.id.title);
Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/variane-script.regular.ttf");
title.setTypeface(custom_font);
level1 = (ImageButton)findViewById(R.id.level1);
level2 = (ImageButton)findViewById(R.id.level2);
level2.setEnabled(false);
level3 = (ImageButton)findViewById(R.id.level3);
level3.setEnabled(false);
level4 = (ImageButton)findViewById(R.id.level4);
level4.setEnabled(false);
level1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 1);
startActivity(i);
finish();
}
});
level2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 2);
startActivity(i);
finish();
}
});
level3.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 3);
startActivity(i);
}
});
}
#Override
protected void onResume(){
super.onResume();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Wordbank");
query.whereEqualTo("username", ParseUser.getCurrentUser().getUsername());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
for (ParseObject object : objects){
myLevel = object.getInt("level");
}
});
if (myLevel == 2){
level2.setEnabled(true);
}
}
}
When the level one button is clicked it starts a new activity where the user has to spell a set amount of words (only 1 at the moment, for testing purposes), when the user has spelled the required words it is supposed to send them back to the level select activity and unlock the level 2 button. This is the code for the second activity that checks they have spelled the words and then updates the level they are at on Parse.com before returning them to the level select activity.
if (count == 1){
ParseQuery<ParseObject> query2 = ParseQuery.getQuery("Wordbank");
query2.whereEqualTo("username", ParseUser.getCurrentUser().getUsername());
query2.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
objects.get(0).put("level", ++intValue);
objects.get(0).saveInBackground();
Intent i = new Intent(getApplicationContext(), QuizLevelSelect.class);
startActivity(i);
finish();
}
}
});
}
All of this works fine except when the user returns to the level select activity, the level 2 button does not become enabled, however if I press back on my phone and then go back into the level select activity it does become enabled. I am assuming this is because when the second activity returns the user to the level select activity the onResume() method is not being run, I have also tried onStart() and onRestart() but neither worked. I know it has something to do with the life cycle of my activities but I dont understand why I have to back out of the activity and then go back into it for the onResume method to run, I thought it ran everytime regardless.
Further to my previous post, I now want to invoke a child activity from the main activity a number of times. In my real project (as opposed to the noddy test below), when the child activity is invoked, its header displays, "Enter first data set" then invites the user to enter some data. This data is actually stored in a common class rather than being returned to the main activity. Then the child needs to be called again with a new prompt "Enter second data set", and the same thing happens.
What I cannot work out is how to do this. If I include two calls to the child, every time, only the second call appears to happen, the prompt appearing in the child activity being "Enter second data set" every time. This startActivityForResult() method is I believe, designed to be used when you want to call an activity and wait for the result (which you do with an onActivityResult() do you not), but it does not wait.
How on earth do I do this? Sample code follows.
Thank you to anyone who can clearly explain where I'm going wrong and what the right code should be.
MainActivity code extract
#Override
public void onResume(){
super.onResume();
TextView maintop = (TextView)findViewById(R.id.maintop);
maintop.setText(Common.mess1);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mainbutton = (Button)findViewById(R.id.mainbutton);
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent1 = new Intent(MainActivity.this,Child.class);
intent1.putExtra("Prompt", "Enter first data set");
startActivityForResult(intent1,1);
onActivityResult(1,1,intent1);
}
});
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent2 = new Intent(MainActivity.this,Child.class);
intent2.putExtra("Prompt", "Enter second data set");
startActivityForResult(intent2,1);
onActivityResult(1,1,intent2);
}
});
}
You can only have one click listener in the button, so when you call set for the 2nd time it replaces the listener.
What you need to do is set the click listener for the enter first data, don't call to onActivityResult(1,1,intent1) that's not how you do it, you need override the method, and in onActivityResult call the 2nd.
Something like this:
static final int FIRST_INTENT = 1;
static final int SECOND_INTENT = 2;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mainbutton = (Button)findViewById(R.id.mainbutton);
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent1 = new Intent(MainActivity.this,Child.class);
intent1.putExtra("Prompt", "Enter first data set");
startActivityForResult(intent1,FIRST_INTENT);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FIRST_INTENT) {
if (resultCode == RESULT_OK) {
Intent intent2 = new Intent(MainActivity.this,Child.class);
intent2.putExtra("Prompt", "Enter second data set");
startActivityForResult(intent2,SECOND_INTENT);
}
}
}
And in your child activity
//DO SOMETHING
....
setResult(RESULT_OK)
finish();
}
For more check
[http://developer.android.com/intl/es/training/basics/intents/result.html]
[http://developer.android.com/intl/es/reference/android/app/Activity.html#setResult%28int%29]
hey every one i am sorry but i have to ask this question, it seems like a very easy issue but i just stuck! i have spent the last 2 hours going through the form and android developer resource site and i cant find the problem with my code.
first of all the startActivityForResult() will not send me the text back.
second every time i click on the Implicit Activation button the app crashes.
here is the main activity file:
public class ActivityLoaderActivity extends Activity {
static private final int GET_TEXT_REQUEST_CODE = 1;
static private final String URL = "http://www.google.com";
static private final String TAG = "Lab-Intents";
// For use with app chooser
static private final String CHOOSER_TEXT = "Load " + URL + " with:";
// TextView that displays user-entered text from ExplicitlyLoadedActivity runs
private TextView mUserTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loader_activity);
// Get reference to the textView
mUserTextView = (TextView) findViewById(R.id.textView1);
// Declare and setup Explicit Activation button
Button explicitActivationButton = (Button) findViewById(R.id.explicit_activation_button);
explicitActivationButton.setOnClickListener(new OnClickListener() {
// Call startExplicitActivation() when pressed
#Override
public void onClick(View v) {
startExplicitActivation();
}
});
// Declare and setup Implicit Activation button
Button implicitActivationButton = (Button) findViewById(R.id.implicit_activation_button);
implicitActivationButton.setOnClickListener(new OnClickListener() {
// Call startImplicitActivation() when pressed
#Override
public void onClick(View v) {
startImplicitActivation();
}
});
}
// Start the ExplicitlyLoadedActivity
private void startExplicitActivation() {
Log.i(TAG,"Entered startExplicitActivation()");
// TODO - Create a new intent to launch the ExplicitlyLoadedActivity class
Intent explicitIntent = new Intent (ActivityLoaderActivity.this, ExplicitlyLoadedActivity.class);
// TODO - Start an Activity using that intent and the request code defined above
startActivityForResult(explicitIntent, GET_TEXT_REQUEST_CODE);
}
// Start a Browser Activity to view a web page or its URL
private void startImplicitActivation() {
Log.i(TAG, "Entered startImplicitActivation()");
// TODO - Create a base intent for viewing a URL
// (HINT: second parameter uses Uri.parse())
Intent baseIntent = new Intent (Intent.ACTION_VIEW, Uri.parse(URL));
// TODO - Create a chooser intent, for choosing which Activity
// will carry out the baseIntent
// (HINT: Use the Intent class' createChooser() method)
Intent chooserIntent = null;
chooserIntent.createChooser(baseIntent, CHOOSER_TEXT);
Log.i(TAG,"Chooser Intent Action:" + chooserIntent.getAction());
// TODO - Start the chooser Activity, using the chooser intent
startActivity(chooserIntent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "Entered onActivityResult()");
// TODO - Process the result only if this method received both a
// RESULT_OK result code and a recognized request code
// If so, update the Textview showing the user-entered text.
if (resultCode == RESULT_OK){
mUserTextView.setText(data.getStringExtra("resulttext"));
}}}
and here is the explicit intent file:
public class ExplicitlyLoadedActivity extends Activity {
static private final String TAG = "Lab-Intents";
private EditText mEditText;
String resulttext="still waiting";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.explicitly_loaded_activity);
// Get a reference to the EditText field
mEditText = (EditText) findViewById(R.id.editText);
// Declare and setup "Enter" button
Button enterButton = (Button) findViewById(R.id.enter_button);
enterButton.setOnClickListener(new OnClickListener() {
// Call enterClicked() when pressed
#Override
public void onClick(View v) {
enterClicked();
}
});
}
// Sets result to send back to calling Activity and finishes
private void enterClicked() {
Log.i(TAG,"Entered enterClicked()");
// TODO - Save user provided input from the EditText field
resulttext= mEditText.getText().toString();
// TODO - Create a new intent and save the input from the EditText field as an extra
Intent returntrip = new Intent ();
returntrip.putExtra("wayback", resulttext);
// TODO - Set Activity's result with result code RESULT_OK
setResult(RESULT_OK, returntrip);
// TODO - Finish the Activity
finish();
}
}
thank you guys so much i know i am a bother!
You are sending an extra data called "wayback" not "resulttext"
returntrip.putExtra("wayback", resulttext);
this will fix your code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "Entered onActivityResult()");
if (resultCode == RESULT_OK){
mUserTextView.setText(data.getStringExtra("wayback"));
}
Well, you won't get the result back correct from your onActivityResult because you are not using the correct key. You look inside for data.getStringExtra("resulttext") but you originally set the key as "wayback". You need to grab with that key.
Hi so even though I have seen a couple of topics about linking activities or returning I can not get my return back to activity to work. I abit of back ground the the app when the user gets an answer wrong or runs out of time it goes to game over taking the score across with it and displaying it on the game over, here's the working code for that if it helps solve my issue:
Main Class:
public void fail(){
{
Intent myIntent = new Intent(MainActivity.this,gameover.class);
myIntent.putExtra("number", score);
MainActivity.this.startActivity(myIntent);
finish();
}
gameover class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover);
re_run = (Button) findViewById(R.id.retry);
EndScore = (TextView) findViewById(R.id.show);
int getVal;
getVal = getIntent().getExtras().getInt("number");
String s = String.valueOf( getVal );
EndScore.setText(s);
}
Now the reason I shared the above working code because I have the feeling the intent that takes the user and score to the gameover screen, is messing with the retry/return code as shown below:
private void setButtonOnClickListeners(){
re_run.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
Intent retry = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(retry);
}
});
}
From what I can find from those topics these seems to be the correct method. but when the code is run the re_run button does nothing. Any help?
You use "setButtonOnClickListeners()" to implement setOnClickListener and so override the onClick. But when did you call setButtonOnClickListeners?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover); re_run = (Button)
findViewById(R.id.retry);
EndScore = (TextView) findViewById(R.id.show);
int getVal;
getVal = getIntent().getExtras().getInt("number");
String s = String.valueOf( getVal );
EndScore.setText(s);
setButtonOnClickListeners();
}
You can maybe check that your OnClick is working correctly adding a log line in LogCat. Log.d("GameOver", "Retry onclick ok");
You are finding a view before it was inflated (R.id.retry).
Change the sequence of commands to:
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover);
re_run = (Button) findViewById(R.id.retry);
Also try changing the intent to:
Intent retry = new Intent(GameOver.this, MainActivity.class);
retry.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
I personally used startActivityForResult(Intent) to start the game over screen, and once the player inputted his name or pressed something or quit the activity with Back, then it returned a value to onActivityResult(..) in which I called finish().
EDIT:
Game ends, so I started activity using
Intent i = new Intent();
i.putExtra("Score", scoreCount);
i.setClass(context, HighScoreInputActivity.class);
context.startActivityForResult(i, 0);
Then when you insert the scores and stuff, you close the game screen in GameActivity with
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
this.finish();
}