Search code examples
androidandroid-layoutandroid-fragmentsandroid-lifecyclescreen-rotation

Android TextView content lost even though android:freezesText is set to true


I have a single activity with two fragments. The activity has different layouts for portrait and for landscape, but the fragments remain the same (created with tags and reused). In one of the fragments I have xml defined textview, and it has the android:freezesText="true" line, but it still looses the text after screen rotation. Why could this happen?

The fragment's layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tvDisplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/dip10"
        android:freezesText="true"
        android:gravity="center"
        android:text="@string/hello_world"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

The fragment's class:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class DisplayFrag extends Fragment {

    @Override
    public View
            onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.display_frag, container, false);
        TextView tvDisplay = (TextView) view.findViewById(R.id.tvDisplay);
        tvDisplay.setText(getArguments().getString(Keys.NAME)
                + ", how are you? your phone number is " + getArguments().getString(Keys.PHONE));
        return view;
    }
}

The activity:

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fragMan = getSupportFragmentManager();
        InputFrag inputFrag = (InputFrag) fragMan.findFragmentByTag(Keys.TAG_INPUT_FRAG);
        if (inputFrag == null) {
            fragMan.beginTransaction().add(R.id.hook1, new InputFrag(), Keys.TAG_INPUT_FRAG)
                    .commit();
        } else {
            fragMan.beginTransaction().replace(R.id.hook1, inputFrag, Keys.TAG_INPUT_FRAG).commit();
        }
    }

    public void submit(View view) {
        FragmentManager fragMan = getSupportFragmentManager();
        DisplayFrag displayFrag = (DisplayFrag) fragMan.findFragmentByTag(Keys.TAG_DISPLAY_FRAG);
        if (displayFrag == null) {
            displayFrag = new DisplayFrag();
            displayFrag = putBundle(displayFrag);
            fragMan.beginTransaction().add(R.id.hook2, displayFrag, Keys.TAG_DISPLAY_FRAG).commit();
        } else {
            fragMan.beginTransaction().replace(R.id.hook2, displayFrag, Keys.TAG_DISPLAY_FRAG)
                    .commit();
        }

    }

    private DisplayFrag putBundle(DisplayFrag displayFrag) {
        Bundle bundle = new Bundle();
        bundle.putString(Keys.NAME, ((EditText) findViewById(R.id.etName)).getText().toString());
        bundle.putString(Keys.PHONE, ((EditText) findViewById(R.id.etPhone)).getText().toString());
        displayFrag.setArguments(bundle);
        return displayFrag;
    }
}

(submit responds to a button on the other fragment, which behaves correctly).


Solution

  • Found a solution: no need to .replace() the fragments at all. here is the new code for MainActivity and DisplayFrag:

    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentManager;
    import android.view.View;
    import android.widget.EditText;
    
    public class MainActivity extends FragmentActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            FragmentManager fragMan = getSupportFragmentManager();
            InputFrag inputFrag = (InputFrag) fragMan.findFragmentByTag(Keys.TAG_INPUT_FRAG);
            if (inputFrag == null) {
                fragMan.beginTransaction().add(R.id.hook1, new InputFrag(), Keys.TAG_INPUT_FRAG)
                        .commit();
            }
    
            DisplayFrag displayFrag = (DisplayFrag) fragMan.findFragmentByTag(Keys.TAG_DISPLAY_FRAG);
            if (displayFrag == null) {
                fragMan.beginTransaction().add(R.id.hook2, new DisplayFrag(), Keys.TAG_DISPLAY_FRAG)
                        .commit();
            }
        }
    
        public void submit(View v) {
            String name = ((EditText) findViewById(R.id.etName)).getText().toString();
            String phone = ((EditText) findViewById(R.id.etPhone)).getText().toString();
            if (!"".matches(name) && !"".matches(phone)) {
                FragmentManager fragMan = getSupportFragmentManager();
                DisplayFrag displayFrag =
                        (DisplayFrag) fragMan.findFragmentByTag(Keys.TAG_DISPLAY_FRAG);
                if (displayFrag != null) {
                    displayFrag.display(name, phone);
                }
            }
        }
    }
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    public class DisplayFrag extends Fragment {
    
        @Override
        public View
                onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.display_frag, container, false);
            return view;
        }
    
        public void display(String name, String phone) {
            TextView tvDisplay = (TextView) getActivity().findViewById(R.id.tvDisplay);
            tvDisplay.setText(name + ", how are you? your phone number is " + phone);
        }
    
    }
    

    Accepting my answer for now. If anyone has any other answer, advice or knowledge to share, I'll happily accept different answers.