I am working on the application in which I added a Navigation Drawer with Tabs. So, for the Navigation Drawer menu option I create a fragment for each option and it works well...
In my main Activity I inflate my TabFragment (contains fragment_1, or fragment_2) as UI, and on the Fragment_1 there is one Button and when I click the button I want to open the Navigation Drawer fragment....
My Navigation Drawer fragment opens fine, but the problem is when my Navigation drawer fragment is open my titleBar doesn't change as per the fragment title...
Note: I know when we open a fragment we have to replace the fragment View to the new fragment View but I want to open a Fragment as an Activity
Picture1: When I click on Button the Second Picture appears, but I want to change the TitleView and remove the Navigation drawer icon.
Edit
In my MainActivity, I inflate Tabfragment as
mFragmentTransaction=mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.containerView, new TabFragment()).commit();
MyTabFragment :
public class TabFragment extends Fragment {
public TabFragment() {
// Required empty public constructor
}
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2 ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View x=inflater.inflate(R.layout.content_main_menu,null);
tabLayout=(TabLayout) x.findViewById(R.id.tabs);
viewPager =(ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new HomeFragment();
case 1:
return new Offers();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Home";
case 1:
return "Offers";
}
return null;
}
}
}
On Button click in HomeFragment(or fragment_1)
Fragment fragment = new NavigationDrawerFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
I just find my Question's Answer..
Before i tried to call fragment to fragment class that's why my ContainerView Remains same in the NavigationDrawer Fragment. So Now this time, I am Creating a new Activity and in this Activity I inflate the navigation Drawer fragment, due to this my previous ContainerView is Replaced by the New Activity layout
Related
If I use a TabLayout with FragmentPagerAdapter, the overridden function getItem(int position) just return one fragment. In case of lager screen I would like to have 2 fragments to be returned.
How can I do it? should wrap these 2 fragments into one fragment and use that instead or is there any better solution?
FragmentPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: //Ingredients
return IngredientsFragment.newInstance(mRecipe);
case 1: // Details
{
// TODO Here instead of DetailFragment I want to return
// two fragments called DetailFragment and StepFragment.
return DetailFragment.newInstance(mRecipe);
}
default:
throw new RuntimeException(this.toString() + " Wrong fragment!");
}
}
And then in my Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Initializing, etc.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
I do not see you have much of a wiggle room here.
These two options are exlusive:
You are returning one Fragment with two nested fragments (Wrapped fragment)
You are returning two fragments each anchored to his own tab.
If you would like two fragments to appear on singular page of ViewPager, you have no choice but to wrap them.
Otherwise swiping would go between these two fragments, which is the same as if they are completely different, that is non-correlated.
OK I managed to solve the problem using a Fragment consist of two other fragments as children.
Just do not forget in this case the FragmentManager object should be populated with getChildFragmentManager() to work properly.
For more info look at my BakingApp project DetailStepWideScreenFragment.java
GitHub Repos
Fragment Wrapper:
public class DetailStepWideScreenFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_detail_step_wide_screen, container, false);
// I added the fragments here. StepFragment can be replaced using
// replaceStepFragment function.
DetailFragment detailFragment = DetailFragment.newInstance(mRecipe);
StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.fl_detail_fragment_wide_screen, detailFragment);
transaction.add(R.id.fl_step_fragment_wide_screen, stepFragment);
transaction.commit();
return view;
}
public void replaceStepFragment(String stepId) {
mStepId = stepId;
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
transaction.replace(R.id.fl_step_fragment_wide_screen, stepFragment);
transaction.commit();
}
}
PagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private DetailStepWideScreenFragment currentFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
currentFragment = null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: //Ingredients
return IngredientsFragment.newInstance(mRecipe);
case 1: // Details
{
// Show base on screen size.
if (mIsLargeScreen) {
DetailStepWideScreenFragment detailStepWideScreenFragment = DetailStepWideScreenFragment.newInstance(mRecipe, "0");
currentFragment = detailStepWideScreenFragment;
return detailStepWideScreenFragment;
} else {
return DetailFragment.newInstance(mRecipe);
}
}
default:
throw new RuntimeException(this.toString() + " Wrong fragment!");
}
}
#Override
public int getCount() { return 2; }
public DetailStepWideScreenFragment getCurrentFragment() {
return currentFragment;
}
}
I have three Fragments attached to ViewPager. If i am Fragment1, and i have a button on Fragment1, i want on button click of that 'Fragment', access the Fragment3 but on the same time if i slide the page,i don't want to access the Fragment3. while sliding i want to access only up to Fragment2. How can i do this.
TabPagerAdapter.java:-
public class TabPagerAdapter extends FragmentStatePagerAdapter
{
public TabPagerAdapter(FragmentManager fragmentManager)
{
super(fragmentManager);
}
#Override
public Fragment getItem(int position)
{
switch (position)
{
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
}
return null;
}
#Override
public int getCount()
{
return 3;
}
I have implemented something very similar: Previously I had four fragments in my ViewPager, but then decided that I want to integrate two of those fragments more intimately by reducing the number of fragment that I can reach by sliding and switching back and forth between two fragments by using a button. The implementation took me a while, though. I did not manage to mess with the index of my fragmentList properly. In the end, the trick was to take out those two fragments from the ViewPager altogether and add a HolderFragment instead. Within this fragment I implemented the fragment transaction for hiding one and showing the other fragment.
Here is the code from my HolderFragment:
public class HolderFragment extends Fragment {
private Context context;
private Fragment currentFragment;
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_holder, container, false);
OneFragment oneFragment =
(OneFragment) Fragment.instantiate(context, OneFragment.class.getName());
OtherFragment otherFragment =
(OtherFragment) Fragment.instantiate(context, OtherFragment.class.getName());
// oneFragment selected on view creation
FragmentManager fm = this.getChildFragmentManager();
fm.beginTransaction().add(R.id.holder_fragment_holder, oneFragment).commit();
fm.beginTransaction().add(R.id.holder_fragment_holder, otherFragment).hide(mediaFragment)
.commit();
currentFragment = oneFragment;
return view;
}
public void switchFragments(Fragment fragment) {
if (!fragment.equals(currentFragment)) {
this.getChildFragmentManager().beginTransaction().hide(currentFragment).commit();
currentFragment = fragment;
this.getChildFragmentManager().beginTransaction().show(currentFragment).commit();
}
}
}
Then, whenever the switch button is pressed just call holderFragment.switchFragments(oneFragment) or holderFragment.switchFragments(otherFragment) from the activity that holds the ViewPager (and a reference to the HolderFragment).
Try this
mViewPager.setCurrentItem(your_position, true);
I am getting issue with ViewPager. I am using FragmentActivity and I added the multiple fragment inside FragmentActivity as following method.
public void addFragment(Fragment fragment, boolean addToBackStack, int transition) {
FragmentTransaction ft = getFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_up,R.anim.slide_down,R.anim.slide_up,R.anim.slide_down);
ft.replace(R.id.main, fragment);
ft.setTransition(transition);
if (addToBackStack)
ft.addToBackStack(null);
ft.commit();
}
I am using ViewPager Inside the fragment. ViewPager is working fine when FragmentActivity loaded. but when i use another fragment ViewPager got invisible.
for example
a.) Fragment A with ViewPager
b.) Fragment B without ViewPager
Fragment A working fine when I run App. when i go to Fragment B
then I again i replace Fragment B to Fragment A then ViewPager is not working. I see the blank view where I am using ViewPager.
Please let me know How can i solve this issue
Thanks
I solved it myself the issue was when you use the ViewPager inside the fragment use getChildFragmentManager() instead of getSupportFragmentManager() or getFragmentManager().
That's it.
I cannot comment so I'm going to write an answer here.
Why you don't just put the viewpager as a fragment:
public class ViewPager extends Fragment{
public static final String TAG = ViewPager.class.getSimpleName();
private ViewPagerAdapter mAdapter;
public static ViewPager newinstance(){
ViewPager viewPager = new ViewPager();
return viewPager ;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_pager, container, false);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
mAdapter = new ViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(mAdapter);
return view;
}
}
In your adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter{
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
return Fragment.newinstance();
}
#Override
public int getCount() {
return 5; //number of pages on your viewPager
}
Then on your main activity you can make the transaction to add the view pager
ViewPager viewPager = ViewPager.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.content_frame,viewPager);
ft.addToBackStack(ViewPager.TAG);
ft.commit();
My application has 3 tabs, each represented by Fragments. There is a custom FragmentPagerAdapter which also implements ActionBar.TabListener. Initially my FragmentPagerAdapter was returning new instances of fragments in public Fragment getItem(int index) method. Also, my TabListener implementation was instantiating Fragments and showing/hiding them in the onTabSelected/onTabUnselected. Unfortunately this approach doesn't fit me well, because in this case each Fragment is actually created twice. What I want is to create it once and then just hide/show, when necessary.
For that I have instantiated my fragment earlier in the activity and passed them to the PagerAdapter:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_tabs_layout);
List<Fragment> fragments = initTabFragments();
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final ActionBar actionBar = getSupportActionBar();
TabsPagerAdapter pagerAdapter = new TabsPagerAdapter(this, getSupportFragmentManager(), fragments, viewPager);
viewPager.setAdapter(pagerAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int tab_name : tabs) {
Tab tab = actionBar.newTab();
actionBar.addTab(tab.setText(tab_name).setTabListener(pagerAdapter));
}
...
}
private List<Fragment> initTabFragments() {
List<Fragment> fragments = new ArrayList<Fragment>(3);
fragments.add(SherlockFragment.instantiate(this, TabFragment1.class.getName()));
fragments.add(SherlockFragment.instantiate(this, TabFragment2.class.getName()));
fragments.add(SherlockFragment.instantiate(this, TabFragment3.class.getName()));
return fragments;
}
Then in the PagerAdapter I just return fragment:
#Override
public Fragment getItem(int index) {
return fragments.get(index);
}
To handle Tab selection there is the following code:
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
int position = tab.getPosition();
String tag = "android:switcher:" + viewPagerId + ":" + position;
Fragment fragment = context.getSupportFragmentManager().findFragmentByTag(tag);
switch (position) {
case 0:
if (fragment == null) {
ft.add(viewPagerId, fragments.get(0), tag);
} else {
// If it exists, simply attach it in order to show it
ft.show(fragments.get(0));
}
break;
}
case 1:
if (fragment == null) {
ft.add(viewPagerId, fragments.get(1), tag);
} else {
// If it exists, simply attach it in order to show it
ft.show(fragments.get(1));
}
break;
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.hide(fragments.get(0));
break;
case 1:
ft.hide(fragments.get(1));
break;
}
}
In this case each fragment is instantiated once. And the first tab is shown correctly, but when I switch between tabs second and third tabs are empty (just white background). Why?
I was trying to add fragment to a container android.R.id.content, but exception was thrown: Can't change container ID of fragment.... I found out that it is because when Fragment is returned in getItem method it is added to a viewPager container. That why I use viewPagerId when add fragment to a transaction.
Any help would be greatly appreciated.
Have a ExampleFragment class defined that extends Fragment. Something like shown below
public class ExampleFragment extends Fragment {
private View categoryView;
private ViewPager mViewPager;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
categoryView = inflater.inflate(R.layout.viewpager, container, false);
mViewPager = (ViewPager) categoryView.findViewById(R.id.pager);
return categoryView;
}
public ViewPager returnViewPager() {
return mViewPager;
}
}
main_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
tools:context=".ExampleFragmentActivity" >
<fragment
android:id="#+id/main_fragment"
android:name="somepackage.ExampleFragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
And then add this in the onCreate() of ExampleFragmentActivity
ExampleFragment fragment = (ExampleFragment) getSupportFragmentManager().findFragmentById(R.id.main_fragment);
mViewPager = fragment.returnViewPager();
fragmentManager = getSupportFragmentManager();
TL;DR Within a ViewPager, I have a Fragment with two child fragments, when I change the background color of list in one child fragment, it sometimes also change the background color of the other child fragment.
So, I have ViewPager with 2 fragments, fragment 1 (FragmentOne) has 2 child fragment, FragmentOneA and FragmentOneB, fragment 2 is FragmentTwo.
FragmentOneA is just a Fragment and FragmentOneB is a ListFragment.
In FragmentOneB, I set color between odd row and even row. Odd row is yellow, even row just white.
So within the ViewPager, the fragment I show first in FragmentOne is FragmentOneA, then I pressed button in FragmentOneA to replace that fragment with FragmentOneB.
This happened:
1) I pressed button in FragmentOneA to replace it with FragmentOneB. Then I pressed Back button to pop the stack. I did that few times.
2) At sometime, the background color in FragmentOneA was changed to yellow. And then I did number 1) again and at some time, the background was changed back to white.
I just don't understand why this happened.
Image of FragmentOneA before event 1) with white background:
Image of FragmentOneB that's shown after I click that blue button "Cari penerbangan":
Image of FragmentOneA after I did event number 1) a few times:
The code of Activity that holds the ViewPager:
public class MyActivity extends ActionBarActivity {
private static final int NUM_PAGES = 2;
private ViewPager viewPager;
private PagerAdapter adapter;
private FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
adapter = new PagerAdapter(fragmentManager);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);
}
#Override
public void onBackPressed() {
Fragment fragment = (Fragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":"viewPager.getCurrentItem());
if (fragment != null) { // could be null if not instantiated yet
if (fragment.getView() != null) {
// Pop the backstack on the ChildManager if there is any. If
// not, close this activity as normal.
if (!fragment.getChildFragmentManager().popBackStackImmediate()) {
finish();
}
}
}
}
private class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FragmentOne d = new FragmentOne();
return d;
case 1:
return new FragmentTwo();
}
return null;
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
The code of FragmentOne:
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FrameLayout root = new FrameLayout(getActivity());
root.setId(R.id.layout_root);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.layout_root, new FragmentOneA());
transaction.commit();
return root;
}
}
The code of FragmentOneA when the blue button get clicked:
FragmentTransaction transaction = getParentFragment().getChildFragmentManager().beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.layout_root, new FragmentOneB());
transaction.commit();
Long post, but I've reviewed my code many times, so if you know anything please give me some answers. Many thanks for you..
My point is, I just want to use odd-even row color, but somehow that affects my other fragment.