How to use a variable across multiple classes in java? - java

I am trying to create my first app in android studio, on the main screen there are three tick boxes asking the user which number of sides they want on the dice. I have a variable called sides which is set to 6,8 or 12 depending on which tick box the user ticks. I want the variable "sides" on the second activity so it can be used to generate a random integer between one and whatever "sides" is set to.

In first activity Lets assume that you have button GO . When You clicks on Button GO it should start Second Activity say Activity2.
Add following code to onClick of GO Button
Intent act2=new Intent(this,Activity2.class);//"this" is activity reference
act2.putExtra("key",value);
startActivity(act2);
Now in the onCreate method of Activity2 you can retrieve value of key as follows:
Int key=getIntent().getIntExtra("key",0);//0 is default value
In the same way as done above you can pass value of "side" variable to next activity

You can also save it in the Internal Storage and load it when you need, it is very useful because that way you can load it in every activity and every class you want.
you can learn how here.
I recommend watching all three parts.

Easiest way is to use singleton classes.
public class DataHolder {
public int sides = 0;
private static DataHolder dataHolder = new DataHolder();
public static DataHolder getInstance()
{
return dataHolder;
}
}
DataHolder.getInstance().sides=sideInActivityA;
you can access the variable by using
int sideInActivityB = DataHolder.getInstance().sides;

Related

Passing values between several activities

I've an issue with passing a variable back to the first activity.
My app starts with one activity, which opens a second one, which opens an third one, which opens a forth, which opens the first activity again.
Now I want to get a variable, which I get from a user input in the third activity in my first one. I already managed to pass variables between two activities there and back with onActivityResult() but I do not get how to manage this between more than two activities.
use bundle
you can use Bundle for move the value from first activity to second activity
check this link ---> [here] (Passing a Bundle on startActivity()?)
if use value in several activity you can use SharePrefrence or you can make
class extends Application and make value in the class and use the values in several activity
be careful if close the app destroy the values
You can use shared preferences to access variables in all your activities or use can use this method:
When going from fourth activity to first use startActivity(intent) and add the variable as an extra in intent. And in first activity override onBackPressed. This may not be good practice but it works.

How to check if an app is being opened - Android Studio

I'm making a game and am saving data for the player using sharedPreferences. The way I have it set up right now, every time the main application (the first page) is loaded, the old data it held before is loaded. So, imagine a player has 100$, and they exit the app. Upon opening the app again, this data will be loaded and everything seems fine.
The problem, however, is that if a player's money is changed in ANOTHER activity, the way I have it set up right now is that any time a player navigates back to the main activity, the data is loaded. So if the player has $100 on the main activity, this info is saved every few seconds on the main activity. If the player spends 50$ on a second activity, when they return to the main activity, since the last saved data the main activity has is $100, it will load the $100.
This is a problem, and a way to fix it is to ONLY LOAD THE DATA WHEN THE APP IS OPENED. So like I don't want to load the data every time the player navigates to the main activity, but only when they open the app. I need a simple if() boolean statement to do this, but I'm not sure what the statement I need is.
Thanks!
Store a boolean in sharedPreferences and check if it exists or if it's false/true in the create of the activity, such as storing a value for "hasLoaded" with a value of either true or false. check this value in onCreate and then do your logic accordingly.
OR alternatively,
create a static variable in your mainActivity for hasLoaded, then in onCreate, do everything you want to do and then change it to true.
static boolean hasLoaded = false;
if(!hasLoaded){
//all your logic here
hasLoaded = true;
}
note:
storing it in sharedPrefs will ensure that your initialization will only happen ONCE for all usages of the app, while storing it in a static variable will make sure it only happens once PER RUN of the app

(Android) How do I update the displayed contents of a TableLayout in response to an event?

