I have tried a every solution I can find and am not having any luck. I have multiple dynamic textViews that change not only text but formatting such as alpha, strike-through... I can not find a reliable way to save this information through screen rotation. I am self taught and new my head is spinning...
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new UIrFragment())
.commit();
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
setRetainInstance(true);
Log.i(Tag, "onCreateView");
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
ImageView background = (ImageView) getView().findViewById(R.id.background);
background.setImageResource(R.drawable.starrynightblurry);
setupKeyBoard(); // multiple textViews get set up here. Want to save this
setupGame();// same here
}
Apparently when using setRetainInstance(true), the Bundle for onRestoreInstanceState is null.
store text views in
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
//store here
}
Restore text view from here
#Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
// restore here
}
hope this helps you
Add below line in activity_main.xml
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation" >
either fix screen orientation to either landscape or portrait in your AndroidManifest.xml like this:
android:screenOrientation="portrait"
or handle the configChanges like this:
android:configChanges="orientation|keyboardHidden|smallestScreenSize|uiMode"
should be added as an attribute of the <activity> tag in the manifest. The configChanges is used to specify configuration changes that the activity will handle itself.
Edit: for handling config changes in Fragments, please see this question.
Related
Hello I've a problem when using my app on the phone, when I rotate the screen inside the app the webview reloads all content getting back to the first page we were opening the app.
I leave you a gif of what happens here and if you know a solution please help me. I also leave my main class and the android manifest.
Proof Video
Main.java
AndroidManifest.xml
Add android:configChanges="orientation|screenSize" in your Manifest.xml file
Like below:
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="#string/title_activity"
android:theme="#style/AppTheme.MyTheme">
</activity>
Create a fragment to wrap your WebView up. Always return the same WebView in onCreateView, so that a new WebView would not be created on orientation change, thus not reloading.
public class MyWebViewFragment extends Fragment {
private WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onResume() {
super.onResume();
mWebView.onResume();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mWebView == null)
mWebView = new WebView(getActivity());
ViewGroup parent = (ViewGroup) mWebView.getParent();
if (parent != null)
parent.removeView(mWebView);
return mWebView;
}
}
Add this fragment to your activity.
This question already has answers here:
How to retain EditText data on orientation change?
(12 answers)
Closed 5 years ago.
I have already posted this question once and even tried all possible solutions. So please, if are going to downvote, at least provide the correct answer because I have tried out many solutions and nothing is working out.
In my app, I have an EditText inside the fragment which on orientation change, looses its value.One more thing, I am using different layouts for different orientations. Is there any way to retain the fragment data? I am again mentioning "Fragment data".Please find my Fragment code below for further reference.
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("fname",etxt_firstname.getText().toString());
outState.putString("lname",etxt_lastname.getText().toString());
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState!= null)
{
etxt_firstname.setText(savedInstanceState.getString("fname"));
etxt_lastname.setText(savedInstanceState.getString("lname"));
}
}
Inside OnCreateView():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
shrp_sharedpreferences = myContext.getSharedPreferences("shrp", Context.MODE_PRIVATE);
View view = null;
if(!isTablet(myContext))
{
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
view = inflater.inflate(R.layout.fragment_home_landscape, container, false);
}
else
{
view = inflater.inflate(R.layout.fragment_home, container, false);
}
}
else
{
view = inflater.inflate(R.layout.fragment_home, container, false);
}
Even though the fragment itself is retained, its view is destroyed when device is rotated in onDestroyView() (You should also clear any references to views there to prevent leaking old orientation).
Trying to restore text in onActivityCreated() does nothing because you're referencing views from old orientation, and they aren't used anymore.
When fragment is reattached (in Activity created for new orientation), new View is created in onCreateView() - this is where you can use savedInstanceState or any fragment fields to restore views to previous state:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// (...) your layout inflation and view binding logic...
if(savedInstanceState != null){
etxt_firstname.setText(savedInstanceState.getString("fname"));
etxt_lastname.setText(savedInstanceState.getString("lname"));
}
// return view you inflated
}
this is my issue, when I create a fragment in android for example let's Say:
GastosSectionFragment gastosFragment = new GastosSectionFragment();
Fragment.gastosFragment.darUserID(userKey);
I send a simple Integer to that activity, no problem. For example lets say I send the number 1. It will be stored in attribute inside that class, because I create the fragment.
Everything will work fine, I receive the number. But when I rotate the phone, the variable "userKEY will be lost, it will converted to cero" I can't save that number when I rotate horizontally my phone, how can I save the data of that variable.
Here I put the code of how I recieve the "userKey" inside the Fragment,
public long darUserID(long userKey) {
// TODO Auto-generated method stub
return user_id = userKey;
}
And the attribute with the onCreate method.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_section_gastos,
container, false);
idStatico = darUserID(user_id);
And I can't save that little number. this is not a FragmentActivity, this class is just a FRAGMENT. First time fine, rotate screen lost the number that I previously recieve. Fragment doesn't have OnSaveBundleInstances.
Fragment can save user_id in bundle in onSaveInstanceState method and restore after orientation change in onCreateView method. Check this fragment guide, especially in example is shown saving fragment state.
Activity code stays the same (I just changed method name) and your fragment should look like this:
class GastosSectionFragment extends Fragment {
private static final String BUNDLE_USER_ID = "BUNDLE_USER_ID";
private long user_id;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_section_gastos, container, false);
if (savedInstanceState != null)
user_id = savedInstanceState.getLong(BUNDLE_USER_ID);
// now is your user_id restored after orientation change,
// so you can do some stuff with it
return rootView;
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(BUNDLE_USER_ID, user_id);
}
public long setUserID(long userKey) {
this.user_id = userKey;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
add method override, and you variable saving state
After KOSO answer, this is how I solve the problem, hope it helps someone else.
When I create the Fragment for first time everything work well, send the userKey, everything is fine.
GastosSectionFragment gastosFragment = new GastosSectionFragment();
Fragment.gastosFragment.darUserID(userKey);
Now in order to fix that, a fragment when the phone is rotated, for example to horizontal it will call the override method OnCreateView(). Everytime when you rotate the phone this method will be called.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_section_gastos,
container, false);
//This is not null when we rotate the screen, first we save the Bundle SavedInstance
//After do that we put a integer, in this case the userKey
//then we recover the user key, and everything will work fine.
if (savedInstanceState != null)
{
this.savedInstanceState = savedInstanceState;
savedInstanceState.putInt("userKey", (int) idStatico);
idStatico = savedInstanceState.getInt("userKey");
}
//this will be null for the first time, only the first time this will bse used.
if (savedInstanceState == null)
{
idStatico = darUserID(user_id);
}
//Do the rest of the work
}
I've got a ViewGroup which will fire onRestoreInstanceState() if inflated by my activity
setContentView(). If I try to inflate it with getLayoutInflater().inflate(), then it won't.
I've tried to set an ID for it as said in Restoring view hierarchy from saved state does not restore views added programatically. I also have an ID in the layout file, and getID() returns the same every activity recreation, yet it won't restore nor save the instance state.
How can I overcome this?
(Edit) Code I'm using at the moment:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.main); //this code will work as intended
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
View content = getLayoutInflater().inflate(R.layout.main, null);
setContentView(content); //this code will also work
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.another_layout);
View content = getLayoutInflater().inflate(R.layout.main, null); //now this view won't fire the method
}
The point is that I don't want to use that view as my layout for the activity. I need to inflate it some other way.
am currently messing around with DialogFragment to learn to use it. I assumed that compared to onCreateView(), onCreate() can do this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testTextView.setText("SUCCESS!"); //ERROR HERE
}
But I am wrong. Not sure why its not working. The error goes away when I comment out testTextView.setText("Success!"); The error is a NullPointerException, and then it just flags line 39 which is where the offending line of code is. Any clarifications much appreciated.
Try this :
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (container == null) {
return null;
}
return (LinearLayout)inflater.inflate(R.layout.your_fragmentlayout_file, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstance)
{
super.onActivityCreated(savedInstance);
TextView testTextView = (TextView)getActivity().findViewById(R.id.your_textview_id);
testTextView.setText("SUCCESS!");
}
where you initalzed testTextView. ? you should do that.........
and also as per fragment life cycle
onAttach(Activity)-->onCreate(Bundle) -->onCreateView(LayoutInflater, ViewGroup, Bundle)->onActivityCreated(Bundle)-->onStart()
so you should handle this work either in onCreateView or after this...
http://android-developers.blogspot.in/2012/05/using-dialogfragments.html