I've got a ListFragment with this:
public void fragmentSelection(Integer count) {
Fragment fr;
if (count == 0) {
fr = new Fragment1();
} else {
fr = new Fragment2();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.content, fr, fr.getClass().getName());
fragmentTransaction.commit();
}
here I am trying to replace the fragment content with fr (depends on count value)..
the part from XML looks like this
<fragment
android:id="#+id/content"
android:name="com.test.app.DefaultContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
Now when I want to replace fragment "content" with "fr" it do not replace it 1:1 - it adds fr down to the already current fragment (here DefaultContent) - so - why it does not replace it? What I have to do, that it replaces it and not puts the fr in addition below the current fragment
The View ID you pass to replace(), in your case R.id.content, has to be the ID of the Fragment's parent View, not the original Fragment itself.
That means you have to set android:id="#+id/content" to the Fragment's parent, like this:
<FragmentLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="com.test.app.DefaultContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FragmentLayout>
Or, if that does not work for you, set a new ID to the parent and use it for replace().
Related
I am trying to add multiple fragments to a FrameLayout. I need to add them one below another. But they are overlapping.
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
MainActivity.java
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
// Create instance of fragments
FragmentPrimaryList firstFrag = new FragmentPrimaryList();
FragmentSecondaryList secFrag = new FragmentSecondaryList();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// add fragment to the fragment container layout
fragmentTransaction.add(R.id.fragment_container,firstFrag);
fragmentTransaction.add(R.id.fragment_container,secFrag);
fragmentTransaction.commit();
}
}
They looks like this. How can I solve this?
Use the replace method instead of the add method.
The replace method hides the current fragment before adding new one, the add method simply adds the new fragment without disposing off the older fragment.
In order to retain the back stack, use the fragment transaction with backstack management.
I need to display both fragments at same time, one below another
You can try the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
Now add fragmments using:
fragmentTransaction.add(R.id.fragment_container1,firstFrag);
make sure you Fragment's layout_height = "wrap_content"
Add background to your fragments and make "android:clickable="true" to parent layout.
Do this way:
First fragment
FragmentPrimaryList firstFrag = new FragmentPrimaryList();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// add fragment to the fragment container layout
fragmentTransaction.add(R.id.fragment_container,firstFrag);
fragmentTransaction.commit();
second fragment
FragmentSecondaryList secFrag = new FragmentSecondaryList();
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container,secFrag);
fragmentTransaction.commit();
I have attached navigation drawer to main Activity of my application.
Navigation drawer have 4 options that will navigate user to 4 different fragments f1, f2, f3 and f4.
I have created a home page Fragment fh.
I am not adding fh as a choices in Navigation Drawer.
Fragment fh populates data making http call.
Whenever user selects f1, f2, f3 or f4; the respective fragments need to be shown back.
Till here everything is working fine.
However, whenever user press back button, then fh should be displayed. ie. content_frame should contain fh.
I am unable to do this portion.
Right now, whenever user press back button, the default view is blank.
Also, since fh makes a http call to populate data, so fh that was added to stack needs to be shown.
Here is my implementation:
MainActivity- OnCreate
mDrawerLayout.closeDrawer(mDrawerList);
setUpHomeFragment();
Here is how I am managing fragment, on navigation drawer item clicked...
private void showFrg(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.content_frame, fragment).commit();
}
The setUpHomeFragment Function, that is called just once on activity oncreate()
private void setUpHomeFragment(){
mLandingPageFragment=new ReadyMyOrderCollections();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, mLandingPageFragment);
ft.addToBackStack(null);
ft.commit();
}
MainActivity XML Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="#layout/toolbar" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
layout="#layout/list_view" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
I found the cleanest approach for this issue here:
https://stackoverflow.com/a/21093352/1348550
Call setUpLandingFragment just once on activity onCreate.
private void setUpLandingFragment(){
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack();
fragmentManager.beginTransaction()
.add(R.id.content_frame, new LandingFragment()).commit();
}
On navigation drawer item click:
private void changeFrag (Fragment f) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack();
fragmentManager.beginTransaction()
.add(R.id.content_frame, f).addToBackStack("fragBack").commit();
}
The coolest part about this solution is, onBackPressed is not needed at all.
My work around for this is
private int getFragmentCount() {
return getSupportFragmentManager().getBackStackEntryCount();
}
In your Activity
#Override
public void onBackPressed() {
if(getFragmentCount()>0) {
getSupportFragmentManager().popBackStackImmediate();
}else{
super.onBackPressed();
}
}
I have strange behaviour. Every time i replace the same type of fragment in Activity (using transaction), the new Fragment instance is added to Fragment List. The old instances remains active in Fragment Manager and after orientation change are visible on the screen (although not clickable).
My Activity Layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
-->
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cubesoft.zenfolio.moments.app.activity.MainActivity" >
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<fragment
android:id="#+id/navigation_drawer"
android:name="com.cubesoft.zenfolio.moments.app.fragment.NavigationDrawerFragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
<fragment
android:id="#+id/fragmentConnectionStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
class="com.cubesoft.zenfolio.fragment.ConnectionStatusFragment" />
My code that changes fragments:
#Override
public void onNavigationDrawerItemSelected(int position) {
mCurrentDrawerPosition = position;
// update the main content by replacing fragments
List<Fragment> fragmemts = getSupportFragmentManager().getFragments();
switch (position) {
case 0:{
if ( getMyApplication().getGroupModel().getUsersCount() > 0 ) {
final Fragment fragment = UserSelectionFragment.newInstance();
final FragmentManager fragmentManager = getSupportFragmentManager();
//fragmentManager.popBackStack();
final FragmentTransaction tr = fragmentManager
.beginTransaction();
tr.replace(R.id.container, fragment);
tr.addToBackStack(null);
tr.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
tr.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
tr.commit();
} else {
final Fragment fragment = MomentsFragment.newInstance(mUsername);
final FragmentManager fragmentManager = getSupportFragmentManager();
//fragmentManager.popBackStack();
final FragmentTransaction tr = fragmentManager
.beginTransaction();
tr.replace(R.id.container, fragment);
//tr.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
tr.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
tr.addToBackStack(null);
tr.commit();
}
break;
}
case 1: {
final Fragment fragment = DownloadFragment.newInstance();
final FragmentManager fragmentManager = getSupportFragmentManager();
//fragmentManager.popBackStack();
final FragmentTransaction tr = fragmentManager
.beginTransaction();
tr.replace(R.id.container, fragment);
tr.addToBackStack(null);
tr.commit();
break;
}
/*case 2:
fragment = UserSelectionFragment.newInstance();
break;*/
}
}
The UserSelectionFragment is displayed incorrectly after several orientation changes, old instances of UserSelectionFragment remains in Fragment List but their View objects are null.
What is wrong?
Try removing
tr.addToBackStack(null);
To me this adds your frgament to the backstack and thats the reason why they are kept in your fragment list. Their view are null because they have been destroyed before going to backgroud.
i really need help.
This is how my application looks like. I got two(2) fragments where the left side is for the buttons and for the right side is for my details.
The bigger fragment has a default display which i called splash. An image is viewed here, a bigger image that would take the height of the device.
So my case is when i click/press button 1, it would display the fragment for that but the image is still present.
My question now is, how to i get rid of the 'splash display'?
Here is my code
/**
* on main listener
*/
#Override
public void onMainListener(String whatPress){
Fragment fr = null;
if(whatPress.equals("button1"))
fr = new FragmentOne();
if(whatPress.equals("button2"))
fr = new FragmentTwo();
if(whatPress.equals("button3"))
fr = new FragmentThree();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, fr, whatPress);
fragmentTransaction.commit();
}
The code above is the one handles which button is pressed.
<?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="horizontal" >
<fragment
android:id="#+id/menuFragment"
android:name="FragmentMenu"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
class="com.mizsh.Fragment_Menu" />
<fragment
android:id="#+id/detailFragment"
android:name="com.mizsh.Fragment_Splash"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</LinearLayout>
The code above is my main.xml
You should replace the detailFragment with FrameLayout
<FrameLayout android:id="#+id/detailFragment" android:layout_weight="1"
android:layout_width="0px" android:layout_height="match_parent" />
and replace it with Fragment_Splash in the onCreate of the activity
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, fragmentSplash, null);
fragmentTransaction.commit();
then replace with chosen fragment on click
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.detailFragment, chosenFragment, null);
fragmentTransaction.commit();
i am using the following layout for fragment transaction. i am replacing the fragment1
with new fragments by using the following code.i am attaching the layout file also for your reference. i am executing the below code for every listitem click.
Code:
Fragment newFragment = new Grades();
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment1, newFragment);
// Commit the transaction
transaction.commit();
Fragment newFragment = new Teachers();
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment1, newFragment);
// Commit the transaction
transaction.commit();
<LinearLayout
android:id="#+id/slidingPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:orientation="vertical"
android:background="#android:color/white"
>
<fragment
android:id="#+id/fragment1"
android:name="com.example.slideoutmenu.Item3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</Linearlayout>
my doubt is should i replace the fragment1 everytime when i show a new fragment or should i replace the existing fragment if so how can i replace the existing fragment.
To replace the fragment:-
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
YourFragment yourFragment = new YourFragment();
fragmentTransaction.replace(R.id.top_layout, yourFragment ); // top_layout is parent layout / viewgroup where you want to place your new fragment
fragmentTransaction.commit();