Fragment managment android - android

I want to pass from a fragment of the navigation drawer menu to a fragment outside of the menu. I manage to display the new fragment but overriden to the previous. Can you suggest me some link?
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction t1 = manager.beginTransaction();
DetailFragment instance = new DetailFragment();
Bundle b2 = new Bundle();
b2.putString("Title", Title);
b2.putString("author", author);
instance.setArguments(b2);
t1.replace(R.id.nav_host_fragment, instance);
t1.commit();
The problem is the R.id.nav_host_fragment

public void routine(String Title, String author,Fragment fragment,FragmentManager f1) {
FragmentTransaction t1 = f1.beginTransaction();
DetailFragment instance = new DetailFragment();
Bundle b2 = new Bundle();
b2.putString("Title", Title);
b2.putString("author", author);
instance.setArguments(b2);
t1.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
t1.replace(fragment.getId(), instance,"Change layout");
t1.commit();
}
The above function is recall by my first fragment in the code below to pass to the next fragment where the first fragment is come from nav bar fragment and the next fragment is an empty fragment
androidx.fragment.app.Fragment fragment =getParentFragment();
instance.routine(Title[position],Author[position],fragment,
instance.getSupportFragmentManager());

Related

How to handle fragment load again and again

In my app, I have navigation bottom and container above navigation. I using multiple fragments in one container. When I click on an item of navigation bottom, I replace the fragment to show.
This is my code that shows fragment in the container
private void showFragment(String tabType) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
baseTabBottomFragment = new BaseTabBottomFragment();
//send data to fragment
Bundle bundle = new Bundle();
bundle.putString(KeyConstant.TAB_BOTTOM, tabType);
baseTabBottomFragment.setArguments(bundle);
ft.add(R.id.frame_container, baseTabBottomFragment, tabType);
ft.addToBackStack(tabType);
ft.commit();
}
But I don't know, how to handle when I click on the item navigation bottom, It's always loaded fragment again and again. I want to handle it. If fragment loaded, I don't want to load it again.
Please help me
Sorry for English grammar
1-You can play with that tag tabType e.g:
String prevTab = "";
private void showFragment(String tabType) {
if(!tabType.equal(prevTab)){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
baseTabBottomFragment = new BaseTabBottomFragment();
//send data to fragment
Bundle bundle = new Bundle();
bundle.putString(KeyConstant.TAB_BOTTOM, tabType);
baseTabBottomFragment.setArguments(bundle);
ft.add(R.id.frame_container, baseTabBottomFragment, tabType);
ft.addToBackStack(tabType);
ft.commit();
}
prevTab = tabType;
}
2-Or from your BottomNavigationView you can check for selected item id, e.g:
if (bottomNav.getSelectedItemId() != R.id.someMenuId)
// replace the fragment
3- Or use onNavigationItemReselcted add from Api 26 to know if the current item got selected again or not.

How to start Fragment from onClick

I am using recyclerview in my app. I want to start a fragment when click on image view. But i don't know how to. Also i want to put data when starting fragment. I know how to start the activity with below code. But how can i start fragment same way?
Edited Code
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.layoutContent, frag);
ft.commit();
Fragments cannot be started, they must be added to a container.
Fragments aren't meant to function on their own, they need an enclosing Activity.
Having the following layout:
[...]
<FrameLayout android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
[...]
You place the fragment in it like such:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, newFragment);
transaction.commit();
You pass arguments to the fragment by using Bundle and creating the fragment as follows:
TestFragment newFragment = new TestFragment();
Bundle args = new Bundle();
args.putString("Hello world!");
newFragment.setArguments(args);
This has to be done before the transaction.
For further info refer to the official documentation
Note on edited code: you have to call the transaction from inside the Activity the FrameLayout is part of. Alternatively use a rather dirty workaround:
In Main:
public class Main extends Activity{
public static Main currentInstance;
public void onCreate(Bundle boomerang){
currentInstance = this;
}
}
In the Playlist activity then use Main.currentInstance.getSupportFragmentManager() etc.
But I wouldn't recommend it.
In order to start a fragment you need to make use of the fragment manager.
YourFragment yourFragmentInstance = YourFragment.newInstance("Hello", 12);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
//Fragment is hosted by an activity, and the activity must have a layout
//or a container for the fragment to be nested in, in this case it will be
//a FrameLayout with an id fragment_container
fragmentTransaction.replace(R.id.fragment_container, yourFragmentInstance);
fragmentTransaction.commit();
And you can pass in arguments to your fragment like this:
public class YourFragment extends Fragment {
public static YourFragment newInstance(String paramOne, int paramTwo) {
YourFragment fragment = new YourFragment();
Bundle b = new Bundle();
//set params/arguments for fragment
b.putString("param_one", paramOne);
b.putInt("param_two", paramTwo);
fragment.setArguments(b);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get the params you passed in
Bundle bundle = getArguments();
String paramOne = bundle.getString("param_one");
String paramTwo = bundle.getInt("param_two");
}
}
Note: I've not tested this code.. This is just an idea :)

