Replace with Fragment does not work properly

Asked

Viewed 488 times

6

I’m making a simple example with Fragments and what I need is that when I click the first button the app replace for Fragmen1 and when you click on the second button appear Fragment2.

When I start the application the Fragment I left set in XML appears normally, but the problem happens when I click on any of the buttons to replace a Fragment, then it happens:

Início da aplicação

Depois que clico no botão 1

What happens is that the Fragment that was in the beginning does not disappear, simply stands on top of the space reserved for the Fragments.

Follow Xmls and Classes:

public class MainActivity extends Activity {

Button btn1, btn2;
FragmentManager fm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn1 = (Button) findViewById(R.id.btnFrag1);
    btn2 = (Button) findViewById(R.id.btnFrag2);

    fm = getFragmentManager();

    btn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Fragmento1 f1 = new Fragmento1();
            FragmentTransaction transaction = fm.beginTransaction();
            transaction.addToBackStack(null);
            transaction.replace(R.id.fragmentPlace,f1);
            transaction.commit();
        }
    });

    btn2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Fragmento2 f2 = new Fragmento2();
            FragmentTransaction transaction = fm.beginTransaction();
            transaction.replace(R.id.fragmentPlace,f2);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });
}

public class Fragmento1 extends Fragment {

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



public class Fragmento2 extends Fragment {

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

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="vertical"
    android:gravity="center">
    <Button
        android:id="@+id/btnFrag1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment 1"/>

    <Button
        android:id="@+id/btnFrag2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment 2"/>
</LinearLayout>

<LinearLayout
    android:id="@+id/fragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
    <fragment
        android:id="@+id/fragmentPlace"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.dideconto.exemplofragmentsimples.Fragmento2"></fragment>
</LinearLayout>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Fragmento 2"/>

I wish I knew where I was going wrong.

1 answer

6


As I quoted in the comment, "You’re giving replace in the Fragment, but you have to do replace in a FrameLayout". In fact the replace does not exchange the element but the content of the element. It would be something like this adapting your example:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="vertical"
    android:gravity="center">
    <Button
        android:id="@+id/btnFrag1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment 1"/>

    <Button
        android:id="@+id/btnFrag2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment 2"/>
</LinearLayout>

<!-- Troque de LinearLayout para FrameLayout -->
<FrameLayout
    android:id="@+id/fragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
    <fragment
        android:id="@+id/fragmentPlace"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.dideconto.exemplofragmentsimples.Fragmento2"></fragment>
</FrameLayout>

At the click of the button, instead of giving replace in the Fragment of replace in the content of FrameLayout:

Fragmento1 f1 = new Fragmento1();
FragmentTransaction transaction = fm.beginTransaction();
transaction.addToBackStack(null);
// troque o replace do Fragment  "fragmentPlace" para o FrameLayout "fragmentContainer"
transaction.replace(R.id.fragmentContainer,f1);
transaction.commit();

Note: I didn’t test, so there may be some syntax errors, but the idea is basically this.

  • It worked perfectly! But I have just one question, the fragment in XML serves only for the app to start with a content?

  • @user3010958, yes! But I don’t usually use in my application, Fragment via code when starting Activity. leaving in XML the FrameLayout empty. But this is way of implementing. =)

  • Got it, thank you very much! It really helped a lot. It has some link to understand the pq of Framelayout and not the other types of layout?

  • @user3010958, I believe other elements that accept child elements (Child), may also be used, although in all official matters I have seen, it is always used FrameLayout as container of Fragments, as an example in this material.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.