So I'm trying to create a swipe tab view in my app. But the problem I'm having is that my fragments need to be FragmentActivity becuase they have listview inside them.
So I think this is where I'm getting my error:
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
case 3:
//Other fragment activity
return new OtherFragment();
}
return null;
}
This needs to be:
public FragmentActivity getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
case 3:
//Other fragment activity
return new OtherFragment();
}
return null;
}
But I keep getting errors on this line:
public FragmentActivity getItem(int index) {
Error:
The return type is incompatible with FragmentPagerAdapter.getItem(int)
Does anyone know what I'm doing wrong here?
My class is extending FragmentPagerAdapter
A Fragment can also have a ListView in it.
FragmentActivity is some support Class, to support Fragments on older devices, i think its pre api 11.
To use a ListView in a Fragment, just create a ListView in the Fragment, or inflate an xml file with a ListView in it.
FragmentPagerAdapter getItem() method needs to return a Fragment. FragmentActivity is not a Fragment, it's an Activity containing Fragments. See here: http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
Use ListFragment for Fragments having a ListView
http://developer.android.com/reference/android/support/v4/app/ListFragment.html
Your fragment don't need to be FragmentActivity to hold a ListView, actually the Activity should extend FragmentActivity, and your fragment should extend ListFragment, which is:
a fragment that displays a list of items by binding to a data source
such as an array or Cursor, and exposes event handlers when the user
selects an item.
I made a post about it that explains how fragments work, how to implement a ListView inside a fragment and how to integrate Fragments with ViewPager. Here is the link, hope it helps.
Related
I 'm using a viewpager as a questionnaire. The user inputs their answers in the first 8 fragments, then their answers are displayed in the 10th fragment (OverviewFragment). It's all working great. The issue I have a question about is when the user returns to a past fragment, ie: Fragment 4 and changes an answer, if they return to the 10th fragment it doesn't update. I'm sure this is a lifecycle/backstack issue but unsure how to kick fragments off the backstack in a viewpager. Or maybe just a way to ensure that fragment is constantly refreshed?
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
private int fragmentCount = 11;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return DemoFragment.newInstance();
case 1:
return PreliminaryQuesFragment.newInstance();
case 2:
return QuestionOneFragment.newInstance();
case 3:
return QuestionTwoFragment.newInstance();
case 4:
return QuestionThreeFragment.newInstance();
case 5:
return QuestionFourFragment.newInstance();
case 6:
return QuestionFiveFragment.newInstance();
case 7:
return QuestionSixFragment.newInstance();
case 8:
return StatementFragment.newInstance();
case 9:
return OverviewFragment.newInstance(user.getTitle(), prelimAnswer, qOne, qTwo,
qThree, qFour, qFive);
case 10:
return GoodbyeFragment.newInstance(position);
default:
return null;
}
}
#Override
public int getCount() {
return fragmentCount;
}
}
It's likely an issue with how your Fragment's state is being restored when a Fragment that has been previously created is navigated back to -- is your FragmentStatePagerAdapter really creating a NEW fragment instance, or reusing an old one it's already been created, and using it's previous Bundle args?
I've run into a similar issue when creating Fragment's and passing a full Parcelable object as the UI Model to use when populating the Fragment's UI. Once the Fragment was navigated back to, the original Parcelable was used when recreating the Fragment's View (so, the old, original object from the Bundle args I set on the Fragment on it's initial creation). To get around this issue, I passed an ID reference to each Fragment in it's Bundle args instead (so, just some integer or something), that mapped to the present, in memory copy of the model Object I was trying to display in the UI.
So, even though my Fragment was recreated with the same bundle args, I would use SomeInMemoryHelperObjectContainingMyMap.get(ID) to get the most recent version of that object to populate the UI.
How can I set a TAG for fragment that is created like this:
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position) {
case 0: return new scanFragment();
case 1: return new shopingListFragment();
case 2: return new PayOnlineFragment();
}
return new scanFragment();
}
I want to set a TAG to be able to communicate between fragments using interfaces.
The documentation of the Fragment class does not expose any setter for the tag. See http://developer.android.com/reference/android/app/Fragment.html
However a Fragment always has a tag (at least once they are attached, maybe earlier im'm not sure). So you can use getTag() to get the tag of your fragment and use it to communicate with it.
So far I have only implemented ViewPager with one type of fragment.
Now I want to add navigation tabs and be able to slide sideways from fragment of type A to fragment of type B . Do I need to contain both types of fragments in one activity ? If so , does it matter which fragment will have the view pager?
thank you.
Neither of the fragments contain the ViewPager. That would be contained in this case in your activity. The navigation tabs sit above the Viewager. Look at this tutorial: https://github.com/codepath/android_guides/wiki/Sliding-Tabs-with-PagerSlidingTabStrip . You can specify what fragments go in the ViewPager in the getItem method of a FragmentPagerAdater.
#Override
public Fragment getItem(int position) {
Fragment fragment =null;
switch (position) {
case 0:
fragment = fragment1.newInstance();
break;
case 1:
fragment = fragment2.newInstance();
break;
case 2:
fragment = fragment3.newInstance();
break; }
return fragment;
}
I followed this tutorial to create an app with four tabs in the action bar [tab1][tab2][tab3][tab4].
When I change from a tab to the nearest one, the destination tab doesn t refresh for example from 1->2 , 3->4 or 3->2, but the problem is when I change from 1->3 or 4, 2->4 ...(a far tab) the destination tab refresh, how can I disable this ?
In the tutorial code, a new instance of fragment is getting generated every time it went to background.
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
Instead of it create fragment at the top level i,e create once you start the class.
public class TabsPagerAdapter extends FragmentPagerAdapter {
TopRatedFragment frag1;
GamesFragment frag2;
MoviesFragment frag3;
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
if(frag1 == null)
frag1 = new TopRatedFragment();
return frag1;
case 1:
//repeat same here
case 2:
//repeat same here
}
By this, if an instance of fragment already exist, then it will return that instance instead of new one.
I am using the standard Android tabs and I need to access my tabs from the parent activity.
I do the following in my MainActivity to get my tabs:
myTab = ((FirstTabFragment)mAdapter.getItem(index));
The problem is that I always get a new object and not the instance because the getItem is implemented as follows:
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Status fragment activity
return new FirstTabFragment();
case 1:
// Mission fragment activity
return new SecondTabFragment();
case 2:
// Team fragment activity
return new ThirdTabFragment();
}
return null;
}
...
I googled quite a lot but I still can't find any working solution to get the instance ob my Fragments.
I need the instance because I need to alter the fragment's views and therefore I need it's variables.
Any ideas?
Thanks!
The best way is to use the FragmentManager with the method findFragmentById or findFragmentByTag. Of course, you need to declare an ID or a TAG for each fragment created by the FragmentPagerAdapter. If I remember correctly, the default implementation uses the class name as tag.
Save the fragment in SparseArray or in HashMap. Add the fragment in array in your getItem method also override the onFragmentDestroy method. In method remove the item from SparseArray or HashMap. Now create a getter method somthing like this
public Fragment getFragment(int pos) {
return array.get(pos);
}