I have a MainActivity which contains a Sliding drawer for menu and a FragmentContainer to switch fragments.
I have a Fragment called History which has a layout like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/colorPrimary"
android:textColor="#FFFFFF"
app:pstsIndicatorColor="#FFFFFF" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tabs" />
</RelativeLayout>
And the class looks like this
public class HistoryFragment extends Fragment {
public HistoryFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
// Initialize the ViewPager and set an adapter
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(new PagerAdapter(getActivity().getSupportFragmentManager()));
// Bind the tabs to the ViewPager
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
tabs.setViewPager(pager);
return view;
}
class PagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = {"Last Transaction", "History"};
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new LastTransaction();
case 1:
return new AboutFragment();
}
return null;
}
}
}
This History page works fine the first time when it is called from the NavigationSlider menu. The history page contains two sliding tabs with two fragments. These are displayed the first time and everything works fine.
The problem happens, when they are called the second time or after that.
There is no error shown, the layout is loaded, the sliding tabs are shown, but their fragments are not shown and the sliders malfunction.
What may be the reason for this problem ?
I tried to use a different approach for implementing the sliders in fragments as per this StackOverflow answer. Still the same problem.
Thanks in advance.
replace
pager.setAdapter(new PagerAdapter(getActivity().getSupportFragmentManager()));
with
pager.setAdapter(new PagerAdapter(getActivity().getChildFragmentmanager()));
Reason:
The CHILD FragmentManager is the one that handles Fragments contained within the Fragment that it was added to.
Related
I'm using TabLayout and ViewPager in my app . I have 2 tabs in my ViewPager . I have the main 2 Fragment for the 2 tabs .
The first Fragment is like a form when user click submit , another Fragment appears to user and so on and be at the same position of the previous Fragment. I want to do that in the first Fragment (first position of my ViewPager) and keep the state of the previous fragment when I click back button . I hope that I posted my question in a right way
Here is my ViewPager
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".UI.Fragments.OnlineBookingModule.OnlineBookingFragment">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabLayout"
app:tabIndicatorColor="#color/colorPrimary"
android:background="#color/bg_nav"/>
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/viewPager"/>
</LinearLayout>
Here is My Pager Adapter
public class BookingPagerAdapter extends FragmentStatePagerAdapter {
private Context context;
public BookingPagerAdapter(#NonNull FragmentManager fm, int behavior,Context context) {
super(fm, behavior);
this.context=context;
}
#NonNull
#Override
public Fragment getItem(int position) {
if(position==0)
return new NewBookingFragment();
else
return new FutureBookingFragment();
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
if(position==0)
return context.getString(R.string.new_booking);
else
return context.getString(R.string.future_booking);
}
}
Here is how I setup my viewPager in my Fragment
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_online_booking, container, false);
tabLayout = view.findViewById(R.id.tabLayout);
viewPager = view.findViewById(R.id.viewPager);
Preferences preferences = new Preferences();
preferences.saveSmallDays(getActivity(),0);
preferences.saveBigDays(getActivity(),0);
assert getFragmentManager() != null;
pagerAdapter = new BookingPagerAdapter(getFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,getActivity());
tabLayout.setupWithViewPager(viewPager);
viewPager.setAdapter(pagerAdapter);
return view;
}
I'm a student in 2 year electrical and computer science : i am not familiar with android studio (most of the time i work on C++).
I made a joystick on processing for an android project, and then I exported my processing sketch to android studio, now I have to find a way to recover data (vector position) from my processing sketch to my main activity.
BUT here is the problem:
I want to add a TextView to my main activity but the processing sketch takes all the window, and I can't reduce it.
so what did i try :
I tried to place the fragment in a relative layout, and then place the TextView but it didn't work, even if i make the fragment very little it still taking the whole screen.
My thought are that there is a problem with this line ->
setContentView(frame, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
I made some screenshots:
Here the Main Activity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frame = new FrameLayout(this);
frame.setId(CompatUtils.getUniqueViewId());
setContentView(frame, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// setContentView(R.layout.main); // attach the view for this activity
sketch = new Joystick();
PFragment fragment = new PFragment(sketch);
fragment.setView(frame, this);
}
Here the view of the main activity
In order to have a fragment in your Main Activity you can do the following:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.*/
ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
private class YourFragmentAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YourFragment()
default:
return null;
}
}
#Override
public int getCount() {
return 1;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Your fragment name";
}
return null;
}
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Your fragment class:
public class YourFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
In this way you could have an activity with as many views as you want, and as many fragments as you wish. Note that if you have more than one fragment your activity will be more like a tabbed activity.
I am using https://github.com/astuetz/PagerSlidingTabStrip a navigation drawer(http://androidshenanigans.blogspot.com.es/2015/03/material-design-template.html).
When I put the fragment of the tabs in the navigation fragment I can not click on the tabs.
Also, when I add an item to fragment tab.It happens
the button is placed on top of the tab.If I do not navigation drawer, it works perfectly.
The code
AdapatadorTabs
public class AdapatadorTabs extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private String tabTitles[] = new String[] { "Tab1", "Tab2" };
public AdapatadorTabs(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentTab1();
case 1:
return new FragmentTab2();
default:
return null;
}
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}}
FragmentTabGeneral
public class FragmentTabGeneral extends Fragment {
public static final String ARG_PAGE = "ARG_PAGE";
private ViewPager viewPager;
public FragmentTabGeneral() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_telefonos, container, false);
// Get the ViewPager and set it's PagerAdapter so that it can display items
viewPager = (ViewPager)view.findViewById(R.id.pager);
viewPager.setAdapter(new AdapatadorTabs(getChildFragmentManager()));
// Give the PagerSlidingTabStrip the ViewPager
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip)view.findViewById(R.id.tabs);
// Attach the view pager to the tab strip
tabs.setViewPager(viewPager);
return view;
}}
FragmentTabGeneral XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frameTabs"
tools:context="com.prueba.NavigationDrawer.Fragmentos.FragmentTabGeneral">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:background="#ffff000c"
android:textColor="#ffffffff"
app:pstsIndicatorColor="#ffffffff"
app:pstsDividerColor="#ffff000c"
app:pstsIndicatorHeight="2dp"
app:pstsShouldExpand="true"
android:layout_width="match_parent"
android:layout_height="48dip" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs"
tools:context=".MainActivity" /></FrameLayout>
the code navigation is the template, if you need him, you can ask him http://androidshenanigans.blogspot.com.es/2015/03/material-design-template.html
greetings and thanks!
hello Friends i am little new to this Fragments concept!
Problem is
I am having a Actionbar with tabs and fragments now I want to implement viewpager inside one of the fragment of Actionbar tabs.
the point is to implement View pager with tabstrip inside a fragment
Please help me!
I hope that will be useful at least for anyone with the same problem if not for you.
You can put this fragment in every tab from action bar. The code is:
public class TabFragment extends Fragment {
ViewPager mViewPager;
DemoCollectionPagerAdapter mPagerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);
mPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager());
// Set up the ViewPager, attaching the adapter.
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mViewPager.setAdapter(mPagerAdapter);
return view;
}
}
I took PagerAdapter from the Effective Navigation example and just removed the "static" attribute in order to move it in the separate file:
public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); // Our object is just an integer :-P
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// For this contrived example, we have a 100-object collection.
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
Integer.toString(args.getInt(ARG_OBJECT)));
return rootView;
}
}
}
And the fragment_tab.xml for this TabFragment is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip android:id="#+id/pager_tab_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
Consider using a PagerTabStrip as a child view of ViewPager if you want the tab headers to be clickable and a PagerTitleStrip for them to be static (user can only swipe in order to switch to the tab).
Depending on your implementation of ActionBar with tabs I suppose there can arise some dependency problems because in this example I've used support library.
I've been trying to create a simple Horizontal scrolling option.
I have 2 ListFragments, which I would like to scroll between.
I'm getting a "Source Not Found" error when returning the View from onCreateView function.
This is my MainActivity Class:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
Fragment a;
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new FragmentA();
default:
return new FragmentB();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return "Section " + (position + 1);
}
}
}
This is one of my ListFragment class (the second is the same but different name & layout file):
public class FragmentA extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
}
updateStationView is a function that populates the List. removing it did not help, so I figured it's harmless.
The error is thrown right after the:
return rootView;
which returns to the onCreate functions of MainActivity.
When I'm changing the ListFragment to be a simple Fragment it works. I think I'm lacking some knowledge to figure this one out. I really want to use ListFragment...
Can someone please try an help ?
Many thanks for your efforts.
Adding the XML files:
activity_main.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
favorites_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
I im quite sure the issue is that your custom layout for the ListFragment does not contain a ListView. These lines of code are causing the error because you need to have a ListView inside your "favourites_layout" .xml file.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
ListFragment has a default layout that consists of a single list view.
However, if you desire, you can customize the fragment layout by
returning your own view hierarchy from onCreateView(LayoutInflater,
ViewGroup, Bundle). To do this, your view hierarchy must contain a
ListView object with the id "#android:id/list" (or list if it's in
code)
So your layout could for example look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
See here for more:
http://developer.android.com/reference/android/app/ListFragment.html