I would like to make a game, if i press play button, random level (activity) will open. I got code for this: https://stackoverflow.com/a/29579373/13101103
This is working, but i would like to edit, example, all levels have 2 different answer, answer1 is fail, answer2 is pass the level, if user pass level1, and in level2 fail, than go back to mainactivity, and if start again, then the passed levels will not show again.
Example:
There are 5 levels, user start random level, example level3, it passed, go to next random level, example level2, it pass, go to next... level4, it failed, go back to mainactivity, user start again, but the already passed levels will not show, only unpassed... example start level3... if passed then go to level1....
How can i edit this code for my solution? Can somebody give me some tips? Because in this if i go back to mainactivity and start again, then it start with all levels... I tried to edit, but i'm stucked and not works...
Plus i would like to save progress when user leave the app. In sharedpreferences how can i save the passed levels (arraylist)....?
MainActivity:
enter code here
Button level1Button = findViewById(R.id.level1Button);
level1Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// We are creating a list, which will store the activities that haven't been opened yet
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(Level1Activity.class);
activityList.add(Level2Activity.class);
activityList.add(Level3Activity.class);
activityList.add(Level4Activity.class);
activityList.add(Level5Activity.class);
Random generator = new Random();
int number = generator.nextInt(5) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
activity = Level1Activity.class;
// We are adding the number of the activity to the list
activityList.remove(Level1Activity.class);
break;
case 2:
activity = Level2Activity.class;
activityList.remove(Level2Activity.class);
break;
case 3:
activity = Level3Activity.class;
activityList.remove(Level3Activity.class);
break;
case 4:
activity = Level4Activity.class;
activityList.remove(Level4Activity.class);
break;
default:
activity = Level5Activity.class;
activityList.remove(Level5Activity.class);
break;
}
// We use intents to start activities
Intent intent = new Intent(getBaseContext(), activity);
// `intent.putExtra(...)` is used to pass on extra information to the next activity
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
});
Level1Activity:
enter code here
failbutton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(Level1Activity.class);
Bundle extras = getIntent().getExtras();
activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");
//Class activity = null;
Intent intent = new Intent(Level1Activity.this, Main2Activity.class);
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
});
buttonlevel1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Class> activityList = new ArrayList<>();
Bundle extras = getIntent().getExtras();
activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");
if(activityList.size() == 0) {
// Do something when after all activities have been opened
//startActivity(new Intent(Level1Activity.this, Main2Activity.class));
//Intent intent = new Intent(Level1Activity.this, Main2Activity.class);
//intent.putExtra("ACTIVITY_LIST", activityList);
//startActivity(intent);
} else {
// Now, the random number is generated between 1 and however many
// activities we have remaining
Random generator = new Random();
int number = generator.nextInt(activityList.size()) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
// We will open the first remaining activity of the list
activity = activityList.get(0);
// We will now remove that activity from the list
activityList.remove(0);
break;
case 2:
// We will open the second remaining activity of the list
activity = activityList.get(1);
activityList.remove(1);
break;
case 3:
// We will open the third remaining activity of the list
activity = activityList.get(2);
activityList.remove(2);
break;
case 4:
// We will open the fourth remaining activity of the list
activity = activityList.get(3);
activityList.remove(3);
break;
default:
// We will open the fifth remaining activity of the list
activity = activityList.get(4);
activityList.remove(4);
break;
}
// Note: in the above, we might not have 3 remaining activities, for example,
// but it doesn't matter because that case wouldn't be called anyway,
// as we have already decided that the number would be between 1 and the number of
// activities left.
// Starting the activity, and passing on the remaining number of activities
// to the next one that is opened
Intent intent = new Intent(getBaseContext(), activity);
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
}
});
level2, level3.... is same just different id-s
I'd suggest using the Singleton pattern to handle passing data between activities.
You can pass the list by intent's putExtra() or by SharedPreferences but with a Singleton class, it looks much better and easier to manipulate your data because they are encapsulated. So much so in your situation where you want to save your levels' states (e.g. when they are already completed).
However, if you really insist on using SharedPreferences to save the list then I suggest converting it to Json by using Gson. (Check below my answer on how to implement this.)
As I said, I'd use the Singleton pattern to avoid creating unnecessary boilerplate code and to encapsulate the levels' states.
LevelManager class (the singleton)
final class LevelManager {
// constants
private static final String LEVELS_SHARED_PREFERENCES_NAME = "app_name.LEVELS";
// variables
private static LevelManager instance;
private List<Class> levels;
private SharedPreferences sharedPreferences;
private LevelManager(Context context) {
sharedPreferences =
context.getSharedPreferences(LEVELS_SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
levels = new ArrayList<>();
initializeList();
}
private void initializeList() {
// Initialize levels, ie. add levels that are not yet completed/passed
// Check in SharedPreferences if level has already been completed
boolean alreadyPassed;
alreadyPassed = sharedPreferences.getBoolean(Level1Activity.class.getSimpleName(), false);
if (!alreadyPassed) levels.add(Level1Activity.class);
alreadyPassed = sharedPreferences.getBoolean(Level2Activity.class.getSimpleName(), false);
if (!alreadyPassed) levels.add(Level2Activity.class);
alreadyPassed = sharedPreferences.getBoolean(Level3Activity.class.getSimpleName(), false);
if (!alreadyPassed) levels.add(Level3Activity.class);
alreadyPassed = sharedPreferences.getBoolean(Level4Activity.class.getSimpleName(), false);
if (!alreadyPassed) levels.add(Level4Activity.class);
alreadyPassed = sharedPreferences.getBoolean(Level5Activity.class.getSimpleName(), false);
if (!alreadyPassed) levels.add(Level5Activity.class);
}
static LevelManager getInstance(Context context) {
if (instance == null) {
instance = new LevelManager(context);
}
return instance;
}
Class getRandomLevel() {
if (levels.isEmpty()) {
return null; // Return null if all levels are already completed
}
Collections.shuffle(levels);
return levels.get(0);
}
void saveLevelState(Class levelClass, boolean passed) {
sharedPreferences.edit().putBoolean(levelClass.getSimpleName(), passed).apply();
if (passed) {
// Remove level from list if user passed it so that it won't
// be included in next levels
levels.remove(levelClass);
}
}
void reset() {
// Clears all entries in SharedPreferences and re-initialize list
sharedPreferences.edit().clear().apply();
initializeList();
}
}
Inside onCreate in MainActivity
// Get LevelManager singleton instance
final LevelManager levelManager = LevelManager.getInstance(this);
Button startButton = findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Get next random level
Class levelToStart = levelManager.getRandomLevel();
// If all levels are already completed
if (levelToStart == null) {
Toast.makeText(MainActivity.this, "All levels are completed!",
Toast.LENGTH_LONG).show();
return;
}
Intent intent = new Intent(MainActivity.this, levelToStart);
startActivity(intent);
}
});
// I added a new button to reset all levels
Button resetButton = findViewById(R.id.resetButton);
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Use the method reset() from LevelManager to restart everything
levelManager.reset();
Toast.makeText(MainActivity.this, "All levels have been reset!",
Toast.LENGTH_LONG).show();
}
});
Inside of onCreate on each Level Activity
// Get LevelManager
final LevelManager levelManager = LevelManager.getInstance(this);
// I created two buttons to simulate pass and fail
Button pass = findViewById(R.id.passButton);
Button fail = findViewById(R.id.failButton);
pass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Save state (Don't forget to change 'N' below)
levelManager.saveLevelState(LevelNActivity.class, true);
// Get next level
Class levelToStart = levelManager.getRandomLevel();
// Check if all are levels already completed
if (levelToStart == null) {
Toast.makeText(LevelNActivity.this, "Completed all levels",
Toast.LENGTH_LONG).show();
finish(); // Must implement to avoid going back to previous level (ie. Activity)
return;
}
Intent intent = new Intent(LevelNActivity.this, levelToStart);
startActivity(intent);
finish();
}
});
fail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
As you can see, you can simply use the finish() method if the user failed the level whereas you use the code below to proceed to the next level:
// Get LevelManager
LevelManager levelManager = LevelManager.getInstance(this);
// Set that the user passed this level (Change 'N' to the current level we are in)
levelManager.saveLevelState(LevelNActivity.class, true);
// Get next level
Class nextLevel = levelManager.getRandomLevel();
// If all levels are completed then 'nextLevel' will be null
if (nextLevel == null) {
// ...
}
// Start next level and finish current
Intent intent = new Intent(this, nextLevel);
startActivity(intent);
finish();
Note: To avoid calling finish() explicitly when starting the next level, you can put android:noHistory="true" in your levels' activity tag inside your manifest file.
How to save list to SharedPreferences by converting it to Json using Gson
To actually use Gson, you'll have to add implementation 'com.google.code.gson:gson:2.8.6' inside your app gradle dependencies.
Also, there's a problem on Gson when parsing Class objects to Json: You need to create your own serializer and deserializer for these objects and register it to your GsonBuilder.
ClassAdapter class (this is where we create our own custom serializer and deserializer for Class objects)
public class ClassAdapter implements JsonSerializer<Class>, JsonDeserializer<Class> {
#Override
public JsonElement serialize(Class src, Type typeOfSrc, JsonSerializationContext context) {
// Get our class 'src' name
return new JsonPrimitive(src.getName());
}
#Override
public Class deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
// Get class
return Class.forName(json.getAsString());
} catch (ClassNotFoundException e) {
// If class could not be found or did not exists, handle error here...
e.printStackTrace();
}
return null;
}
}
Here's a sample usage of saving a list to SharedPreferences by Json using Gson:
// Create new GsonBuilder and register our adapter for Class objects
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Class.class, new ClassAdapter());
// Initialize our list of levels (ie. classes)
List<Class> classes = new ArrayList<>();
classes.add(Level1Activity.class);
classes.add(Level2Activity.class);
classes.add(Level3Activity.class);
classes.add(Level4Activity.class);
classes.add(Level5Activity.class);
// Create Gson from GsonBuilder and convert list to json
Gson gson = gsonBuilder.create();
String json = gson.toJson(classes);
// Save json to SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("app_name", MODE_PRIVATE);
sharedPreferences.edit().putString("levels", json).apply();
And to retrieve the list back:
// Retrieve json from SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("app_name", MODE_PRIVATE);
String json = sharedPreferences.getString("levels", null);
// Handle here if json doesn't exist yet
if (json == null) {
// ...
}
// Create new GsonBuilder and register our adapter for Class objects
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Class.class, new ClassAdapter());
// Create Gson from GsonBuilder and specify type of list
Gson gson = gsonBuilder.create();
Type type = new TypeToken<ArrayList<Class>>(){}.getType();
// Convert json to list
List<Class> classes = gson.fromJson(json, type);
I hope you gained valuable tips to tackle this problem! And as always, happy coding!
Related
I am a new android programmer.
I have 4 activities: A B C D.
The order is A -> B -> C -> D -> A and A -> D using buttons.
I want to save data in ArrayList that is in activity D.
The problem is that when I move from D to A and come back to D, the data in the ArrayList didn't save.
Code for D activity here:
public class SchedulerActivity extends AppCompatActivity {
public String name = "";
public String number = "";
public String date = "";
public String hour = "";
public ArrayList<EventClass> scheduler = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scheduler);
Bundle extras = getIntent().getExtras();
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(SchedulerActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
}
});
if (extras != null) {
String sender = extras.getString("sender");
if(sender.compareTo("Hours") == 0) {
name = extras.getString("name");
number = extras.getString("number");
date = extras.getString("date");
hour = extras.getString("hour");
Date real_date = new Date();
SimpleDateFormat formatter1=new SimpleDateFormat("dd/MM/yyyy");
try {
real_date = formatter1.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
scheduler.add(new EventClass(real_date, name, number, "", hour));
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(t, params);
}
}
else{
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final Button btn = new Button(this);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(btn, params);
}
}
}
}
I want to change my ArrayList when C->D occurs and print it and when D->A occurs I just want to print it. I know that I can with SharedPreferences but for the first step, I want to do this with ArrayList.
What's the best way to do this?
Creating static objects is not a good approach. So you can use android activity stack in-place of using static Arraylist. Android activities are stored in the activity stack. Going back to a previous activity could mean two things.
You opened the new activity from another activity with startActivityForResult. In that case you can just call the finishActivity() function from your code and it'll take you back to the previous activity.
Keep track of the activity stack. Whenever you start a new activity with an intent you can specify an intent flag like FLAG_ACTIVITY_REORDER_TO_FRONT or FLAG_ACTIVITY_PREVIOUS_IS_TOP. You can use this to shuffle between the activities in your application.
The scheduler is a non-static field in the SchedulerActivity which means that its existance is tied to the instance of the activity. When the activity instance is destroyed, and that might happen for example when the screen orientation is destroyed or you move to another activity, so are all its non-static fields. You can change that by adding a static keyword before your field:
public static ArrayList<EventClass> scheduler = new ArrayList<>();
Now, your field is tied to the class itself, not the instance, whitch means it wont be destroyed along with the instance. But it also means that it is shared between all instances and must be referenced with the class name outside of the class body:
EventClass event = SchedulerActivity.scheduler.get(0)
A good approach is saving your data in a local database, like Room. You need to save before go to new activity, and get it back on OnResume().
I am new in Android. I need your help. My Problem is - I have 2 classes Nplist.java and Addcustomer.java. In my AddCustomer class,One TextView and one Button is there to go Nplist class. In my Nplist class there is checklist and this checklist is coming from database and all the checked values are stored in ArrayList<String> and one Button is used to go back to AddCustomer class. I want that ArrayList<String> which is in Nplist to by display in my AddCustomer class Textview . I haved tried these but my Addcustomer class crashed.
1.Nplist.class
add.setOnClickListener(new View.OnClickListener() {<br>
#Override<br>
public void onClick(View view) {<br>
Bundle extra=new Bundle();<br>
extra.putSerializable("objects",checkedList);<br>
Intent intent = new Intent(Nplist.this, AddCustomer.class);<br>
intent.putExtra("extra",extra);<br>
startActivity(intent);<br>
});
2.AddCustomer.class
onCrete()...{
Bundle extra = getIntent().getBundleExtra("extra");<br>
ArrayList<String> object = (ArrayList<String>)extra.getSerializable("objects");<br>
for (String str : object) {<br>
getnp.append(str + "\n");<br>
}
}
What do you expect the result to be?
- What is the actual result you get? (Please include any errors.)
When i go like this Nplist-->AddCustomer its working well but crash on ( AddCustomer-->Nplist-->AddCustomer)
It's because when you are coming back to your AddCustomer Activity the list is null . You can solve this problem by making a global class which will store the list in a Static Field , And You can access that list from any class or Activity you want to. Try out below solution .
Global.java Class is as below :
public class Global {
private static ArrayList<String> object = new ArrayList<>();
public static ArrayList<String> getObject() {
return object;
}
public static void setObject(ArrayList<String> object) {
Global.object = object;
}
}
From NpList.java class set the value of the list as below :
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Global.setObject(checkedList);
Intent intent = new Intent(Nplist.this, AddCustomer.class);
startActivity(intent);
}
});
Now Access in AdCustomer.java as below :
onCreate()...{
Bundle extra = getIntent().getBundleExtra("extra");
ArrayList<String> object = Global.getObject();
for (String str : object) {
getnp.append(str + "\n");
}
}
This maybe helpful for you.
Using putStringArrayListExtra method you can send an array list of strings along with the intent.
Sender side:
Intent intent = ...
intent.putStringArrayListExtra("THE_KEY", theList);
Receiver side:
ArrayList<String> theList = intent.getStringArrayListExtra("THE_KEY");
I'm trying to create an app like shopping cart
Using this to access my database http://www.tutecentral.com/restful-api-for-android-part-2/
And i'm stuck at adding products to cart, so far I understand that the selected products go to arraylist in a few tutorials. In the code below I have two Activities, the MaterialView (this shows the details of the materials and has the option to add to cart), and the MaterialCart (shows the list of selected products.)
this is the block of code in MaterialView to send the values to MaterialCart
ButtonAdd.setOnClickListener(new View.OnClickListener(){
public void onClick (View view){
Intent i=new Intent(MaterialView.this, MaterialCart.class);
i.putExtra("mID", mid);
i.putExtra("name", Name.getText().toString());
i.putExtra("qty", Qty.getText().toString());
i.putExtra("price", Price.getText().toString());
i.putExtra("stock", Stock.getText().toString());
i.putExtra("rqQty", RqQty.getText().toString());
startActivity(i);
Toast.makeText(MaterialView.this, "Added Succesfully.", Toast.LENGTH_LONG).show();
}
} );
I have used Intent to pass the values (I'm pretty sure this method is wrong, I also tried calling the MaterialCart class itself to access the arrayList so I can add values and it didn't work)
This is the block of codes in my MaterialCart to receive the values
public class MaterialCart extends Activity {
final ArrayList<PropertyCartTable> materialProperties = new ArrayList<>();
#SuppressLint("LongLogTag")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_material_cart);
Intent i = new Intent();
Bundle extras = getIntent().getExtras();
try{
String Name = extras.getString("name");
String Qty = extras.getString("qty");
String Price = extras.getString("price");
String Stock = extras.getString("stock");
String RqQty = extras.getString("rqQty");
String ID = extras.getString("mID");
Log.d("EXTRAS:", Name + " " + Qty + " " + ID);
materialProperties.add(new PropertyCartTable( ID,Name,Qty,Price,Stock,RqQty));
getIntent().removeExtra("Name");
getIntent().removeExtra("Qty");
getIntent().removeExtra("Price");
getIntent().removeExtra("Stock");
getIntent().removeExtra("RqQty");
getIntent().removeExtra("MID");
}
catch (Exception h){
Log.d("Exception!",h.toString());
}
// materialProperties.add(array);
Log.d("MaterialView.Cart isEmpty", String.valueOf(materialProperties.isEmpty()));
if(materialProperties.isEmpty()) {
Toast.makeText(this, "You have no materials to request.", Toast.LENGTH_LONG).show();
i = new Intent(MaterialCart.this, ProductDetails.class);
startActivity(i);
}else{
ArrayAdapter<PropertyCartTable> adapter = new propertyArrayAdapter(this, 0, materialProperties);
ListView listView = (ListView) findViewById(R.id.lv_materialcart);
listView.setAdapter(adapter);
}
}
The codes work for receiving the values, but when I go back to the materialView (or choose another product) the ArrayList doesn't append the values.
What I'm trying to achieve here is to add the values from the MaterialView (even if the user adds many prodducts) to MaterialCart's ArrayList.
You can let your Application contain the data:
public class MyApp extends Application {
private static List<String> data = new ArrayList<>();
public static void addItem(String item) {
data.add(item);
}
public static List<String> getData() {
return data;
}
}
And when button is clicked:
ButtonAdd.setOnClickListener(new View.OnClickListener(){
public void onClick (View view){
MyApp.addItem(your item);
Intent i=new Intent(MaterialView.this, MaterialCart.class);
startActivity(i);
}
} );
And in MaterialCart.class:
List<String> data = MyApp.getData();
But remember:data will be clear when app is closed.And if you want save it locally,you need to use SharedPreferences
I'm new to android development and I am creating an android application that works like "4 Pics 1 Word" for my project. I'm having difficulties in storing ArrayList in SharedPreferences or in the internal storage of the android phone. The reason why is because I am randomizing the next activity using random generator and ArrayList. Any suggestions or ideas that my help my case? Thank you in advance! I've been stuck here for hours now.
This is my MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btnStart;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// We are creating a list, which will store the activities that haven't been opened yet
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(first.class);
activityList.add(second.class);
activityList.add(third.class);
activityList.add(fourth.class);
activityList.add(fifth.class);
Random generator = new Random();
int number = generator.nextInt(5) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
activity = first.class;
// We are adding the number of the activity to the list
activityList.remove(first.class);
break;
case 2:
activity = second.class;
activityList.remove(second.class);
break;
case 3:
activity = third.class;
activityList.remove(third.class);
break;
case 4:
activity = fourth.class;
activityList.remove(fourth.class);
break;
default:
activity = fifth.class;
activityList.remove(fifth.class);
break;
}
// We use intents to start activities
Intent intent = new Intent(getBaseContext(), activity);
// `intent.putExtra(...)` is used to pass on extra information to the next activity
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
}
And here's my first activity:
public class first extends AppCompatActivity implements View.OnClickListener{
EditText etAnswer;
Button btnGo;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
etAnswer = (EditText) findViewById(R.id.etAnswer);
btnGo = (Button) findViewById(R.id.btnGo);
btnGo.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnGo:
String answer = etAnswer.getText().toString();
if(answer.equals("Jose Rizal") || answer.equals("jose rizal") || answer.equals("Rizal") || answer.equals("rizal") ){
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setMessage("The famous Rizal monument in Luneta was not the work of a Filipino but a Swiss sculptor named Richard Kissling?" +
"Source: http://www.joserizal.ph/ta01.html");
dlgAlert.setTitle("Did you know that ...");
dlgAlert.setPositiveButton("Next",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ArrayList<Class> activityList = new ArrayList<>();
Bundle extras = getIntent().getExtras();
activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");
if(activityList.size() == 0) {
Context context = getApplicationContext();
CharSequence last = "Congratulations! You just finished the game! Please wait for the next update!";
int durationFinal = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, last, durationFinal);
toast.show();
} else {
// Now, the random number is generated between 1 and however many
// activities we have remaining
Random generator = new Random();
int number = generator.nextInt(activityList.size()) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
// We will open the first remaining activity of the list
activity = activityList.get(0);
// We will now remove that activity from the list
activityList.remove(0);
break;
case 2:
// We will open the second remaining activity of the list
activity = activityList.get(1);
activityList.remove(1);
break;
case 3:
// We will open the third remaining activity of the list
activity = activityList.get(2);
activityList.remove(2);
break;
case 4:
// We will open the fourth remaining activity of the list
activity = activityList.get(3);
activityList.remove(3);
break;
default:
// We will open the fifth remaining activity of the list
activity = activityList.get(4);
activityList.remove(4);
break;
}
// Note: in the above, we might not have 3 remaining activities, for example,
// but it doesn't matter because that case wouldn't be called anyway,
// as we have already decided that the number would be between 1 and the number of
// activities left.
// Starting the activity, and passing on the remaining number of activities
// to the next one that is opened
Intent intent = new Intent(getBaseContext(), activity);
intent.putExtra("ACTIVITY_LIST", activityList);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
dlgAlert.setCancelable(true);
dlgAlert.create().show();
}else{
Context context = getApplicationContext();
CharSequence text = "Wrong! Try Again.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
break;
}
}
}
Okay, this is a horrible hack and I don't endorse it in any way, but since you are so close to finishing your app, I propose a workaround:
Instead of storing an ArrayList<Class> in your SharedPreferences (which is impossible), store a HashSet<String> containing the fully qualified names of your classes via putStringSet().
In order to get the String representations of the fully qualified names of your classes you need to call getName(), e.g. first.class.getName().
Then, you can get your Set<String> from SharedPreferences using getStringSet() and create a Class instance for each String in that set via Class.forName().
I've got 2 activities and a class that extends Application where I'm trying to store global variables with a kind of setter getter functions.
The main activity sets some views and a chart; then calls the second activity which should be setting values to be used afterwards on the previous chart.
Then pressing backbutton and returning to the previous activity onRestart is called and the chart is refreshed.
The problem is I lose my theorically global variables somewhere. Debugging i realized that the functions work perfectly fine while im adding values in the second activity but when I return to the first activity globalXCount returns '0' again. Why is that?
I think im missunderstanding some point regarding lifecycles.
I attach some fragments of the code.
First activity:
public class MainActivity extends Activity {
Global glObj = new Global();
CombinedChart mChart;
private int itemcount;
float displayed;
private final List<String> mMonthList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
mChart = (CombinedChart) findViewById(R.id.mchart);
populateHeaderList();
setChartSettings();
Intent intent = new Intent(MainActivity.this, QandA.class);
startActivity(intent);
}
#Override
protected void onRestart() {
super.onRestart();
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
populateHeaderList();
setChartSettings();
}
Second activity:
public class QandA extends Activity {
Global glObj = new Global();
ViewFlipper flipper;
private float lastX;
...
}else{
//TODO If all information if correctly filled
trainedmins = et1.getText().toString();
localLineValue = Integer.parseInt(trainedmins) * Integer.parseInt(statusQ1);
//Add values to lines
glObj.setLineXvalues(localLineValue);
// TODO Add new Bar value //
//Add 1 more value to count
glObj.addGlobalXCount();
}
...
Global class:
public class Global extends Application {
//TODO
public Integer globalXCount;
private List<Integer> lineXvalues = new ArrayList<>();
private List<Integer> barXvalues = new ArrayList<>();
//////
public Integer getGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
return this.globalXCount;
}else{
return this.globalXCount;
}
}
public void addGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
}else{
this.globalXCount = this.globalXCount + 1;
}
}
Thanks in advance.
First of all, register your custom Application context in AndroidManifest.xml within the <application>-tag.
<application
android:name="<your_package>.Global" ...>
Access the global application context within your activities like this:
Global glObj = (Global) getApplicationContext();
glObj.addGlobalXCount();
Do not create a new instance with new! Always retrieve the instance via getApplicationContext().
Furthermore, I would suggest you to initialize your class field glObj within the onCreate()-method of your Activities.