Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragments and rotating screen problems

i have a problem with fragments and rotating screen. I read this threads, and it didn't solve my problem:

Fragment without a view crashes on configuration change (isn't exactly the same)

IllegalStateException when replacing a Fragment (not solve my problem)

I have only one activity:

public class MainActivity extends FragmentActivity implements TabSelectedListener {

    /** Application tab menu */
    private TopMenu menu;


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

        menu = (TopMenu) this.findViewById(R.id.menu);
        menu.setListener(this);


    }//onCreate

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
    }

    public void tabSelected(int tab) {

        FragmentManager fragmentManager = this.getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment f = null;

        boolean logged = DataController.getInstance().getLogged();

        switch(tab){
        case TopMenu.TAB1:
            if( !logged ){
                f = new HomeFragment();
            }else{
                f = new AccountsFragment();
            }
            break;
        case TopMenu.TAB2:
                     // i create more fragments depending the tab
        }   

        if( f != null){

            // Replace whatever is in the fragment view with this fragment,
            // and add the transaction to the back stack
            fragmentTransaction.replace(R.id.fragment, f);
            fragmentTransaction.addToBackStack(null);

            // Commit the transaction
            fragmentTransaction.commit();
        }

    }//tabSelected

    public void setSelectedTab(int tab){
        menu.setSelectedTab(tab);
    }


 .....
}

And the code of the fragment is:

public class HomeFragment extends Fragment implements OnClickListener{

    private static final String KEY_STATE_BUNDLE = "HomeFragmentManagerState";

    private LocalActivityManager mLocalActivityManager;

    View homeRelative;
    View homeLocked;
    View homeUnlocked;

    EditText id;
    Button ok;
    ImageView lock;
    CheckBox remember;

    private boolean lock_state;



    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Bundle state = null;
            if (savedInstanceState != null) {
                state = savedInstanceState.getBundle(KEY_STATE_BUNDLE);
                lock_state=savedInstanceState.getBoolean("lock_state");
            } else {
                lock_state=true;
            }

            mLocalActivityManager = new LocalActivityManager(getActivity(), true);
            mLocalActivityManager.dispatchCreate(state);
        }  


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        homeRelative = view.findViewById(R.id.home_relative);
        homeLocked = view.findViewById(R.id.ly_home_buttonlogin);
        homeLocked.setOnClickListener(this);

        homeUnlocked = view.findViewById(R.id.ly_home_buttonlogin_unlocked);
        id = (EditText) view.findViewById(R.id.userid);

        ok = (Button) view.findViewById(R.id.useridok);
        ok.setEnabled(false); // ?? if id.equalsIgnoreCase("")
        ok.setOnClickListener(this);
        lock = (ImageView) view.findViewById(R.id.iv_home_candado);
        lock.setOnClickListener(this);

        if (!lock_state)
            animateLogon(true);

        remember = (CheckBox) view.findViewById(R.id.remember);

        id.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable s) {

                ok.setEnabled(!id.getText().toString().equalsIgnoreCase(""));

                id.setBackgroundResource(R.drawable.bordercolorblack_rightsquare);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        }); 

        return view; 

    }

....

And only when I change the tab, and after I rotate my device, I get one FC and the logcat is this:

10-01 14:04:07.561: E/AndroidRuntime(11759): FATAL EXCEPTION: main
10-01 14:04:07.561: E/AndroidRuntime(11759): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.stkaction.sov/com.stkaction.sov.MainActivity}: android.view.InflateException: Binary XML file line #12: Error inflating class fragment
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3362)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.access$700(ActivityThread.java:127)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1162)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.os.Looper.loop(Looper.java:137)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.main(ActivityThread.java:4511)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at java.lang.reflect.Method.invokeNative(Native Method)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at java.lang.reflect.Method.invoke(Method.java:511)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at dalvik.system.NativeStart.main(Native Method)
10-01 14:04:07.561: E/AndroidRuntime(11759): Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class fragment
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:272)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.Activity.setContentView(Activity.java:1835)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at com.stkaction.sov.MainActivity.onCreate(MainActivity.java:29)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.Activity.performCreate(Activity.java:4470)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
10-01 14:04:07.561: E/AndroidRuntime(11759):    ... 12 more
10-01 14:04:07.561: E/AndroidRuntime(11759): Caused by: java.lang.IllegalStateException: Fragment com.com.stkaction.sov.HomeFragment did not create a view.
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:293)
10-01 14:04:07.561: E/AndroidRuntime(11759):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:669)
10-01 14:04:07.561: E/AndroidRuntime(11759):    ... 22 more

Thanks to all.

like image 294
moskis Avatar asked Oct 01 '12 12:10

moskis


1 Answers

I found the solution. When you use dynamic fragments, you must use a layout, and put the fragment inside it.

For example: The main activity use this layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:id="@+id/activity_main_layout">

    <com.myproyect.TopMenu
        android:id="@+id/menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    />

    <!-- this was the problem
    <fragment 
        android:id="@+id/fragment"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        class="com.myproyect.HomeFragment"
        android:layout_below="@id/menu"
    />  -->

    <FrameLayout android:id="@+id/fragment"
            android:layout_width="match_parent" android:layout_height="match_parent" 
            android:layout_below="@id/menu"/>

    <LinearLayout
        android:id="@+id/menu_layout"
        android:layout_width="175dp" 
        android:layout_height="wrap_content"
        android:background="@drawable/menu_filtros" 
        android:layout_marginRight="5dp"
        android:layout_below="@id/menu"
        android:layout_marginTop="-47dp"
        android:layout_alignParentRight="true"
        android:visibility="gone"
        android:orientation="vertical">
    </LinearLayout>
</RelativeLayout>

And I instantiate the fragment inside the FrameLayout.

fragmentTransaction.replace(R.id.fragment, f);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
like image 51
moskis Avatar answered Oct 14 '22 14:10

moskis