0

I am now practicing on ViewPager and Fragments but I am facing an issue with replacing fragment to one another.

It is working well with swiping screen to move to another fragment, but I also wanted to try out if I can do this with a button too.

So I added a button, and tried to use FragmentManager's replace() method.

But what it actually does is not replacing the fragment but adding the fragment on the current fragment.

In a simple word, it overlaps.

Could not really find anything helpful for hours now, can anyone please help me with it?

Here is my code of the fragment that has the button:

public class MainActivity extends Fragment {

    Fragment fragment;
    FragmentManager fragmentManager;
    FragmentTransaction fragmentTransaction;

    Button buildButton;
    private ViewPager viewPager;

    public static Fragment newInstance(Context context) {
        MainActivity mainActivity = new MainActivity();
        return mainActivity;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.main, null);
        return root;
    }

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

        buildButton = (Button) getView().findViewById(R.id.buildButton);
        buildButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragment = new SecondActivity();
                fragmentManager = getActivity().getSupportFragmentManager();
                fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.calendarActivity, fragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
            }
        });
    }
}

And this is the xml file of the fragment:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <fragment class="com.example.auclo.calendarpractice5.MainActivity"
        android:id="@+id/calendarActivity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <Button
        android:id="@+id/buildButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="100dp"
        android:layout_marginEnd="148dp"
        android:layout_marginStart="148dp"
        android:layout_marginTop="16dp"
        android:text="Track"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/calendarView" />

</android.support.constraint.ConstraintLayout>

And this is the fragment that I want to replace to:

public class SecondActivity extends Fragment {

    TextView textView;

    public static Fragment newInstance(Context context) {
        SecondActivity secondActivity = new SecondActivity();
        return secondActivity;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.activity_second, null);
        return root;
    }

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

        textView = getView().findViewById(R.id.textView);
    }
}

And xml of the second fragment:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".SecondActivity">
<fragment class="com.example.auclo.calendarpractice5.SecondActivity"
    android:id="@+id/secondActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pikachu"
    android:textSize="18sp" />
</RelativeLayout>

I will really appreciate to any kind of help.

Thank you!

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Auclown
  • 179
  • 1
  • 3
  • 20

2 Answers2

0

The issue is that you're replacing the element with ID calendarActivity with your new fragment. This element is inside the XML for your first fragment (I think, based on your post). So it's putting this fragment in your old fragment.

You'll need to instead use the id in R.layout.main that represents your first fragment. I usually use a framelayout for this. Then I have the activity replace that framelayout with a fragment in its onCreate().

rexar5
  • 470
  • 2
  • 10
  • R.layout. cannot be put in replace() method, it only takes id as parameter. Do you mean I better use Framelayout instead of fragment inside the xml file? And how do you do the thing that you wrote on the last sentence of your answer? – Auclown Sep 24 '18 at 18:56
  • 1
    I think you misunderstood me. So your activity has an R.Layout file. This file has a layout inside of it that either is a fragment or serves as a container for a fragment. The fragment then has its own layout file and so does your second fragment. So we should be working with 3 layouts. From what I can tell, you only posted the 2 fragment layouts. It looks like you are actually inserting the second fragment layout inside of the first instead of inserting it into the activity layout in the spot where the first fragment lives. – rexar5 Sep 25 '18 at 19:26
  • 1
    The last sentence just means you can replace any type of layout with a fragment. I usually use a FrameLayout in my activity and give it the id "fragmentContainer" or something similar. Then I have the Activity replace it with an instance of the fragment in its onCreate method. Then you can have that button replace the same fragmentContainer with a different fragment instance. The best way to do this is through an interface and let the Activity manage its fragments. https://developer.android.com/training/basics/fragments/communicating – rexar5 Sep 25 '18 at 19:28
0

To add the same visual effects, you have to add a animation to your fragmentTransaction

Exemple:

fragmentTransaction.setCuston(
                    R.anim.enter_from_right,
                    R.anim.exit_to_left);

See this answer for explanation on fragments animations

Ruann Reis
  • 159
  • 8