I am trying to learn Android app programming by building an app to keep score in Hearts. The data for the game itself is arranged in the following hierarchy:
Game represents the whole game
Vector of Round objects representing each hand in the game.
Vector of BoxScore objects representing each box score in a hand.
This data is presented in a ScoreTableActivity by a TableLayout, where each TableRow contains a marker cell, a cell for each BoxScore object, and a cell which indicates whether the hand's total score is correct. The final row of the table shows each player's total score, by adding up the box scores in each column.
I have a method drawScoreTable() which is called during the activity's onCreate() method, and it is working as expected. While creating the cells for box scores, I have the following to catch clicks on those cells:
TextView txtScore = ScoreTableCellFactory.getBoxScoreCell( this, oScore ) ;
txtScore.setOnClickListener(this) ;
rowRound.addView( txtScore ) ; // rowRound is a TableRow.
The ScoreTableActivity itself implements OnClickListener in order to support this; only the box scores are clickable. The activity's onClick() method is as follows:
public void onClick( View oClicked )
{
// A reference to the score object is built into the view's tag.
BoxScore oScore = (BoxScore)oClicked.getTag() ;
// Create the dialog where the user modifies the box score.
BoxScoreEditorDialogFragment fragBoxScoreDialog = new BoxScoreEditorDialogFragment() ;
fragBoxScoreDialog.setBoxScore(oScore) ;
fragBoxScoreDialog.setRules(m_oGame.getRules()) ;
fragBoxScoreDialog.show(getFragmentManager(), "fragBoxScore") ;
// We passed the BoxScore object across to the editor dialog by
// reference (It's Java, after all), so we should be able to
// update the text of the box score cell by simply re-examining
// the data in that BoxScore object.
((TextView)oClicked).setText(Integer.toString(oScore.getScore())) ;
// And it's at this point that something else is clearly needed.
}
Other answers on this site have suggested that the setText() method is enough to convince the renderer to refresh the cell, but it is not. With the code as it is above, the cell is not refreshed until the next time that the cell is clicked.
I have tried using the invalidate() method on the cell itself, its parent row, and the entire TableLayout, but none of these had any effect. I even tried using the removeAllViews() method and then calling drawScoreTable() again; even that didn't update the screen until after the next click event was caught.
If I tilt the tablet to a new orientation (from portrait to landscape or vice versa) then the entire activity is recreated and the new table shows all the correct data. I would rather not resort to completely destroying and rebuilding the whole table but I thought that's what I was doing with removeAllViews() and even that didn't work.
EDIT: Forceful solution found.
Part of the problem stems from the fact that the data update comes from the dialog. This is a separate arena from the basic activity, so the dialog needs to trigger something when it exits.
My code is a bit more specialized but I've created a general example below to give you a context-free idea of what's going on. It's actually based on the official Android reference for "Dialogs", which I unfortunately read only after posting this question.
Step 1: Create a custom listener class for the dialog.
/**
* Callers of this dialog must implement this interface to catch the events
* that are returned from it.
*/
public interface Listener
{
public void onDialogCommit( MyDialogClass fragDialog ) ;
}
Step 2: Implement the listener in your base activity.
At the head of your main activity class:
public class MyBaseActivity
extends Activity
implements OnClickListener, MyDialogClass.Listener
I've kept the OnClickListener here because my code also catches the clicks that trigger the dialog's creation. If you handle this with inline inner classes, then you don't need the OnClickListener in your implements clause.
Step 3: Implement the listener's interface in your base activity.
This is the part that's left out of the official Android example -- What do you do put into this listener method? Well, the answer is surprisingly awful.
public void onDialogCommit( MyDialogClass oDialog )
{
TableLayout oLayout = (TableLayout)(findViewById(R.id.tbl_MyTableLayout)) ;
// This is where things still seem more ugly than they should.
oLayout.removeAllViews() ;
this.recreateEverything() ; // assumes you've written a method for this
}
Surprises
Even after creating this new interface-and-listener model, using the invalidate() and requestLayout() methods still wasn't enough. I had to removeAllViews() and recall the method that redraws the whole activity. I still believe that, surely, there's a more efficient way of doing this, but I haven't yet found it.

Making Layouts visible/invisible with Button

At the moment I am working on a project for a graphical user interface on an Android tablet. On one screen I have several buttons, which I want to make a RelativeLayout visible/invisible with.
I tried using an onClickListener, but in the inner method onClick doesn't support non final variables, which I use to select each button and RelativeLayout.
The GUI is built dynamically, as its whole structure depends on the data it gets fed via an XML file. Also the RelativeLayout uses TextViews which receive an update of their textes (sensordata like temperature and humidity), which is why a dynamic approach is used.
Could you give me some ideas for a workaround around that problem? Help is appreciated. If the stated information is not enough for you, just ask and I will give you more details.
At the moment I tried this:
private void setSensorPointOnClick(final ObjectView currentObjectView, final String currentLinkName)
{
for(int i=0; i<listofSensorDeviceButtons.size(); i++ )
{
listofSensorDeviceButtons.get(i).setOnClickListener(
new View.OnClickListener()
{
public void onClick(View v)
{
arrayClickedButton[i] = listofSensorDeviceButtons.get(i);
mainFrameLayout.removeAllViews();
stepToObject(currentObjectView, currentObjectView.getName());
}
}
);
}
}
either use fields which hold the views that you want to hide/show (and use them in the onClickListener) , or use findViewById within the event handling .
another alternative would be to create another view variable which is final , that will be set just before setting the onClickListener , to hold the reference of the newly created view .
so , in short , the possible solutions i wrote are:
use fields .
use findViewById
use an additional final variable .

Moving String and Image between Activity Android Application

I've to develop an application that allows user to browse picture and write some information
about him, all these information will stored in a class with Person name,
After he presses NextButton the activiy should moves him to another activity with these information in the second activity he'll type another information about him,
well in the 3rd activity I should receive all these info. from ( 1st and 2nd ) activities then, showing it in the 3rd one ,,
my Questions are:
1- How can move more than one info. I write a code that moves string and other code to move picture, but I couldn't combine them with each other!
2- How can I insert the information that will be typed in the second activity to the same object of Person Class ??
Hope my Questions and my scenario is clear!!
thanks alot
Shomokh =)
-----------------------Updating----------------------------------------
// this is for String info
String FullPersonInfo = person1.toString();
Bundle basket = new Bundle();
basket.putString("key", FullPersonInfo);
Intent intent = new Intent(Form_1.this,Form_2.class);
intent.putExtras(basket);
startActivity(intent);
// I'm confusing how can I add image when i try this code it doesn't work
intent.putExtra("URI", selectedImageUri.toString() );
You can pass in extra information in the intent you are passing in to the next activity and then read the intent using intent.getExtra in the 2nd and 3rd activity. I hope that gives you better idea.
As omkar.ghaisas aluded to above you can pass extras to an Intent. However, you can only pass primitives OR any object which implements the Parcelable interface. Passing string is easy enough but the image data is trickier.
I think you have a couple of options:
Write the image path to disk and then pass the file location as a
string using the Extras in the Intent, plus any other strings you
need, e.g. other metadata
Grab the image as a byte[] array, create a class which implements
Parceleable and shuffle the byte[] around.
I think #1 is probably easier.
you can Create Parcelable object of your class that content all information whcih u want to move from one activity to another.use Bundle.putParcelable and extract all class object in another Activity.
for passing Parcelable custom or complex object between activites see:
Passing a list of objects between Activities
http://prasanta-paul.blogspot.in/2010/06/android-parcelable-example.html
Android: Passing object from one activity to another
and as your application requirement but do't pass whole image in bundle just pass a reference path and text to another activity and retrieve image from path

Categories