I am creating ViewPager in SherlockFragmentActivity.
Structure of my app is like ViewPager->having three tabs: tab1, tab2, tab3.
In tab2, I want to display different fragments like fragment1->fragment2->fragment3.
In ViewPager, I am having three tabs (Fragments) added using FragmentStatePageAdapter as shown below.
public Fragment getItem(int arg0) {
switch (arg0) {
case 0:
SearchTab searchtab = new Tab1();
return tab1;
case 1:
BrowseTab browsetab = new Tab2();
return tab2;
case 2:
SavedItemsTab savedTab = new Tab3();
return Tab3;
}
return null;
}
Now in tab2, I have displayed ListView in fragment1. When user clicks an item from ListView, I want to display another fragment (fragment2) with other ListView. I am doing this by fragment transaction as bellow:
Fragment newFragment = new Brxxxx_Fragment();
Bundle args = new Bundle();
args.putString("Main_Cat_ID", Main_Category_ID_Str);
args.putString("Main_Cat_Name", Main_Category_Name_Str);
newFragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.b_p_layoutid, newFragment);
transaction.addToBackStack(null);
transaction.commit();
After this step, I am able to display another fragment (fragment2), but my old fragment (fragment1) is still visible below the new fragment.
If I want to remove previous fragment without using replace(), how should I get the current fragment to pass in remove method?
Maybe you can remove the other fragment if you don't need to navigate back or set background color to the new fragment . You can check that your layout id 'R.id.b_p_layoutid' is of your 'FrameLayout' and not your 'Fragment' id just in case...
android:background="?android:attr/colorBackground"
getActivity().getSupportFragmentManager().beginTransaction().remove('YOUR_FRAGMENT').commit();
You can check this answer too:
Visit Android replace fragment still displays some of the replaced fragment
Visit Fragment replaced still visible on background
Related
I have a navigation drawer that works well. By well I mean I can navigate through all the fragments tied to the Navigation drawer (A,B,C,D). My issue arises here. Lets say am in Fragment A, in this fragment I have a button which on clicking should ideally replace the fragment with another one say Frag Z, and once I am in Frag Z I can return back to frag A.
To achieve this I use the below code. However the new fragment Z appears transparent on top of Fragment A. What could be the problem:
Bundle bundle = new Bundle();
bundle.putInt("int", 1);
bundle.putString("str","string" );
fragmentTransaction = getFragmentManager().beginTransaction();
FragZ fragmentz = new FragZ();
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.some_container, fragmentz);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
EDIT:
I have found a workaround to this as shown below,however it does not completely solve my problem since the newly displayed fragment is still shown with the navigation drawer capable of being toggled,but it atleast removed the overlaying of the fragments. I would still want a solution to launching an independent fragment
Bundle bundle = new Bundle();
bundle.putInt("int", 1);
bundle.putString("str","string" );
FragZ fragmentz = new FragZ();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
fragment.setArguments(bundle);
ft.replace(R.id.main, fragment);
ft.addToBackStack(null);
ft.commit();
Create a method in your activity to launch fragments. Whenever you want to display the fragment, just call in with a number or string to represent the fragment. You can use the same function to launch fragments from your navigation drawer.
For example:
public void displayView(int position) {
Fragment fragment = null;
currentFragmentNumber = position;
switch (position) {
case 0:
fragment = new frag1();
break;
case 1:
fragment = new frag2();
break;
case 2:
fragment = new frag3();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment)
.addToBackStack("tag").commit();
} else {
// error in creating fragment
Log.e(TAG, "Error in creating fragment");
}
}
You can call this function from your activity by using:
((**ActivityName**) getActivity()).displayView(0);
The layout file of my main activity contains a in wich I'm loading
fragments dinamically using NavigationDrawer.
To achive this I use a FragmentPagerAdapter:
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FragmentA();
case 1:
return new FragmentB();
case 2:
return new FragmentC();
}
return null;
}
In FragmentA there is a ViewPager + another FragmentPagerAdapter, so you can swipe
between three other fragments. (Frament1, Fragment2, Fragment3).
It works like this:
(I can't insert the image due to the lack of reputation...)
http://62.165.232.86:1991/images/fragments.png
When I swap between Frament1, Fragment2 and Fragment3, it works fine.
(I set the ViewPager's offScreenPageLimit high enough.)
The problem occures when I navigate to FragmentB or FragmentC and then FragmentA gets destroyed and I dont know how to save its instance and recover it, becaues I dont have
reference to Fragment1.
EDIT 1:
I swap between FragmentA and FragmentB like this:
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.main, mAdapter.getItem(0));
tx.commit();
Im a bit confused. I should save the instances of Fragment1, 2, 3 and Fragment A,
and recover them all when I navigate back to Fragment A but I don't know how because I dont have reference to the child fragments.
Can you help me?
Thanks for your answers,
Daneel Olivaw
Idea (I not sure at 100%):
Fragment fragment = getFragmentManager().findFragmentByTag("yourtag");
if (fragment==null) {
fragment = mAdapter.getItem(0)
}
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.add(R.id.main, fragment, "yourtag");
tx.commit();
I am trying to save the state on the navigation drawer fragments as I toggle between different fragments within the navigation drawer. For Example: I start at Fragment A fire some events, then toggle to Fragment B. Then I want to see the same state of Fragment A when I toggle back to Fragment A from Fragment B.
I tried using the onSavedInstanceState(Bundle savedInstanceState) but it only gets called when the orientation changes in the fragment life cycle. A new fragment gets created whenever I toggle to a new fragment and I can't figure out how to save data from a fragment and reload it on another visit.
I don't want to use backstack() either because it removes all the fragments up to the fragment that I want to restore.
Below is how I call the fragments on the drawer toggle.
private void selectItem(int position) {
Fragment fragment;
String TAG;
switch (position) {
case 0:
fragment = new FragmntA();
TAG = "A";
break;
case 1:
fragment = new FragmentB();
TAG = "B";
break;
case 2:
fragment = new FragmentC();
TAG = "C";
break;
case 3:
fragment = new FragmentD();
TAG = "D";
break;
case 4:
fragment = new FragmentE();
TAG = "E";
break;
default:
fragment = new FragmentA();
TAG = "A";
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, fragment, TAG);
ft.commit()
I don't know if there is any point in the fragment life cycle where I can save its state. Any help would be appreciated. Thanks.
To not loose the state of your fragments when switching from one to another you should do "new Fragment()" only once, and keep the instance in a global variable.
But this will not fix the rotation problem.
For the rotation problem, you should read this => http://blog.sqisland.com/2014/06/navigationdrawer-creates-fragment-twice.html
Not easy but I haven't found another way yet.
define fragment object as static in the class and in newInstance method only initialise is fragment is null otherwise just return the fragment.
This will solve your problem.
but for orientation change you will have to use on saveinstancestate method.
Android ListView is reloading all of the items (rather than just appending the new item) after I return back from a fragment where i inserted a new item onto the listview (in another fragment, ListFragment)
I have the following code to launch a fragment through Navigation Drawer:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
SherlockFragment frag = null;
// Locate Position
switch (position) {
case 0:
frag = ListFragment.newInstance();
ft.replace(R.id.content_frame, frag);
break;
case 1:
frag = InsertNewsFragment.newInstance();
ft.replace(R.id.content_frame, frag);
break;
default:
frag = UnderConstructionFragment.newInstance();
ft.replace(R.id.content_frame, frag);
break;
}
ft.commit();
listview.setItemChecked(position, true);
drawlayout.closeDrawer(listview);
The issue is that when I initially load the activity ListFragment is launched, but when user opens the navigation drawer and selects the add News, I replace the current fragment with the InsertNewsFragment, the insertNewsFragment adds data to the adapter that is displayed in the ListFragment. After adding the news element, the user selects the list fragment option in the navigation drawer, but I would expect the same listview to be there and just append the new data to the listview. But what happens is that the whole listview is loaded from scratch again. Can show me the way to how item can be appended to the list view when I return from another fragment, and not reload the whole listview. Thanks in advance :)
you cannot do this as you are replacing the listfragment. Initially you will have to check if the listview is opened if it comes out to be true then close all the other fragments that are opened and bring it (The listview fragment) to the top then dont set the adapter again and again just use the notifydatasetchanged method
I am using swipe view with ViewPager to display tabs in project.
I am adding three tabs(fragments) to AlertTabsPagerAdapter using
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new FragmentA();
case 1:
// Games fragment activity
return new FragmentB();
case 2:
// Movies fragment activity
return new FragmentC();
}
return null;
}
I am having two problems:
By default OffscreenPageLimit of ViewPager is two, so in my case for first time FragmentA and FragmentB will get created. I want to reload or recreate FragmentB on swipe from FragmentA. How can I achieve this?
In the first tab (i.e. FragmentA) I am having multiple fragments like FragmentA through FragmentD. For this I am replacing FragmentA with FragmentD using FragmentTransaction.
After the fragment transaction onback key press from FragmentD i am getting back to FragmentA, but now I want to reload or recreate FragmentA.