Saving view state android while app restarted - java

I am currently new to android and am working on a note taker application so please be patient with me. Inside the menu, i implemented an option whereby the user can change view if desired (List or Grid).
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View customTitleView = inflater.inflate(R.layout.dialog_menu, null);
mListViewSelect = (LinearLayout) customTitleView.findViewById(R.id.list_select);
mGridViewSelect = (LinearLayout) customTitleView.findViewById(R.id.grid_select);
case R.id.changeView:
final AlertDialog alertbox = new AlertDialog.Builder(this).create();
alertbox.setCancelable(true);
alertbox.setView(customTitleView);
alertbox.show();
mListViewSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListNotes.setVisibility(View.VISIBLE);
mGridNotes.setVisibility(View.GONE);
alertbox.dismiss();
}
});
mGridViewSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListNotes.setVisibility(View.GONE);
mGridNotes.setVisibility(View.VISIBLE);
alertbox.dismiss();
}
});
}
return super.onOptionsItemSelected(item);
}
This works perfectly. However, i want the app to open in the selected view initially selected by user. For example, if the user had closed the app while in gridview, the app should open in gridview while restarted.
I understand i need to save data persistently with shared preferences or something. But i need to know exactly what i need to do.

If you want to save your data in Shared Preference, here is a way to do it.
First you need to create an instance of SharedPreferences and SharedPreferences.Editor:
private SharedPreferences settings = context.getSharedPreferences("*Desired preferences file", Context.MODE_PRIVATE);
*Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor
(SharedPreferences.edit()) and then commit changes (Editor.commit()).
private SharedPreferences.Editor editor = settings.edit();
If you need to save a String:
editor.putString(key, val).commit()
Don't forget to do the .commit();
To get The String from SharedPreferences:
String str = settings.getString(key, "");
Saving Int:
just use:
editor.putInt(key, val).commit();
and so on.

You are correct that you need to persist data, you have options though. You say it is a note taking app, where are you saving your notes?
You could store your application's state in share preferences, described in the the docs here. You could store the applications state, as well as all the notes in a database, such as a relational database, of which there a tons of tutorials on and the main docs can be found here, or alternatively a database such as Realm, which saves objects to the database.
I would research into these options, and implement one. Then, on application launch, check the 'application state' that you have saved and adjust the UI accordingly!

Related

How to use SharedPreferences in android to get value from PhotoView id/image id

I am creating an android application, I am displaying images from drawable folder based on the numbering, my activity start showing images from number 1 and I am using buttons to show next or previous image.
I am trying to save the value of image user was viewing while pressed back button using shared preferences. my code looks like this
private int currentPage = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read);
final Button btnNext = findViewById(R.id.btnNext);
final Button btnBack = findViewById(R.id.btnBack);
listOfObjects = getResources().getStringArray(R.array.object_array);
images = getResources().obtainTypedArray(R.array.object_image);
itemImage = (ImageView)findViewById(R.id.imgSpace);
final Spinner spinner = (Spinner)findViewById(R.id.spinner);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,R.layout.my_spinner, listOfObjects);;
spinnerAdapter.setDropDownViewResource(R.layout.my_spinner);
spinner.setAdapter(spinnerAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
itemImage.setImageResource(images.getResourceId(spinner.getSelectedItemPosition(), -1));
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
final ImageView img = findViewById(R.id.imgSpace);
PhotoView photoView = (PhotoView) findViewById(R.id.imgSpace);
img.setImageResource(getResources().getIdentifier("page_"+currentPage,"drawable",getPackageName()));
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(spinner.getSelectedItemPosition() < spinner.getAdapter().getCount()){
spinner.setSelection(spinner.getSelectedItemPosition()+1);
}
}
} );
}
currentPage is the variable which I want to save after pressing back button or to go to any other activity and also if user minimises the application, I want to pass it to main activity in order to show the extra button of resume activity and also to show the exact image the user was seeing before pressing the back button when user clicks on resume activity button.
I am using Chris Banes's photoview to show the image. I know how to pass variables and et them in PHP however android is new for me. ANy help would be appreciated.
SharedPreferences prefs = getSharedPreferences("nameOfSharedPreference", MODE_PRIVATE);
SharedPreferences.Editor editor = getSharedPreferences("nameOfSharedPreference", MODE_PRIVATE).edit();
editor.putInt("image", R.imageID).commit();
#Override
onBackPressed(){
image = prefs.getInt("image", defaultValue) //Default value is taken if the pref doesn't exist yet
}
onBackPressed() is called automatically by android when pressing the phone back button. You can call it manually:
onBackPressed();
I don't understand the question completely but you could write:
SharedPreferences prefs = getSharedPreferences("nameOFPref", MODE_PRIVATE);
private int currentPage = prefs.getInt("image", 1);
The way it works is it saves a file in nameOfPref in the "image" section so you get it back when the program launches. Here we put 1 as default value so the value it will take is 1 the first time you launch the program. You should write:
SharedPreferences.Editor editor = getSharedPreferences("nameOfSharedPreference", MODE_PRIVATE).edit();
editor.putInt("image", idOFImageCurrentlyVIewed).commit();
Later in the program each time the user changes image. So it will change the preference and will make sure that when you launch the program back currentImage will take the right value.
In android studio you can look at the file system of emulated phones. For preferences you need to go in Android/data/com.yourPackageName/preferences and you should see your file there if everything goes fine.

