简体   繁体   中英

Switching between Fragments with button

In my app, I have one activity and two fragments. What I'm trying to do, is to navigate between this two fragments back or front with button. Each navigate button is defined in fragment.

The first problem is, with the code that is below, I get the exception on application run:

E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{...MainActivity}: 
            java.lang.IllegalArgumentException: No view found for id 0x7f0c0050 for fragment Fragment1{b41da690 #0 id=0x7f0c0050}
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0c0050 for fragment Fragment1{b41da690 #0 id=0x7f0c0050}
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:823)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
        at android.app.BackStackRecord.run(BackStackRecord.java:635)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
        at android.app.Activity.performStart(Activity.java:5017)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 

CODE:

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        // set desired fragment for the first time
        setFragment(this, new Fragment1());
    }

    public void switch_fragment(View view, String fragmentID) {
        Fragment newFragment = null;
        switch (fragmentID) {
            case Fragment1.ID:
                newFragment = new Fragment1();
                break;
            case Fragment2.ID:
                newFragment = new Fragment2();
                break;
        }
        setFragment(this, newFragment);
    }

    public static void setFragment(Activity activity, Fragment fragment) {
        FragmentTransaction fragmentTransaction = activity.getFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_placeHolder, fragment);
        fragmentTransaction.commit();
    }
}

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fragment_placeHolder"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment1"
        />
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment2"
        />
</RelativeLayout>

Fragment1.java

public class Fragment1 extends Fragment {

    public static final String ID = "1";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment1, container, false);
    }

}

fragment1.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GO TO FRAGMENT 1"
        android:id="@+id/btn_1"
        android:onClick="switch_fragment"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        />
</RelativeLayout>

Fragment2.java

public class Fragment2 extends Fragment {

    public static final String ID = "2";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment2, container, false);
    }

}

fragment2.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GO TO FRAGMENT 2"
        android:id="@+id/btn_2"
        android:onClick="switch_fragment"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        />
</RelativeLayout>

If this sample is wrong way of achieving this, can you please link some similar example for newbie.

You missed a very important part is setContentView and before using replace you should have an existing fragment. So in onCreate change:

// set desired fragment for the first time
        setFragment(this, new Fragment1());

Should be changed to:

   setContentView(R.layout.main_activity);//then
   // set desired fragment for the first time
   FragmentManager fm = getSupportFragmentManager();
   FragmentTransaction ft = fm.beginTransaction();

    // The id specified here identifies which ViewGroup to
    // append the Fragment to.
    ft.add(R.id.fragment_placeHolder, new Fragment1());
    ft.commit();

Try to replace:

... activity.getFragmentManager()

With:

... getSupportFragmentManager()

and remove:

<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment1"
    />
<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment2"
    />

Finally, change the switch_fragment to:

public void switch_fragment(View view) {
        Fragment newFragment = null;
        switch (view.getID()) {
            case R.id.btn_2:
                newFragment = new Fragment1();
                break;
            case R.id.btn_1:
                newFragment = new Fragment2();
                break;
        }
        setFragment(this, newFragment);
    }

remove below code from your activity layout file,

<fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment1"
        />
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment2"
        />

Also please use below in your fragment before your return statement,

super.onCreateView(inflater, container, savedInstanceState);

and try to run your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM