Reputation: 1857
I am using an EditText under the Material Design and I am having problems in screen orientation. I was able to save the content onSavedInstanceState and reinstate back what was written on edittext back again but there seems to be a bug-like behavior going on.
Look at these following pics:
Original orientation when activity start:
When I rotate the screen, I still get a hold of the content but when I place the carret on an existing text span, it returns the carret to 0 (Beginning of edit text) and then when I typed something it looks like this:
I encountered this situation once and that was very long time ago. IIRC I was able to solve it by completely replacing the content onCreateView's savedInstanceState, it doesn't seem to work anymore.
Any ideas?
[EDIT] A lot of people will be expecting to answer "ONCONFIGURATIONCHANGED". No please, this is not merely the solution for the underlying problem. In fact, I tried it and didn't work, don't want to implement that solution anyways. I believe this doesn't warrant band aid solution, at least as a last resort.
Read the answer to this: Why not use always android:configChanges=“keyboardHidden|orientation”?
Here is my layout file for the 'Fragment' containing the edit text:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".HomeScreenActivity"
android:weightSum="1">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingtoolbarlayout_note"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_note"
android:layout_width="match_parent"
android:layout_height="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin">
....
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/edittext_note"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:gravity="top"
android:freezesText="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp" />
<include
layout="@layout/layout_rte_toolbar_black_icon"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="bottom"
android:layout_weight="0.60"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Next here is my Activity layout, a very simple layout actually:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/framelayout_note"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Here is create method callback for Activity:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.i("NoteActivity.OnCreate" , TAG);
setContentView(R.layout.activity_note);
NoteFragment fragment = NoteFragment.createInstance();
fragment.setOnToolbarButtonSelected(this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.framelayout_note , fragment)
.commit();
}
Here is the create/onSavedInstanceState method callback for the fragment
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.i("NoteFragment.onCreateView", TAG);
if(savedInstanceState != null)
{
mTitle = savedInstanceState.getString(KEY_EDITTEXT_TITLE, TAG);
mContent = Html.fromHtml(savedInstanceState.getString(KEY_EDITTEXT_CONTENT, TAG));
}
mNoteDataController = ((NotifireApplication) getActivity().getApplication()).getNoteDataController();
setHasOptionsMenu(true);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater , ViewGroup parent, Bundle savedInstanceState)
{
Log.i("NoteFragment.onCreateView", TAG);
View view = inflater.inflate(R.layout.fragment_note, parent, false);
mNoteContent = (EditText) view.findViewById(R.id.edittext_note);
mNoteTitle = (EditText) view.findViewById(R.id.edittext_note_title);
if(mContent != null) mNoteContent.setText(mContent);
if(mTitle != null) mNoteTitle.setText(mTitle);
initToolbar(view);
return view;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
Html.toHtml(mNoteContent.getText());
savedInstanceState.putString(KEY_EDITTEXT_CONTENT, Html.toHtml(mNoteContent.getText()));
savedInstanceState.putString(KEY_EDITTEXT_TITLE, mNoteTitle.getText().toString());
super.onSaveInstanceState(savedInstanceState);
}
Upvotes: 1
Views: 172
Reputation: 7210
When the screen orientation changes, two instances of NoteFragment are being created and added to the container view. This is your root problem. One NoteFragment is being created and added by FragmentActivity#onCreate. Another NoteFragment is being created in the onCreate callback of your activity which subclasses FragmentActivity.
You can fix this by checking whether savedInstanceState is null before adding your fragment in onCreate. If savedInstanceState is null, then add your fragment. If not, then the activity is being re-created after a configuration change and the logic of FragmentActivity will restore fragments fro you, so do nothing.
Upvotes: 1
Reputation: 726
Got the problem. Actually All this work that you have done in fragment should have been done in activity. In this scenario since you are using frame layout, I think what is happening is that your old fragment is in place and once you rotate the device a new instance of fragment gets created and placed above it.
In my opinion this is the reason why your older text is there which is actually in your previous fragment. My opinion is either handle onConfiguration change and don't create new fragment on orientation change.
Second if you want to test what I'm saying is you can use linearlayout with vertical orientation and you will see that there are two fragments.
Upvotes: 1
Reputation: 1503
In the onConfigurationChanged()
First Get the data of your Edit text into a global variable and then call setContentView()
and now set the Data into your Edit text.
This should work.
Upvotes: -1