how to make stay in the last language when android app is closed?

I have already made an app android to change the language. But when the app is closed and the open again, the language back to the default language.
How can i make when app open again and the language is the last choose by user?
Thanks for help and i really appreciate it.
you need to save the user selected language to shared preference or any other persistent storage, on next app launch retrieve the language previously selected and apply it to the application.
when user changes the language, in order to apply the new laguage activity should be finished and restarted or else you need to call recreate() method of the activity.
https://github.com/gunhansancar/ChangeLanguageExample/blob/master/app/src/main/java/com/gunhansancar/changelanguageexample/helper/LocaleHelper.java
Copy the above class to your code.
In your activity override the below method.
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
When user change the language ,e.g its on button click. save the language using below code. Here en is the language (iso) code for english.
#Override
public void onClick(View v) {
LocaleHelper.persist(context,"en");
recreate();
}
By default the language of app will be falling back to device locale as a result each time you restart your app the language will change.
In order to make your app's language same as user's choosen preference, you need to persist the language chosen by user. One way is to store the language preference in SharedPreference. When the app is launched, check for the value in preference to decide which Language should be used and then adjust your view accordingly.
You can do it as follows
Store value as follows when language is changed:
SharedPreferences.Editor editor = getSharedPreferences("MyPref",
MODE_PRIVATE).edit(); editor.putString("language", "en");
editor.commit();
Retrieve value as follows in onCreate():
SharedPreferences prefs = getSharedPreferences("MyPref", MODE_PRIVATE);
String selectedLanguage = prefs.getString("language", "<enter default locale of app>");
setLocale(selectedLanguage);
Eventually set the locale as follows:
Without Activity restart:
Set android:configChanges="locale" in your in manifest
Change your setLocale as follows:
private void setLocale(String lang) {
Locale myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
getBaseContext().getResources().updateConfiguration(conf, getBaseContext().getResources().getDisplayMetrics());
invalidateOptionsMenu();
onConfigurationChanged(conf);//Add this line
}
Override onConfigurationChanged():
#Override
public void onConfigurationChanged(final Configuration newConfig) {
super.onConfigurationChanged(newConfig);
textView.setText(<your-text>);
//Any other UI text to change
}
Alternatively you can call recreate(); once locale is changed.
This will ensure your locale is changed correctly.

Dynamically Add and Save buttons in Android studio

