I have an activity with bottom tabs, which I use to switch fragments. One of the tabs have fragment with ViewPager setup (with 3 tabs). ViewPager has a RecyclerView and when I click on any item, the new fragment should replace fragment in which ViewPager exists.
But I receive an error No view found for id R.id.frame_layout_content for fragment IndexFragment when trying to replace fragment. How to properly replace fragment in this case?
Code flow:
Activity -> replace fragment in R.id.frame_layout_content with ViewPagerFragment -> Setup the ViewPager with fragment adapter (3 tabs) -> Click on RecyclerView item in IndexFragment to replace fragment in R.id.frame_layout_content with IndexDetailsFragment.
ViewPagerFragment:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
mViewPager = (ViewPager) view.findViewById(R.id.pager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new IndexFragment(), view.getResources().getString(R.string.title_index));
adapter.addFragment(new FaqFragment(), view.getResources().getString(R.string.title_faq));
adapter.addFragment(new QuotesFragment(), view.getResources().getString(R.string.title_cquotes));
mViewPager.setAdapter(adapter);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
super.onViewCreated(view, savedInstanceState);
}
Code to change fragment from IndexFragment:
IndexDetailsFragment newFragment = new IndexDetailsFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
transaction.replace(R.id.frame_layout_content, newFragment);
transaction.addToBackStack(null);
transaction.commit();
Try to change
IndexFragment newFragment = new IndexFragment();
to
Fragment newFragment = new IndexFragment();
Hope it helps.
R.id.frame_layout_content is inside MainActivity, so IndexFragment won't be able to access it.
You should make an interface, so IndexFragment can notify MainActivity and then MainActivity should change R.id.frame_layout_content content.
When I call FragmentTransaction transaction = getFragmentManager().beginTransaction() in IndexFragment (which replaced with FragmentManager attached to ViewPager) I receive an instance attached to ViewPager not to activity, which has R.id.frame_layout_content
So the solution is to get FragmentManager instance from parent Activity:
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
Related
I'm currently programming my first app, and I want to modify my Tabbed Activity so that the user can navigate between the fragments using back- and next-buttons and not by swiping.
The fragments are used for user interaction and hold some dynamically filled textViews and radioButtons. I've tried to change to a specific fragment when I click the button 'fab' with the following code, but that doesn't work as I just get a blank fragment:
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fragment = mSectionsPagerAdapter.getItem(2);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
How do I move forward and backward through the fragments using buttons? I assume that it is better to declare those buttons in the activity and not in the fragment, isn't it? What do I need to change in the onClick method of those Buttons?
on the next button write this
NextFragment fragment = new NextFragment();
android.app.FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.content, fragment);
fragmentTransaction.addToBackStack(NextFragment.class.toString());
fragmentTransaction.commit();
on previous button simply write this
getActivity().getFragmentManager().popBackStack();
I navigate from fragment A which has a pager adapter with 2 fragments to fragment B committing the transaction to backstack. On returning to fragment A the pager adapter although initialised fails to load its fragments.
This part runs after returning to fragment A.
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
POSPagerAdapter posPagerAdapter = new POSPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager)getActivity().findViewById(R.id.pager);
viewPager.setAdapter(posPagerAdapter);
setQuantity(cart.quantity);
setCharge(cart.totalAmount);
cart.onCartChanged.subscribe(cartChangedSuscriber);
}
This is how i'm navigating to fragment B
PaymentMethodFragment f = PaymentMethodFragment.newInstance();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container,f)
.addToBackStack(null).commit();
Right now, I have five fragments (tabs) in my app as the image shows. And they are all listed as members of the tab bar in the MainActivity.java
public class MainActivity extends AppCompatActivity implements InputTab.SendMessage, FollowingTab.SendMessage, FollowerTab.SendMessage, ProfileTab.SendMessage {
private SectionsPageAdapter pageAdapter;
ViewPager viewPager;
public static String currentUser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, new ProfileTab());
fragmentTransaction.commit();
pageAdapter = new SectionsPageAdapter(getSupportFragmentManager());
// Sets up the ViewPager with the sections adapter
viewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager((viewPager));
}
// Adds fragments to SectionsPageAdapter and gives names for the corresponding tab
private void setupViewPager(ViewPager viewPager) {
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new InputTab(), "Search");
adapter.addFragment(new ProfileTab(), "Profile");
adapter.addFragment(new GithubTab(), "Github Repos");
adapter.addFragment(new FollowerTab(), "Followers");
adapter.addFragment(new FollowingTab(), "Followings");
viewPager.setAdapter(adapter);
}
Since I implemented a search tab, I was wondering if it's possible to create another page(or fragment) that displays the result of the search, and when I click the result, I want to make it direct to the corresponding tabs (Profile for users, and Github Repos for repo search).
In short, how can I create a page that is not part of the tab and still display it when I press the 'search' button?
Implement your TabLayout and ViewPager inside a fragment instead of the activiry and replace that fragment with the results fragment.
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();
I'm trying to change a fragment inside a ViewPager:
public void change() {
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.pager, mapa);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
mSectionsPagerAdapter.notifyDataSetChanged();
}
R.id.pager is my ViewPager id.
mapa is a inflated fragment.
If I call change(), the fragment I want to replace will disappear but the new fragment will not be load.
The view pager uses an Adapter to change the fragments it displays. Just like a ListView uses its adapter to get views to populate the list.
You have to extend FragmentPagerAdapter, create a new instance of it and set it to the pager with this line:
mViewPager.setAdapter(fragPagerAdapter);