start Fragment from RecycleView Adapter Onclick

Hi I have A RecycleView Adapter and A button. I want that button to start a Fragment. I can start an activity but not a fragment. I have tried this Onclick method for my Button
#Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putParcelable("event", events.get(getLayoutPosition()));
Fragment fragment = new EditEventDetailFragment();
fragment.setArguments(bundle);
fragment.getFragmentManager().beginTransaction().replace(R.id.contentMainDrawer,fragment).commit();
}
But have error invoke null object (contentMainDrawer) is my Main activity content_layout.
Any help is much appreciate. The Fragment host recycle view is call from Mainactivity
Use below code for replace fragment
Fragment fragment = new EditEventDetailFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.contentMainDrawer, fragment, "tag").commit();
if you are using this code inside adapter than replace getActivity() to ((Activity) context).
Hi I have found 2 answer that help whoever needed. The answer is to use the Activity that host the calling fragment. Many thanks #Mohit Suthar
Bundle bundle = new Bundle();
bundle.putParcelable("event", events.get(getLayoutPosition()));
Fragment fragment = new EditEventDetailFragment();
fragment.setArguments(bundle);
FragmentManager fragmentManager = ((MainActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.contentMainDrawer, fragment, "tag").commit();

Replace a Fragment created from Navigation Drawer with another dynamically

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);

How to save a viewpager content contained in a fragment?

I use a master/detail flow and in every fragment I have a viewpager containing some forms but the thing is when I click on some other links from the master list, the content of the viewpager is lost. How to save this content so everytime I click on the same choice I find my data.
My code :
#Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
if(id.contains("1"))
{
Bundle arguments = new Bundle();
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setRetainInstance(true);
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment).commit();
}
else if(id.contains("2"))
{
Bundle arguments = new Bundle();
ItemDetailFragment2 fragment = new ItemDetailFragment2();
fragment.setRetainInstance(true);
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment).commit();
}
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
EDIT:
I tried to modify my code this way :
if (id.contains("1")) {
Fragment currFragment = fm.findFragmentByTag(lastTag);
ItemDetailFragment newFragment = (ItemDetailFragment) fm.findFragmentByTag("f"+1);
FragmentTransaction ft = fm.beginTransaction();
ft.hide(currFragment);
if(newFragment==null)
{lastTag="f"+1;
newFragment=new ItemDetailFragment();
ft
.replace(R.id.item_detail_container, newFragment);}
else {
ft.show(newFragment);
}
ft.commit();
}
But i got a NullPointerException at android.support.v4.app.BackStackRecord.run(BackStackrecord.java:656)
Try to call setRetainInstance(true) in your fragments onCreate()
As writed here, if you do not add the transaction to the back stack, then the fragment is destroyed when removed or replaced.
You can hide current fragment, instead replacing, then add new. Like that:
int currPage = 0;
public void goToPage(int num) {
FragmentManager fm = getSupportFragmentManager();
Fragment currFragment = fm.findFragmentByTag("f" + currPage);
Fragment newFragment = fm.findFragmentByTag("f" + num);
FragmentTransition ft = fm.beginTransaction();
ft.hide(currFragment);
if(newFragment == null) {
// First use. Create new instance for page.
newFragment = new MyFragment();
ft.add(R.id.item_detail_container, newFragment, "f" + num);
} else {
// Fragment for page already added. Just show it.
ft.show(newFragment);
}
ft.commit();
this.currPage = num;
}
And don't forget to specify tag for initial page fragment too.
You can implement the onPause() or onStop() methods of your fragments and save the data when that methods are called, which happens automatically when they are removed.
Or you could perhaps go with the savedInstanceState.
It's better to save in the arrayList. Onclick store the image id in the arrayList.

Categories

Resources