Currently i managed to create the buttons dynamically on a view
Here is the my code to create the buttons;
public void Add_on(View v) {
AlertDialog.Builder mbuilder = new AlertDialog.Builder(Mb.this);
View mview = getLayoutInflater().inflate(R.layout.activity_mb1, null);
EditText number = (EditText) mview.findViewById(R.id.etnum);
Button Create = (Button) mview.findViewById(R.id.etcreate);
Button Cancel = (Button) mview.findViewById(R.id.etcancel);
Create.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
if (!number.getText().toString().isEmpty())
{
Toast.makeText(Mb.this, "Number can be NULL",Toast.LENGTH_SHORT).show();
LinearLayout yenilayout = new LinearLayout(Mb.this);
int n =1;
for(int i=0; i<n; i++)
{
Button yeniButton = new Button(Mb.this);
yenilayout.addView(yeniButton);
yeniButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(Mb.this, "Button is working",Toast.LENGTH_SHORT).show();
}
});
}
altlayout.addView(yenilayout);
} else {
Toast.makeText(Mb.this, "Number cannot be NULL",Toast.LENGTH_SHORT).show();
}
}
});
But whenever i recall the activity, the buttons are no longer exist. So May i know can i place the button there permanently?
Thank you for suggestions
You can use Bundle to save an activity's state and recreate it in the onCreate() method. This works for a particular instance of Activity, so can be used to save data concerning selection, or user input etc., but not data that you need to be persistent across application launches.
To use the Bundle, override the onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle) methods in the Activity class. You can use methods from Bundle to save whatever data you like in a map, and get it back in onRestoreInstanceState(Bundle), which is called in onStart().
The default implementations already handle most UI stuff though, and I would have thought this would keep track of your buttons for you, so it may be that your question is actually about associating some persistent data with your application. (this also means that if you do override the above methods, you should make sure to call the super methods in the first line of your implementation).
If you need persistent data across application launches, then the quickest and easiest way would be to use SharedPreferences, see this answer for an example.

Retaining the data in the view during activity switch?

In my android app the user can enter the text in the EditView and the click on a button which takes him to an other activity where he can select a contact ... and then press a button which
brings him back to the first activity...
now the problem is I need to pass the selected contact to the first activity and display it (which i have done it using a bundle) but i am unable to retain already entered text in the EditView... which i should do (but the text should be retained with out passing it through the the bundle and getting it back)
thanks :)
The text in a view component is automagically saved by the OS, even after a soft kill (user changed phone orientation), but not after a hard kill, the user hit the back button while the parent activity was in focus. So, unless you are doing something non-standard, such as calling onSaveInstanceState without calling super.onSaveInstanceState, the data in the view state should persist.
One solution would be to save the text in the view component as a non view instance property before you launch the child activity, and just read this value back when the focus returns to the parent activity in the method onActivityResult.
JAL
EDIT: The Android Docs Activity page has been extensively updated. View state will not be saved if the widget does not have an ID.
EDIT: What I am saying is that the view state should be persisted by the OS. You should not need to save the view state manually. On a hard kill, you would need to save the state of your activity IF that is the expected behavior of the activity. So here is some code that saves the activity state. Given an instance variable:
String password;
Here we save state on a soft kill:
protected void onSaveInstanceState(Bundle outState){
password= editTextPassword.getText().toString();
outState.putString("password", password);
super.onSaveInstanceState(outState); // save view state
}
Here we save state on a hard kill
#Override
protected void onStop(){
super.onStop();
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("password",password);
editor.commit();
Here we restore state in onCreate(Bundle savedInstanceState):
if( savedInstanceState!= null){ // get saved state from soft kill after first pass
try {
password= savedInstanceState.getString("password");
Log.d(TAG,"RestoredState!");
}
catch(Exception e){
Log.d(TAG,"FailedToRestoreState",e);
}
}
else { // get saved state from preferences on first pass
SharedPreferences prefs = getPreferences(MODE_PRIVATE); // singleton
if (prefs != null){
this.password= prefs.getString("password","");
Log.d(TAG,"gettingPrefs");
}
}
Log.d(TAG,"onCreate");
Also given the fact that IF onSaveInstanceState is called it will be called before onStop, it is possible to use the flags isSavedInstanceState and isSavedPreferences to write to prefs ONLY on a hard kill if you reset the flags in onResume as:
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
isSavedInstanceState= false;
isSavedPrefs= false;
}
Setting the flags in onCreate will not result in the desired outcome.

Saving and restoring state in android

