I am new to Android development and am having a question about multiple switch buttons, how to retrieve values smartly, and make this data available for other activities?
Currently, I am implemented the save of the button state and retrieval of the information found in the current activity as followed:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
switchButtonOne = findViewById(R.id.switchButtonOne);
switchButtonOne.setChecked(true);
switchButtonTwo = findViewById(R.id.switchButtonTwo);
switchButtonTwo.setChecked(false);
//...... (In total there are 5 switch buttons)
//switchButtonOne
switchButtonOne.setOnCheckedChangeListener((compoundButton, isChecked) -> {
if(isChecked){
stringArrayList.add("1");
}else {
stringArrayList.remove("1");
}
getArray(stringArrayList);
//SAVE
sharedPreferences[0] = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences[0].edit();
editor.putBoolean("1", switchButtonOne.isChecked());
editor.commit();
});
switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));
//switchButtonTwo
switchButtonTwo.setOnCheckedChangeListener((compoundButton, isChecked) -> {
if(isChecked){
stringArrayList.add("2");
}else {
stringArrayList.remove("2");
}
getArray(stringArrayList);
//SAVE
sharedPreferences[0] = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences[0].edit();
editor.putBoolean("2", switchButtonTwo.isChecked());
editor.commit();
});
//.......
}
I am sure there is a more efficient way to implement this and I would gladly appreciate effective resources to learn the best practices of making information and Activity state available between Activities.
Big thanks in advance
One option is to use only one listener for all five buttons. You would do this like so:
public class MyActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
Switch[] buttons;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
buttons = new Switch[5];
Switch switchButtonOne = findViewById(R.id.switchButtonOne);
switchButtonOne.setOnCheckedChangeListener(this);
switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));
buttons[0] = switchButtonOne;
Switch switchButtonTwo = findViewById(R.id.switchButtonTwo);
switchButtonTwo.setOnCheckedChangeListener(this);
switchButtonTwo.setChecked(sharedPreferences[1].getBoolean("2", false));
buttons[1] = switchButtonTwo;
//...... (In total there are 5 switch buttons)
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int index;
switch (buttonView.getId()) {
case R.id.switchButtonOne:
index = 0;
break;
case R.id.switchButtonTwo:
index = 1;
break;
...
}
if (isChecked) {
stringArrayList.add(String.valueOf(index + 1));
} else {
stringArrayList.remove(String.valueOf(index + 1));
}
getArray(stringArrayList);
//SAVE
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences[index].edit();
editor.putBoolean(String.valueOf(index + 1), buttons[index].isChecked());
editor.commit();
}
}
At this point the code is not much shorter than yours, however, as soon as you add your other three buttons, you will see than the code for all buttons ends up being considerably shorter and more concise.
It would be great to have a BooleanArray for the SharedPreferences, however, such a class does not exist. A workaround can be found here.
EDIT
Looking at your question and your full code again, I would suggest a different approach. You don't need any OnCheckedChangeListener at all. Simply save the state of your buttons whenever the activity is left (onPause) and restore state once the activity is resumed (onResume). A side effect is that the code gets much shorter.
public class MainActivity extends Activity {
Switch[] buttons;
int numberOfButtons = 5;
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
buttons = new Switch[numberOfButtons];
sharedPreferences = getSharedPreferences("YourPreferenceName", MODE_PRIVATE);
for (int i = 0; i < numberOfButtons; i++) {
buttons[i] = findViewById(getResources().getIdentifier("switchButton" + String.valueOf(i + 1), "id", getPackageName()));
}
}
public void onPause() {
super.onPause();
for (int i = 0; i < numberOfButtons; i++) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(String.valueOf(i + 1), buttons[i].isChecked());
editor.apply();
}
}
public void onResume(){
super.onResume();
for (int i = 0; i < numberOfButtons; i++) {
buttons[i].setChecked(sharedPreferences.getBoolean(String.valueOf(i + 1), false));
}
}
}
Please note that, in your layout xml, you have to change the ids of your switches to the following: switchButton1, ..., switchButton5.
You can Implement CompoundButton.OnCheckedChangeListener for whole activity and then set listener for all switch you have used.Handle all switch in single callback onCheckedChanged.
public class SwitchActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
Switch switchButtonOne;
Switch switchButtonTwo;
#Override
public void onCreate(#Nullable Bundle savedInstanceState, #Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
switchButtonOne = findViewById(R.id.switchButtonOne);
switchButtonOne.setChecked(true);
switchButtonTwo = findViewById(R.id.switchButtonTwo);
switchButtonTwo.setChecked(false);
switchButtonOne.setOnCheckedChangeListener(this);
switchButtonTwo.setOnCheckedChangeListener(this);
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (buttonView.getId()) {
case R.id.switchButtonOne:
//Handle Code for switchButtonOne
break;
case R.id.switchButtonTwo:
//Handle Code for switchButtonOne
break;
}
}
}
Related
I want to save the number value so that when close the app it continues to be saved and when open it the progress is maintained. I don't know why SharedPreferences don't work.
I have tried in many ways but either the app forces it to close or it just doesn't work
number = numero
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView contador;
int numero = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences mPrefs = getSharedPreferences("valor", numero);
int data = mPrefs.getInt("valor", numero);
contador = findViewById(R.id.contador);
}
public void onClick(View v) {
numero++;
contador.setText(String.valueOf(numero));
SharedPreferences.Editor data = data.edit();
data.putInt("tag", numero).commit();
}
};
You should use the same sharedPreferences for retrieving the values.
also, get the values by the same key you saved them. below is an example you can follow.
SharedPreferences mPrefs = getSharedPreferences("valor",
Context.MODE_PRIVATE);
try{
int data = mPrefs.getInt("tag", numero);
}
catch(NullPointerException e){
e.printStackTrace()
}
public void onClick(View v) {
numero++;
contador.setText(String.valueOf(numero));
SharedPreferences.Editor editor = mPrefs.edit();
editor.putInt("tag", numero).commit();
}
};
I'm building an app to check prime numbers and display them. the user need to be able to save the number and load it upon restart of the app.
I have problem when retrieving the saved int from Sharedprefrences. the codes saves the int and loads it on the "loaddata" function. But when I start checking if the saved in is a primenumber, the code jumps 2 primenumbers. Eg if I save "11", the next primenumber should be "13" but it jumps to "19".
Would be great if someone could point into the right direction since i'm a bit of newbie.
public class MainActivity extends AppCompatActivity {
private TextView textView;
private EditText editText;
private Button applyPrimeButton;
private Button saveButton;
private Button loadButton;
public static final String SHARED_PREFS = "sharedPrefs";
int max = 500;
int j = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview);
editText = (EditText) findViewById(R.id.edittext);
applyPrimeButton = (Button) findViewById(R.id.apply_prime_button);
saveButton = (Button) findViewById(R.id.save_button);
loadButton = (Button) findViewById(R.id.load_button);
applyPrimeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i = j; i <= max; i++) {
if (isPrimeNumber(i)) {
textView.setText(i+"");
j = i+1;
break;
}
}
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveData();
}
});
loadButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
public boolean isPrimeNumber(int nummer) {
for (int i = 2; i <= nummer / 2; i++) {
if (nummer % i == 0) {
return false;
}
}
return true;
}
public void saveData() {
SharedPreferences sp = getSharedPreferences(SHARED_PREFS, Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
int nummer = Integer.parseInt(textView.getText().toString());
editor.putInt("prime_save", nummer);
editor.commit();
Toast.makeText(this, "Data saved", Toast.LENGTH_SHORT).show();
}
public void loadData() {
SharedPreferences sp = getSharedPreferences(SHARED_PREFS, Activity.MODE_PRIVATE);
int nummer = sp.getInt("prime_save",0);
textView.setText(String.valueOf(nummer));
}
}
Several issues:
You are not updating j to the correct value when loading data, and instead relying on what you are displaying in the textview.
To find prime number, it is enough to check until the square root of the original number and not half of it.
Try this:
applyPrimeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(j<max ){
if (isPrimeNumber(j)) {
textView.setText(j+"");
j++;
}
}
}
});
public void saveData() {
SharedPreferences sp = getSharedPreferences(SHARED_PREFS, Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("prime_save", j);
editor.commit();
Toast.makeText(this, "Data saved", Toast.LENGTH_SHORT).show();
}
public void loadData() {
SharedPreferences sp = getSharedPreferences(SHARED_PREFS, Activity.MODE_PRIVATE);
int nummer = sp.getInt("prime_save",0);
j = nummer;
textView.setText(String.valueOf(nummer));
}
I am learning how to use shared preferences and I understand how to set it and get it with one class. However I want to be ale to use shared preferences across two classes. Let me explain.
So in the class below I am basically getting the total number of click counts for whenever the jokes, poems or funny stories button is clicked. This code is below (known as MainActivity):
public class MainActivity extends AppCompatActivity{
final Context context = this;
int clicksCount = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button jokesButton = findViewById(R.id.button_jokes);
Button poemsButton = findViewById(R.id.button_poems);
Button funnyStoriesButton = findViewById(R.id.button_funny_stories);
jokesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicksCount++;
storeClicks(clicksCount);
openContentPage("jokes");
}
});
poemsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicksCount++;
storeClicks(clicksCount);
openContentPage("poems");
}
});
funnyStoriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicksCount++;
storeClicks(clicksCount);
openContentPage("funnystories");
}
});
}
private void openContentPage(String v) {
Intent intentContentPage = new Intent(MainActivity.this, Content.class);
intentContentPage.putExtra("keyPage", v);
startActivity(intentContentPage);
}
public void storeClicks(int count)
{
SharedPreferences mSharedPreferences = getSharedPreferences("numberOfClicks", MODE_PRIVATE);
SharedPreferences.Editor meditor = mSharedPreferences.edit();
meditor.putInt("numberOfClicks", count);
meditor.apply();
}
public int getNumberOfClicks(){
SharedPreferences mSharedPreferences = getSharedPreferences("numberOfClicks", MODE_PRIVATE);
int clicksNumber = mSharedPreferences.getInt("numberOfClicks", clicksCount);
return clicksNumber;
}
}
However I have another class known as 'Content' and basically this contains a button known as 'Select Another'. I want this to be included with the click count as well.
So that's the goal basically, no matter what page I am on it should keep track of the number of clicks combined for buttons jokes, poems, funny stories and select another. How can this be implemented?
Below is the code for Content:
public class Content extends AppCompatActivity{
Button selectAnotherButton;
TextView contentText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
selectAnotherButton = findViewById(R.id.button_select_another);
selectAnotherButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setContent();
}
});
}
You can use Singleton pattern to implement global access to the SharedPreferences. Something like this:
public class SharedPreferencesManager {
private static final String APP_PREFS = "AppPrefsFile";
private static final String KEY_FOR_SOMETHING = "KEY_FOR_SOMETHING";
private SharedPreferences sharedPrefs;
private static SharedPreferencesManager instance;
private SharedPreferencesManager(Context context) {
sharedPrefs =
context.getApplicationContext().getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
}
public static synchronized SharedPreferencesManager getInstance(Context context){
if(instance == null)
instance = new SharedPreferencesManager(context);
return instance;
}
public void setSomething(String something) {
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(KEY_FOR_SOMETHING, something);
editor.apply();
}
public String getSomeKey() {
String someValue = sharedPrefs.getString(KEY_FOR_SOMETHING, null);
return someValue;
}
}
You can have as much as you want methods for getting and setting various values to the SharedPreferences, and it will be accessible through the whole application, just do:
SharedPreferencesManager.getInstance(context).getSomeKey();
Shared Preference is just a common file that contains a set of Key Value Pairs.It would be accessible in any class from your App.
For your case , you can store it as a key value pair in one Class .
Then retrieve it using the same KeyName in another Class.It should retrieve the value you stored in the other class provided the flow is continous.
Please refer below existing stackoverflow answers for more info ::
Android Shared preferences example
Official Docs :
https://developer.android.com/training/data-storage/shared-preferences
Tutorial Example :
https://www.journaldev.com/9412/android-shared-preferences-example-tutorial
I have a simple scenario but can't seem to wrap my head around it.
I want to save a incremented value as a int to SharedPreferences every time a user tap on a item, let me show what I have:
int counter = 0;
mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter++;
SharedPreferences shareOpenClose = getSharedPreferences("Counter", Context.MODE_PRIVATE);
SharedPreferences.Editor editorOpenClose = shareOpenClose.edit();
editorOpenClose.putInt("count", counter);
editorOpenClose.apply();
SharedPreferences getCount = getSharedPreferences("Counter", Context.MODE_PRIVATE);
int getCountAmmount = getCount.getInt("count", 0);
if (getCountAmmount>3){
Toast.makeText(c, "success!", Toast.LENGTH_SHORT).show();
}
}
});
So, when I close the activity and open it again the counter will be reset to zero and the first save to SharedPreferences back to 0. If I keep the activity open and test this it work and I get the toast as expected.
Can someone please point out what I'm doing wrong?
Because you never set the counter back when the activity loads. try this:
int counter = 0;
onCreate(...){
SharedPreferences countPref = getSharedPreferences("Counter", Context.MODE_PRIVATE);
counter = countPref.getInt("count", 0);
}
mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter++;
SharedPreferences countPref = getSharedPreferences("Counter", Context.MODE_PRIVATE);
SharedPreferences.Editor editorOpenClose = countPref.edit();
editorOpenClose.putInt("count", counter);
editorOpenClose.apply();
if (counter>3){
Toast.makeText(c, "success!", Toast.LENGTH_SHORT).show();
}
}
});
Make the following changes in your code
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences shareOpenClose = getSharedPreferences("Counter", Context.MODE_PRIVATE);
final SharedPreferences.Editor editorOpenClose = shareOpenClose.edit();
final int[] counter = {0};
mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter[0]++;
editorOpenClose.putInt("count", counter[0]);
editorOpenClose.apply();
SharedPreferences getCount = getSharedPreferences("Counter", Context.MODE_PRIVATE);
int getCountAmmount = getCount.getInt("count", 0);
if (getCountAmmount>3){
Toast.makeText(c, "success!", Toast.LENGTH_SHORT).show();
}
}
});
}
I hope this will help you, Happy Coding
Am trying save boolean FAVOURITE data in sharedPreferences. when phone is rotated or closed .It is not working it is taking default value. I don't know whats wrong with this code. i am unable to figure out whats the problem is can someone show me the problem with the code
//Context context =this;
String FAVOURITE = "selected";
boolean favourite = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState!=null){
favourite = savedInstanceState.getBoolean(FAVOURITE,false);
Toast.makeText(this,""+favourite,Toast.LENGTH_SHORT).show();
}
final Bundle queryBundle = new Bundle();
movieObject=(CardsClass)getIntent().getSerializableExtra("movieObject");
setTitle(movieObject.getmTitle());
setContentView(R.layout.activity_details);
final ImageView fav = (ImageView)findViewById(R.id.fav);
fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (favourite == false) {
favourite = true;
fav.setImageResource(R.drawable.fav_on);
Toast.makeText(DetailsActivity.this, favourite + " is added to favourites", Toast.LENGTH_SHORT).show();
queryBundle.putBoolean(FAVOURITE,favourite);
}
else if(favourite){
favourite=false;
fav.setImageResource(R.drawable.fav_off);
queryBundle.putBoolean(FAVOURITE,favourite);
Toast.makeText(DetailsActivity.this, movieObject.getmTitle() + " is removed from favourites", Toast.LENGTH_SHORT).show();
}
}
});
Actually, you're doing the wrong thing. You should do something like:
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(FAVOURITE, favorite); // then you can check the favorite value in onCreate as well.
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
this.favorite = savedInstanceState.getBoolean(FAVOURITE);
// do something here when restore.
super.onRestoreInstanceState(savedInstanceState);
}
To write or read in the SharedPreferences
Write:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean(FAVORITE, favorite);
editor.commit();
Read:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
Boolean favorite = sharedPref.getBoolean(FAVORITE, true);