I want to when button clicked to return to previous fragment. This is how I create fragment:
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, statisticsSpecificStudentFragment)
.addToBackStack("StatisticsStudentOverallFragment")
.commit();
This is how I try and return to this fragment, from whom I started new fragment:
btDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().popBackStack();
}
});
All that happends is that it reloads current fragment, like I added current one to stack but I did not.
Try
popBackStack("StatisticsStudentOverallFragment")
Or
addToBackStack(null)
and keep popBackStack() like you have it already.
I am trying to open a fragment (PageFragment) from inside a fragment (UpcomingFragment).
When I open the fragment, the previous fragment UI is still present and I would not like this to be so.
I have tried both .getSupportFragmentManager(), and GetChildFragmentManager() neither of these solve the problem.And looking through simular thread on here, and I can't get a working result.
mRecyclerAdapter.setItemClickListener(new CardOnClicked() {
#Override
public void onCardClicked(int position) {
Log.d(TAG, "Test");
Fragment pageView = new PageFragment();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction()
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.frag, pageView);
transaction.addToBackStack(null);
transaction.commit();
}
});
You can find my Github repository here:
https://github.com/KyleGwynDavies/aTV
You can see the problem here
https://imgur.com/a/BHkXOsc
Two fragments should never communicate directly. All communication needs to be done through the host activity. For that use an Interface.
Create an interface:
public interface IMainActivity {
void navigateFragment();
}
Add interface to the adapter override onAttachedToRecyclerView:
private IMainActivity mInterface;
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
//instantiate interface when view attach to the recycler view
mInterface = (IMainActivity) mContext;
}
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mInterface.navigateFragment();
}
});
Finally, implement interface from to MainActivity and override the method then add your fragment.
#Override
public void navigateFragment() {
mViewProfileFragment = new ViewProfileFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.main_content_frame, mViewProfileFragment, getString(R.string.tag_fragment_view_profile));
transaction.commit();
}
So, what my problem is that in one fragment(w/i a viewpager, I'll call this Fragment A) I click on this dynamically created button that adds a new fragment(I'll call this Fragment B) in a framelayout which allows me to use PayPal service. On PayPal Activity result, Fragment B communicates with the main Activity via a communicator(an interface class) to call Fragment A to change that text. But I'm getting a null pointer exeception crash.
To be specific:
what I did was that I made a global TextView variable that is initialized on click. I did this b/c I have a list of other things that are dynamically inflated and to avoid the TextView from being initialized with wrong layout I initialized it on click.
bidChange.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
eventListChangeKey = keyVal;
eventListChangeIdx = eventListIdx;
eventBiddingChangeIdx = finalI;
priceToChage = (TextView) biddersLayout.findViewById(R.id.single_list_bidder_bid_price);
Bundle bundle = new Bundle();
bundle.putInt("auctionID", auctionId);
bundle.putInt("dateID", dateId);
bundle.putInt("FromWhere", 2);
Fragment fragment = new Fragment_Home_ItemInfo_Bid();
fragment.setArguments(bundle);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.container_mainScreen, fragment, "itemInfo_bid")
.addToBackStack(null)
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
});
In the main activity
public void changeBidderPrice(String s) {
Fragment fragment = viewPagerAdapter.getItem(1);
((Fragment_List) fragment).changePrice(s);
}
is what I do
back in Fragment A
public void changePrice(String val) {
priceToChage.setText(val);
dataMap.get(eventListChangeKey).get(eventListChangeIdx).getBidList().get(eventBiddingChangeIdx).setPrice(val);
}
I've thought this over an over but I just can't figure this out. I've searched for similar cases in StackOverflow but I wasn't able to get a help.
Would the problem be the way I initialize that TextView? or is it the way I'm calling Fragment A from the main activity?
for fragments onViewCreated() is called after onCreateView() and ensures that the fragment's root view is non-null. Any view setup should happen here. E.g., view lookups, attaching listeners.
source : codepath
for activities onCreate()
Solve by using getActivity()
I have this MainActivity.java and RepeatEntry.java
inside my MainActivity i have this code to have RepeatEntry ui
//i did hide two linear layout here with buttons and edittext inside it ,using the following method
hideTwoLinearLayout();
showCategoryContainerLayout();
Fragment fragment = new RepeatEntry();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
//category_cont is a linear layout container for my fragment
ft.replace(R.id.category_cont, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
inside my RepeatEntry.java sample code
Button k = (Button) v.findViewById(R.id.button);
k.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Intent intent = new Intent(getActivity(),MainActivity.class);
// startActivity(intent);
// if i use popBackStack and also remove the code for intent , i cannot show what i hide
//note i have a method inside mainactivity to showTwoLinearLayout()
getFragmentManager().popBackStack();
}
});
Now my question is, do i have other option other than using intent to go back to MainActivity view
Note:Edited
You can add the transaction to backstack and then reverse with poping the backstack the code is here
Fragment fragment = new RepeatEntry();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
//category_cont is a linear layout container for my fragment
ft.replace(R.id.category_cont, fragment).addToBackStack("tag");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
And for going back to the activity view call this to pop backstack
FragmentManager fm = getFragmentManager();
fm.popBackStack();
Also you can use the tag to poping back the specific transaction with
fm.popBackStack("tag");
There is a method called onAttach in your fragment. You can write an interface and assign your fragment's activity like:
private MyFragmentListener mListener;
#Override public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = ((MainActivity) activity);
}
public interface MyFragmentListener{
void onClicked(int value);
}
//Call your listener when button clicked or other events
... mListener.onClicked(position);
Or another solution is to use Otto or Eventbus to get rid unnecessary code
You can also go back in Fragment like
getActivity().getSupportFragmentManager().popBackStack();
any way i solve my problem just in case if anyone might see this.I came up with two solution which i think the first one is best for me.Thanks to Adnan Basar who give me idea.
First solution is so simple by just adding this code inside my onClick event
((MainActivity) getActivity()).showTwoLinearLayout();
((MainActivity) getActivity()).hideCategoryContainerLayout();
Second Solution I created Activity after extends Fragment{
Activity mainActivity;
And use override methods
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mainActivity= activity;
}
#Override
public void onDestroy() {
super.onDestroy();
// this is where i call the method for showing the twolinearlayout again
((MainActivity) mainActivity).showTwoLinearLayout();
((MainActivity) mainActivity).hideCategoryContainerLayout();
}
I have a fragment inside a group activity and I want to replace it with another fragment:
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
It works fine when it is done as a seperate project without using activity group, every thing works fine in log cat as control goes inside getview(), but no view is visible, not even any exception arises, I want the book detail fragment to be replaced by section detail fragment.
Xml of book detail fragment has id book_description_fragment and xml for section description fragment has id section_description_fragment.
The above code is in onClick method of an item, I want that when user taps on an item in horizontal scroll view, then the fragment changes.
Fragments that are hard coded in XML, cannot be replaced. If you need to replace a fragment with another, you should have added them dynamically, first of all.
Note: R.id.fragment_container is a layout or container of your choice in the activity you are bringing the fragment to.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().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();
Please see this Question
You can only replace a "dynamically added fragment".
So, if you want to add a dynamic fragment, see this example.
I've made a gist with THE perfect method to manage fragment replacement and lifecycle.
It only replace the current fragment by a new one, if it's not the same and if it's not in backstack (in this case it will pop it).
It contain several option as if you want the fragment to be saved in backstack.
=> See Gist here
Using this and a single Activity, you may want to add this to your activity:
#Override
public void onBackPressed() {
int fragments = getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
finish();
return;
}
super.onBackPressed();
}
Use the below code in android.support.v4
FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();
Use ViewPager. It's work for me.
final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager);
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(1);
}
});
hope you are doing well.when I started work with Android Fragments then I was also having the same problem then I read about
1- How to switch fragment with other.
2- How to add fragment if Fragment container does not have any fragment.
then after some R&D, I created a function which helps me in many Projects till now and I am still using this simple function.
public void switchFragment(BaseFragment baseFragment) {
try {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
ft.add(R.id.home_frame, baseFragment);
} else {
ft.replace(R.id.home_frame, baseFragment);
}
ft.addToBackStack(null);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
enjoy your code time :)
you can use simple code its work for transaction
Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit();
You Can Use This code
((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();
or You Can This Use Code
YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);
if (fragments==null) {
getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
}
I change fragment dynamically in single line code
It is work in any SDK version and androidx
I use navigation as BottomNavigationView
BottomNavigationView btn_nav;
FragmentFirst fragmentFirst;
FragmentSecond fragmentSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
fragmentFirst = new FragmentFirst();
fragmentSecond = new FragmentSecond ();
changeFragment(fragmentFirst); // at first time load the fragmentFirst
btn_nav = findViewById(R.id.bottomNav);
btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch(menuItem.getItemId()){
case R.id.menu_first_frag:
changeFragment(fragmentFirst); // change fragmentFirst
break;
case R.id.menu_second_frag:
changeFragment(fragmentSecond); // change fragmentSecond
break;
default:
Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
}
return true;
}
});
}
public void changeFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
}
In kotlin you can do:
// instantiate the new fragment
val fragment: Fragment = ExampleFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()
This will work if you're trying to change the fragment from another fragment.
Objects.requireNonNull(getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_fragment_container,new NewFragment())
NOTE As stated in the above answers, You need to have dynamic fragments.
You can use fragment-ktx
// If you are in fragmet
childFragmentManager.beginTransaction()
// or if you are in activiry
supportFragmentManager.beginTransaction()
// Create and commit a new transaction
supportFragmentManager.commit {
setReorderingAllowed(true)
// Replace whatever is in the fragment_container view with this fragment
replace<ExampleFragment>(R.id.fragment_container)
}
To replace a fragment with another one do this, Note that R.id.fragment comes from the id that you give to the first tag of the fragment in the XML.
barAudioPlaying.setOnClickListener(view -> {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment,new HomeFragment())
.commit();