I have searched through this and a few other sites for the answer, but I have been unable to find it. I am trying to save a boolean and an int using onSaveInstanceState and onRestoreInstanceState, but I can't seem to get it to work. It doesn't crash or anything, but it either isn't saving it or it isn't restoring it, or I am stupid and have no idea what I am doing.
Here is what I have for my activity, do I need to have it in my onCreate somewhere or something?
public class CannonBlast extends Activity {
/** Called when the activity is first created. */
private panel panelStuffz;
#Override
public void onCreate(Bundle savedInstanceState) {
final Window win = getWindow();
super.onCreate(savedInstanceState);
panelStuffz = new panel(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(panelStuffz);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putInt("HighLevel", panelStuffz.getLevel());
savedInstanceState.putBoolean("soundstate", panelStuffz.getSound());
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
panelStuffz.setHighLevel(savedInstanceState.getInt("HighLevel"));
panelStuffz.setSound(savedInstanceState.getBoolean("soundstate"));
}
#Override
public void onResume(){
super.onResume();
}
#Override
public void onPause(){
super.onPause();
panelStuffz.setThread(null);
}
#Override
public void onStop(){
}
I tried putting stuff in the onStop, but it crashes, which is why its empty, in case that matters, thanks in advance
Many applications may provide a way to capture user preferences on the settings of a specific application or an activity. For supporting this, Android provides a simple set of APIs.
Preferences are typically name value pairs. They can be stored as “Shared Preferences” across various activities in an application (note currently it cannot be shared across processes). Or it can be something that needs to be stored specific to an activity.
Shared Preferences: The shared preferences can be used by all the components (activities, services etc) off the applications.
Activity handled preferences: These preferences can only be used with in the activity and can not be used by other components of the application.
Shared Preferences:
The shared preferences are managed with the help of getSharedPreferences method of the Context class. The preferences are stored in a default file(1) or you can specify a file name(2) to be used to refer to the preferences.
(1) Here is how you get the instance when you specify the file name
public static final String PREF_FILE_NAME = "PrefFile";
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
MODE_PRIVATE is the operating mode for the preferences. It is the default mode and means the created file will be accessed by only the calling application. Other two mode supported are MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE. In MODE_WORLD_READABLE other application can read the created file but can not modify it. In case of MODE_WORLD_WRITEABLE other applications also have write permissions for the created file.
(2) The recommended way is to use by the default mode, without specifying the file name
SharedPreferences preferences = PreferencesManager.getDefaultSharedPreferences(context);
Finally, once you have the preferences instance, here is how you can retrieve the stored values from the preferences:
int storedPreference = preferences.getInt("storedInt", 0);
To store values in the preference file SharedPreference.Editor object has to be used. Editor is the nested interface of the SharedPreference class.
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
Editor also support methods like remove() and clear() to delete the preference value from the file.
Activity Preferences:
The shared preferences can be used by other application components. But if you do not need to share the preferences with other components and want to have activities private preferences. You can do that with the help of getPreferences() method of the activity. The getPreference method uses the getSharedPreferences() method with the name of the activity class for the preference file name.
Following is the code to get preferences
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
The code to store values is also same as in case of shared preferences.
SharedPreferences preferences = getPreference(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
You can also use other methods like storing the activity state in database. Note Android also contains a package called android.preference. The package defines classes to implement application preferences UI.
To see some more examples check Android's Data Storage post on developers site.
This method is only for saving state associated with a current instance of an Activity,are you switching to another activity and trying to get the values again when you return to this activity? i supposed that :: "I tried putting stuff in the onStop, but it crashes".
a recommendation, is NOT SAFE to use onSaveInstanceState() and onRestoreInstanceState(), according to http://developer.android.com/reference/android/app/Activity.html
consider using Sharedpreferences or SQLite database.
SharedPreferences Example (from webworld):
/**
* get if this is the first run
*
* #return returns true, if this is the first run
*/
public boolean getFirstRun() {
return mPrefs.getBoolean("firstRun", true);
}
/**
* store the first run
*/
public void setRunned() {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putBoolean("firstRun", false);
edit.commit();
}
SharedPreferences mPrefs;
/**
* setting up preferences storage
*/
public void firstRunPreferences() {
Context mContext = this.getApplicationContext();
mPrefs = mContext.getSharedPreferences("myAppPrefs", 0); //0 = mode private. only this app can read these preferences
}

Categories