1

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: enter image description here

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:

enter image description here

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);
}
Community
  • 1
  • 1
Neon Warge
  • 1,817
  • 6
  • 29
  • 53

3 Answers3

1

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • Thanks for the answer but my main concern it not entirely retaining the edit text or putting carrets where I want it etc. I am explaining the behavior that causes text to overlapped another text. That is my main problem hence the 2nd picture. – Neon Warge Feb 13 '16 at 07:48
  • check my updated answer this is the reason for the vague behaviour. – Damanpreet Singh Feb 13 '16 at 08:22
  • You beat me to it! Spot on! – Neon Warge Feb 13 '16 at 08:41
  • You are exactly right. This is what is causing my problem. In practice I always employ the use of fragment when dealing with layouts, some of the layouts I am using pre-material design are using fragments and now decided to use the awesome-power of paper design in Android. I guess they are incompatible? Do you have an idea how can I get CoordinatorLayout to work with Fragment? – Neon Warge Feb 13 '16 at 10:04
1

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.

Brendan Weinstein
  • 6,938
  • 7
  • 25
  • 29
-1

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.

CandleCoder
  • 1,387
  • 4
  • 21
  • 45
  • Thanks for your answer. But, I don't like to go to onConfigurationChanged area, that will be my last resort. It is not normally used to fix this kind of problem. – Neon Warge Feb 13 '16 at 03:48
  • Yes, I know but somehow this was the way I solved mine problem. – CandleCoder Feb 13 '16 at 03:52