My problem is that I want to remove a Fragment from an Activity. There are two steps:
Adding the Fragment into a FrameLayout (R.id.frame_for_des_details) by checking the CheckBox.
Removing the Fragment by clicking a TextView
public class CreateTripActivity extends FragmentActivity {
//Vars for Destination Fragment
private CheckBox checkBox;
private DestinationDetailsFragment destinationDetailsFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the ContentView
setContentView(R.layout.activity_create_trip);
//Set the Destination Checkbox listener
checkBox = (CheckBox) this.findViewById(R.id.checkBox_destination_now);
Listener for the CheckBox:
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
//Adding the Fragment. THIS WORK
destinationDetailsFragment = new DestinationDetailsFragment();
FragmentManager fm = getFragmentManager();
fm.beginTransaction().add(R.id.frame_for_des_details, destinationDetailsFragment).commit();
}
});
Listener for the TextView:
findViewById(R.id.label_later).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Removing the Fragment. DOES NOT WORK
FragmentManager fm = getFragmentManager();
fm.beginTransaction().remove(destinationDetailsFragment).commit();
}
});
}
When I check the CheckBox, I can see the Fragment. But when I click the TextView to remove it, it remains.
When I check the CheckBox again and again it seems that the new Fragment overlays the older fragment so I can write over placeholders in an EditText.
I hope someone understand me and can help me.
Thanks.
Try The android.support.v4.app.FragmentManager. Here is the code.
destinationDetailsFragment = new DestinationDetailsFragment();
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton,
boolean b) {
// Adding the Fragment. THIS WORK
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.add(R.id.frame_for_des_details,
destinationDetailsFragment).commit();
}
});
findViewById(R.id.label_later).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.remove(destinationDetailsFragment).commit();
}
});
FIXED
I implement a the Fragment as android.support.v4.app.Fragment but that wasnt the problem.
Before I add the fragment i removed the checkbox. And bevor removing the Fragment i add the checkbox again to the View. But i also called checkbox.setChecked(false). That fired the onCheckedChanged again!
My new Code
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked) {
LinearLayout layout = (LinearLayout) findViewById(R.id.layout_destination);
//Remove and Add Content
layout.removeView(checkBox);
destinationDetailsFragment = new DestinationDetailsFragment();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.frame_for_des_details, destinationDetailsFragment).commit();
//Enable Later Button
findViewById(R.id.img_later).setVisibility(View.VISIBLE);
findViewById(R.id.label_later).setVisibility(View.VISIBLE);
}
}
Thanks.
Related
I need to display a Fragment when the user touches the TextView of another Fragment. Here's what I have:
public class FindPeopleHelpFragment extends Fragment {
public FindPeopleHelpFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_find_people_help, container, false);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(R.string.find_people_help);
TextView welcome_home = (TextView) view.findViewById(R.id.find_people_help);
welcome_home.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent evt) {
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
EditProfileFragment editProfileFragment = new EditProfileFragment();
FragmentManager manager = getActivity().getSupportFragmentManager();
manager.beginTransaction().replace(R.id.fragment_container, editProfileFragment, editProfileFragment.getTag()).commit();
}
return true;
}
});
// Inflate the layout for this fragment
return view;
}
}
The issue is that onTouch() returns a boolean, but when replacing the Fragment, I need to return a View. Otherwise I get the following.
10-05 15:00:51.057 25152-25152/wegrok.chiaramail.com E/AndroidRuntime: FATAL EXCEPTION: main
Process: wegrok.chiaramail.com, PID: 25152
java.lang.IllegalArgumentException: No view found for id 0x7f0f00b1 (wegrok.chiaramail.com:id/fragment_container) for fragment FindPeopleHelpFragment{c052157 #1 id=0x7f0f00b1}
Anyone know how to deal with this?
You need to make these Fragment transactions from your Activity. The Activity that hosted the Fragment should have a public function for handling the fragment switching so that when the TextView of your Fragment1 is clicked, the public method of the Activity will be called to make the Fragment switch.
So you might consider having an Activity like this.
public class YourActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
// The Fragment 1 will be loaded by default
switchToFragment1();
}
public void switchToFragment1() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new Fragment1()).commit();
}
public void switchToFragment2() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new Fragment2()).commit();
}
}
Now from your Fragment1, you need to implement an onClick listener in to the TextView, so that when the TextView is clicked, Fragment1 switches to Fragment2.
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((YourActivity) getActivity()).switchToFragment2();
}
});)
Hope that helps.
I have issue in fragment, i have to remove all added fragment when clicking the check box, but now fragments are not removed, please guide me to resolve this issue, here by i have added my code below,
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView txtVw_showfirstfragment,txtVw_showsecondfragment;
FragmentTransaction ft;
CheckBox checkBox;
fragment1 frag1 = new fragment1();
fragment2 frag2 = new fragment2();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtVw_showfirstfragment = (TextView) findViewById(R.id.txtVw_showfirstfragment);
txtVw_showsecondfragment = (TextView) findViewById(R.id.txtVw_showsecondfragment);
checkBox = (CheckBox)findViewById(R.id.checkBox);
txtVw_showfirstfragment.setOnClickListener(this);
txtVw_showsecondfragment.setOnClickListener(this);
checkBox.setText("I Agree"); // Prompting "Hide Password"
// Begin the transaction
checkBox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
if (isChecked) {
if(frag1!=null) ft.remove(frag1);
if(frag2!=null) ft.remove(frag2);
}
}
} );
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.txtVw_showfirstfragment:
String backFragment1 = getApplicationContext().getClass().getName();
ft = getSupportFragmentManager().beginTransaction();
// Replace the contents of the container with the new fragment
ft.replace(R.id.your_placeholder,frag1);
ft.addToBackStack(backFragment1);
// Complete the changes added above
ft.commit();
break;
case R.id.txtVw_showsecondfragment:
String backFragment2 = getApplicationContext().getClass().getName();
ft = getSupportFragmentManager().beginTransaction();
// Replace the contents of the container with the new fragment
ft.replace(R.id.your_placeholder,frag2);
ft.addToBackStack(backFragment2);
// Complete the changes added above
ft.commit();
break;
}
}
}
Use getSupportFragmentManager().beginTransaction().remove(frag1).commit(); instead of ft.remove(frag1);
Im developing an app and on my first activity, I'm using an tablayout and a viewpager. So when the user, change the tabs the fragment change too. But the problem is on the second tab. In that tab I use a "container" so, when the user change to this tab, I add a fragmentOne and it has a button, when I click on that button, I replace the fragment whit a fragmentTwo. Now, on this second fragment I have a textview, when I click in that textview I want to change to the firstFragment. The trouble I think is because both have an onActivityCreated and the belong to the same activity. This is my code.
Containerfragment:
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
RegistroUnoFragment registroUnoFragment = new RegistroUnoFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.contenedorRegistro, registroUnoFragment).commit();
}
This is my first fragment:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
btnContinuar = (Button)getView().findViewById(R.id.btnContinuar);
btnContinuar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RegistroDosFragment registroDosFragment = new RegistroDosFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.contenedorRegistro, registroDosFragment).commit();
}
});
}
and in this fragment is when I want to return my first fragment
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
tviRetroceder = (TextView)getView().findViewById(R.id.tviRetroceder);
tviRetroceder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RegistroUnoFragment registroUnoFragment = new RegistroUnoFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.contenedorRegistro, registroUnoFragment).commit();
}
}
The tviRetroceder OnClickListener creates a new RegsitroUnoFragment called registroUnoFragment. But there is already a RegistroUnoFragment in existence called registroUnoFragment created in your container activity in its onCreate method. You cannot create it again. You have to "find" this fragment and only then add it to the container. So you need to check if the gragment is NULL first.
Use "replace" and not "add" and use a tag so that you can find the fragment e.g.
fragmentTransaction.replace(R.id.contenedorRegistro,registroUnoFragment,"TagUno");
Then in the OnClick
RegistroUnoFragment registroUnoFragment=(RegistroUnoFragment) getActivity().getFragmentManager.FindFragmentByTag("TagUno");
if(registroUnoFragment!=null) {
{fragmentTransaction.replace(R.id.contenedorRegistro,registroUnoFragment,"TagUno");
}
Hi guys im working on my MainActivity and I am dealing with the following problem:
In my MainActivity I have 3 buttons(button1, button2, button3). With each I can add a Fragment(Fragment2, Fragment1, ProfileFragment) to my container. Everytime a button is pressed, it checks the Fragments if there is already anotherone visible.
If yes, FragmentManager().beginnTransaction().fragment.hide() should hide it.
Then it checks if the fragment bound to the button already exists.
If no, it adds it.
If yes, it should make the existing hidden fragment visible again with FragmentManager().beginnTransaction().fragment.show()
Now: If I press button2 as the first when I start my App everything works fine and I can infinitely switch between the fragments.
But: If I press button1 as the first, and then switch to button2 or button3, the fragment bound to button1 (m2fragment) can't be shown again. It just shows m1fragment (which should be hidden when I press button1)
The same happens if I press button3 as the first. Everytime I try to switch back to button3(profileFragment) it just shows m1fragment.
May be there a problem with the googleMap which I call from the xml from m2Fragment??
Anyone can see where I made (a) mistake(s) ? I would be really glad since I am dealing with this for several days now.
Thank you all !
Cut from my MainActivity:
public class MainActivity extends FragmentActivity implements ProfileFragment.OnFragmentInteractionListener,
OfferFragment.OnFragmentInteractionListener, MapsFragment.OnFragmentInteractionListener, OpenerFragment.OnFragmentInteractionListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
protected int fragment1Open = 0;
protected int fragment2Open = 0;
protected int profileFragmentOpen = 0;
Fragment1 m1Fragment = new Fragment1();
Fragment2 m2Fragment = new Fragment2();
ProfileFragment mProfileFragment = new ProfileFragment();
OpenerFragment mOpenerFragment = new OpenerFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState==null) {
getFragmentManager().beginTransaction().add(R.id.container,mOpenerFragment).commit();
}
final Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//check fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
Log.d("button1", "remove OpenerFragment");
}
if(m1Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m1Fragment).commit();
}
if(mProfileFragment.isVisible()) {
getFragmentManager().beginTransaction().hide(mProfileFragment).commit();
}
if(fragment2Open==0) {
fragment2Open=1;
getFragmentManager().beginTransaction().add(R.id.container, m2Fragment).commit();
} else {
getFragmentManager().beginTransaction().show(m2Fragment).commit();
}
}
});
final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//hide other fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
}
if(mProfileFragment.isVisible()) {
getFragmentManager().beginTransaction().hide(mProfileFragment).commit();
}
if(m2Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m2Fragment).commit();
}
if(fragment1Open==0) {
fragment1Open=1;
getFragmentManager().beginTransaction().add(R.id.container, m1Fragment).commit();
} else {
getFragmentManager().beginTransaction().show(m1Fragment).commit();
}
}
});
final Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//hide other fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
}
if(m1Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m1Fragment).commit();
}
if(m2Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m2Fragment).commit();
}
//open fragment
if(profileFragmentOpen==0) {
profileFragmentOpen=1;
getFragmentManager().beginTransaction().add(R.id.container, mProfileFragment).commit();
} else {
getFragmentManager().beginTransaction().show(mProfileFragment).commit();
}
}
});
mProfileFragment and m2Fragment use identically onCreate and onCreateView methods:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_profile, container, false);
return rootview;
}
m1Fragment has the same methods, but gets a googleMaps fragment from its xml file.
m1Fragment:
public class Fragment1 extends Fragment implements OnMapReadyCallback {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapFragment mapFragment=(MapFragment) getFragmentManager().findFragmentById(mapid);
if (mapFragment==null) {
mapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, mapFragment);
fragmentTransaction.commit();
mapFragment.getMapAsync(this);
}
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap map) {
//right upper corner, location layer activated
map.setMyLocationEnabled(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_maps, container, false);
return rootView;
}
fragment_1.xml:
<fragment
android:id="#id/mapid"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
MapFragment mapFragment=(MapFragment) getFragmentManager().findFragmentById(mapid);
in this line your actually tring to get the parent's fragmentManager (in your case the activity),and fail to find the fragment.
and then in this line:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, mapFragment);
fragmentTransaction.commit();
you are adding to the parent FragmentManager.
a quick to solution is to replace getFragmentManger() with getChildFragmentManager, which refers to the fragment's FragmentManager.
Maybe you should try to use :
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
With fragment_container as FrameLayout in your activity?
I'm not 100% sure, but i think it'll avoid such issues
I just solved it:
Withing my MapsFragment class I instantiated a googleMaps fragment "twice". Trying to hide the mapFragment I just hid one of them, leaving the other one visible in front.
For people having similar issues here my solution:
I erased the
<fragment
android:id="#id/mapid"
class="com.google.android.gms.maps.MapFragment"/>
from the xml layout file.
And inside the MapsFragment class I changed
MapFragment mapFragment=(MapFragment) getChildFragmentManager().findFragmentById(mapid);
to
MapFragment mapFragment = MapFragment.newInstance();
getChildFragmentManager().beginTransaction().add(R.id.framLay, mapFragment).commit();
Now I put one clean Instance of MapFragment into my FrameLayout and it works properly.
I am fresh at android programming and in my simple program,
I am trying to show fragment when CheckBox is checked and remove
fragment when CheckBox is not checked.
In my code, when I checked the CheckBox, fragment is shown and when I disable the CheckBox fragment is removed. However when I try to show it again I can not succeed it.
this is my part of code about checkbox
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(checkBox.isChecked())
{
checkBox.setText("It is on.");
MyFragment fragment = (MyFragment)getFragmentManager().findFragmentById(R.id.container);
if (fragment == null)
{
getFragmentManager().beginTransaction()
.add(R.id.container, new MyFragment()).
commit();
}
}
else
{
checkBox.setText("It is off.");
MyFragment fragment = (MyFragment)getFragmentManager().findFragmentById(R.id.container);
if (fragment != null)
{
getFragmentManager().beginTransaction()
.remove(fragment)
.commit();
}
}
}
});
is there anybody can help me?
You cannot probably add it because you removed it completely, try to detatch it. By detaching it Fragment keeps its state.
try this:
getFragmentManager().beginTransaction()
.detach(fragment)
.commit();
}
Remove means the fragment instance cannot be re-attached. You will have to add it again to the fragment transaction.
try like this,
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
MyFragment fragment = (MyFragment)getFragmentManager().findFragmentById(R.id.container);
if(checkBox.isChecked())
{
checkBox.setText("It is on.");
getFragmentManager().beginTransaction()
.add(R.id.container, fragment).
commit();
}
else
{
checkBox.setText("It is off.");
if (fragment != null)
{
getFragmentManager().beginTransaction()
.remove(fragment)
.commit();
}
}
}
});
try it like this:
1)Create a layout for the fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ff0000">
</LinearLayout>
2)Create your fragment class which extends Fragment
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.myfragment, container,false);
}
}
3) In activity_main.xml put an empty layout with id
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/frag">
</LinearLayout>
</LinearLayout>
4)In MainActivity.java, Create an object of your Fragment class then add and remove it with FragmentManager
public class MainActivity extends Activity {
CheckBox cbox;
FragmentManager manager;
MyFragment frag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = (FragmentManager) getFragmentManager();
frag = new MyFragment();
cbox = (CheckBox) findViewById(R.id.checkBox1);
cbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked==true){
manager.beginTransaction().add(R.id.frag, frag).commit();
}
else{
manager.beginTransaction().remove(frag).commit();
}
}
});
}
}