It's taken me some time to wrap my head around fragments, but this should be my last question on fragments, since I think I just about have them down. I know this is a huge mess of code to go through. But I'd appreciate the help, to make sure I'm not breaking any fundamental rules with fragments.
I am going to post all of my code just to see if someone can "look over it" to see if I'm making any major mistakes or if I should go a simpler route. Lastly, as stated in the title, my fragment is NOT being replaced... it'd being added on top.
File Tree:
MainActivity.java:
package com.example.learn.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends FragmentActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
/* Add a class to handle fragment */
public static class SSFFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.choose_pill_frag, container,
false);
return v;
}
}
public void red(View view) {
// Create new fragment and transaction
ExampleFragments newFragment = new ExampleFragments();
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frag, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
public void blue(View view) {
//Figure out code for "red" first
}
}
ExampleFragments.java:
package com.example.learn.fragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ExampleFragments extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.red_pill_frag, container, false);
}
}
ActivityMain.xml:
<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" >
<fragment
android:id="@+id/frag"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.learn.fragments.MainActivity$SSFFragment" />
</RelativeLayout>
choose_pill_frag.xml
<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" >
<ImageButton
android:id="@+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="blue"
android:src="@drawable/blue" />
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="red"
android:src="@drawable/red" />
</RelativeLayout>
red_pill_frag.xml
<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" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="You stay in Wonderland and I show you how deep the rabbit-hole goes."
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
The application should show two buttons. The two buttons exist in a single fragment, and then if you hit a button, the fragment gets replaced with a new fragment that shows the proper text. As of right now, it should replace, but it only seems to add it on top.
Instead of <fragment>
use <FrameLayout>
in layout xml for activity.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_id"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Then in FragmentActivity
in onCreate
add initial fragment (in your case SSFFragment
):
FragmentA fragmentA = new FragmentA();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.container_id, fragmentA);
transaction.commit();
From inside fragment you can replace fragment in container.
class FragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Button button = new Button(getActivity());
button.setText("Replace");
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
FragmentB fragmentB = new FragmentB();
transaction.replace(R.id.container_id, fragmentB);
transaction.commit();
}
});
return button;
}
}
Here is the answer to your real question...since this was your second question resulting from your original post, I've modified the solution to get at that frag in another way:
Fragment details = (Fragment)getSupportFragmentManager().findFragmentById(R.id.details);
details = new ExamplesFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
Also, the android.support.v4.app part is just not necessary, and frankly leads to possible hours of "going down the wrong road" type efforts by adding and removing it all over your code (as long as you're using:)
import android.support.v4.app.FragmentTransaction;
In this my example, you don't need to import the support for FragmentManager. However, if you're getting errors, make sure you've imported the library itself into your "libs" folder.
This solution will fix the overlapping fragment problem, and hopefully save people hours of tinkering around with replacing frags.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With