I have a little project, one activity and two fragment. I have started from the "Bottom Navigation Activity" sample on a new projet.
The I use the Android Annotations (https://github.com/androidannotations/androidannotations/wiki) for injecting my fragment, It display correctly but when I rotate, I loose all my information and the app display the first fragment, even if I displayed the second one. I tried to save my data, from an edit text with a Bundle object, in the "onSaveInstanceState" method, I get back it in the "onActivityCreated" or in the "onCreate" method but after their method were re-call and my data desappear.
I don't know how to save which fragment was displayed and how re-displayed it with the android annotations.
In my Activity class I have those methods :
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
And in my main fragments :
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(dpdEditText != null){
rttNumberTemp = rttEditText.getText().toString();
outState.putString("rttNumberTemp", rttNumberTemp);
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(Tag, "onActivityCreated");
if(savedInstanceState != null){
Log.d(Tag, "onActivityCreated if");
updateEditText(rttEditText,savedInstanceState.getString("rttNumberTemp"));
}
}
So my question is how can I save my fragment, and its data and which fragment is displayed ?
I finally find my mistake. In my main activity I have the following method :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
So the program call the view by the injection and call it again with the setContentView. So I update the method like that :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
Related
I want to save my fragment with recycler view, to restore it whlie screen rotate. I was looking for instructions in the net and I get:
In my Fragment
private Parcelable recyclerViewState;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
list.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
recyclerViewState = layoutManager.onSaveInstanceState();
}
in my Activity
//onCreate
if (savedInstanceState != null) {
getSupportFragmentManager().getFragment(savedInstanceState, LIST_USERS_FRAGMENT);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().getFragment(outState, LIST_USERS_FRAGMENT);
}
I was debbuging and it looks fine, however while I rotate my screen I get blank fragment, with no recycler view. Could You help me investigate why it's happening ?
The default behavior in Android is destroying all the attached fragments on configuration changes. To bypass fragment recreation you should use setRetainInstance(true) in the OnCreate callback of the fragment.
There are a different options to handle the orientation changes:
Lock screen orientation
<activity
android:name="com.example.test.activity.MainActivity"
android:screenOrientation="portrait"/>
Prevent Activity to recreated
<activity
android:name="com.example.test.activity.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"/>
Save basic state
public class MainActivity extends Activity{
private static final String SELECTED_ITEM_POSITION = "ItemPosition";
private int mPosition;
#Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
// Save the state of item position
outState.putInt(SELECTED_ITEM_POSITION, mPosition);
}
#Override
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Read the state of item position
mPosition = savedInstanceState.gettInt(SELECTED_ITEM_POSITION);
}
}
Save complex objects
Override
onRetainNonConfigurationInstance()
getLastNonConfigurationInstance()
After API level 13 these methods have been deprecated in favor of the more Fragment’s setRetainInstance(boolean) capability, which provides a much cleaner and modular means of retaining objects during configuration changes.
I use an intent to start another activity to display data in an ArrayList.
After pressing the back button in the action bar, the values of the array list are lost.
How do I fix this?
The code I'm currently using:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putStringArrayList(X_COORDINATE, dataX);
savedInstanceState.putStringArrayList(Y_COORDINATE, dataX);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
dataX=savedInstanceState.getStringArrayList(X_COORDINATE);
dataY=savedInstanceState.getStringArrayList(Y_COORDINATE);
}
The first method is how I put my arraylists in to the Bundle, and the second method is how I restore it.
try this:
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putStringArrayList(X_COORDINATE, dataX);
}
And restore the values in onCreate():
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState!= null){
dataX=savedInstanceState.getStringArrayList(X_COORDINATE);
}
}
i have a problem with my app. if i click the button to stop the ProgressBarIndeterminate in actionbar, when i rotate the screen it reappear. can i stop it forever? thanks
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
setProgressBarIndeterminateVisibility(true);
}
public void test(View v) {
setProgressBarIndeterminateVisibility(false);
}
sorry for my english
When you rotate your screen, the Activity gets created again (onCreate will get invoked again), so you will call setProgressBarIndeterminateVisibility(true) which will make it reappear.
To keep track of whether or not you've clicked the stop button, you will need to save the state somehow (consider implementing onSaveInstanceState and then retrieving the stored value in onCreate, or saving the state to a shared preference/database).
onSaveInstanceState --> invoked when your Activity is torn down due to the rotation
private boolean showProgressBarVisibility = true; //always show the first time
#Override
public void onCreate(Bundle savedInstanceState){
if(savedInstanceState != null && savedInstanceState.containsKey("user3744384_pressed_the_button"){
showProgressBarVisibility = false
}
setProgressBarIndeterminateVisibility(showProgressBarVisibility);
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("user3744384_pressed_the_button", true);
}
do something like this in onCreate:
if(savedInstanceState !=null){
setProgressBarIndeterminateVisibility(false);
}
but you should also save the state in public void onSaveInstanceState(Bundle ...).. research on how activities save their state.
when orientation changes android kills your activity and onCreate is called.. you can save your app state and restore it.
override this method to save state
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(key, yourstatevariable);
}
and get your state variable in onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
if (savedInstanceState != null) {
String yourstatevariable = savedInstanceState.get(key);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.savedInstanceState = savedInstance;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
try {
Log.d("Equals?",savedInstanceState.equals(this.savedInstanceState));
} catch (Exception e) {
Log.d("Equals?",savedInstanceState==this.savedInstanceState);
}
}
Will this always\never or only on some cases log true?
EDIT:
after seeing Henry's comment, lets address my question as if Intent has overriden its equals and it does compare those objects content, not by references...
onCreate(Bundle) called to do initial creation of the fragment.
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
so we can say that Bundle savedInstanceState are same at both places.
for more visit
http://developer.android.com/reference/android/app/Fragment.html
http://developer.android.com/guide/components/fragments.html
you wrote
#Override
public void onCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.savedInstanceState = savedInstance;
}
i do not understand which lifecycle mehod is onCreated i think it should be onCreate and the lines should be
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....}
the ArrayList is defined on class level.
these are my savedInstance methods:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("savedList", list);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
list=savedInstanceState.getStringArrayList("savedList");
}
but still, when i change orientation the ArrayList is blank
When you use onRestoreInstanceState() to restore state, its called after onStart() so you update your list with the saved state after you define your adapter. Your best option is to restore the list in onCreate() the same way you do it on onRestoreInstanceState(). You can also redefine the adapter or call notifyDataSetChanged().
TextView textviewname;
String textname;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//declare the ui like this
textviewname = (TextView) findViewById(R.id.textviewid);
if(savedInstanceState==null){
//the first time the activity was created
//do the normal flow of the code
//Example:getting the intent data for(savedList)or processing it
Intent i = getIntent();
textname = i.getStringExtra("savetext");
//or textname="name_data";
}else{
//this is called when orientation change occur
//get the savedata
list=savedInstanceState.getStringArrayList("savedList");
textname=savedInstanceState.getString("savetext");
}
textviewname.setText(textname);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//saving data when orientation change trigger
//saving data before ondestroy happens
//onSaveInstanceState is called before going to another activity or orientation change
outState.putStringArrayList("savedList", list);
outState.putString("savetext", textname);
//all imnportant data saved and can be restored
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//this is only called after ondestroy-> oncreate occur
list=savedInstanceState.getStringArrayList("savedList");
textname=savedInstanceState.getString("savetext");
//oncreate->onSaveInstanceState->ondestroy->oncreate->onRestoreInstanceState
}
try to use
list.addAll(savedInstanceState.getStringArrayList("savedList"));
instead
list=savedInstanceState.getStringArrayList("savedList");