Tab fragments in android - android

public class MyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
#Override
public int getCount() {
int s = this.fragments.size();
return this.fragments.size();
}
}
Text here:
if i go from tab4 to tab2 than first control go to tab2 than it go to tab1. i could not understand how can it go to tab1?

I can see you're trying to cache the fragments into memory by using the this context. But you're not supposed to, FragmentPagerAdapter class should do it for you. Google webpage and sample # FragmentPagerAdapter. Look at sample code on that page.
Code snippet:
#Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
Notes:
Notice the call to method newInstance. Implement it in your Fragment.
Need to define a fragment subclass, sample uses ArrayListFragment.

Related

Lag with ViewPager

I'm developing an app that displays information about wifistate, battery and other stuffs. To do this, I'm using fragments and each one has It's own ListView showing the info. When I slide from a fragment to another one, Listviews make the UI lag causing a bad user experience. How could I avoid this?
Thank You in advance.
EDIT:
This is my Adapter code:
public class GenericFragmentPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> _fragments;
public GenericFragmentPagerAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
_fragments = fragments;
}
#Override
public int getCount() {
return _fragments.size();
}
#Override
public Fragment getItem(int position) {
return _fragments.get(position);
}
#Override
public String getPageTitle(int position) {
return ((ITitledFragment) _fragments.get(position)).getTitle();
}
}

FragmentPagerAdapter override getItem() method clash

In order to implement sliding tabs in Android, i am following this guide: Google Play Style Tabs using TabLayout
At the point of implement the FragmentPageAdapter i am having a problem whith the "getItem()" method which is supossed to return the fragment with the associated position, in this case "PageFragment.newinstance(position + 1)". Being PageFragment a generic Fragment.
The problem itself is:
'getItem(int)' in 'com.myProject.SampleFragmentPagerAdapter' clashed
with 'getItem(int)' in 'android.support.v4.app.FragmentPagerAdapter';
attempting to use incompatible return types
Can someone figure out where the problem is?
I have attached the SampleFragmentPagerAdapter of the guide for faster checks:
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[] { "Tab1", "Tab2", "Tab3" };
private Context context;
public SampleFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
return PageFragment.newInstance(position + 1);
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
Solved, the problem was that SampleFragmentPagerAdapter class uses android.support.v4.app.Fragment
I was using, android.app.Fragment in PageFragment class.
That resulted in getItem method of SampleFragmentPagerAdapter having a clash between types because of diferent libraries.
Solution? Change the import line from
android.app.Fragment
to
android.support.v4.app.Fragmentin PageFragment Class.

update a fragment on ViewPager based on the fragment before

I am using ViewPager with fragments and a FragmentStatePagerAdapter, i need update my second fragment based on what the user checked in the first one, what happens is that both fragments are loaded when the fragment activity is started, so doesn't matter what the user checks on the first fragment, the second will not get updated. i've tried to override de getItemPosition with the notifyDataSetChanged for call a method to update my fragment, but it appears to be called just when it's created, i need update the second fragment when the user check the options that he want in the first fragment. Thanks
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(mFragments.get(position) instanceof UpdateableFragment){
notifyDataSetChanged();
}
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public int getItemPosition(Object object) {
if (object instanceof UpdateableFragment) {
((UpdateableFragment) object).customize();
}
return super.getItemPosition(object);
}
}

Why can't I use FragmentSupportManager inside a FragmentsStatePagerAdapter?

In the android documentation on FragmentStatePagerAdapter it is explained that the adapter can be set up like this:
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
return MyFragment.newInstance();
}
}
I would like to use this, however, I would also like to manage the Fragments that were added with a FragmentManager. How can I do this? My approach is throwing a NullPointerException.
public static class MyAdapter extends FragmentStatePagerAdapter {
private FragmentManager mFragmentManager;
public MyAdapter(FragmentManager fm) {
super(fm);
mFragmentManager = fm;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
mFragmentManager.beginTransaction()
.add(MyFragment.newInstance(), MyFragment.TAG).commit();
return mFragmentManager.findFragmentByTag(MyFragment.TAG);
}
}
How can I do this?
You write your own PagerAdapter implementation from scratch. FragmentPagerAdapter and FragmentStatePagerAdapter will do their own fragment transactions, colliding with yours.

Android ViewPager prepend new View

I want to prepend a new View as first page of my ViewPager.
My adapter looks like this:
public class PagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int index) {
return fragments.get(index);
}
#Override
public int getCount() {
return fragments.size();
}
public void add(int i, ImageFileObject imageFile) {
ImageViewFragment f = new ImageViewFragment();
f.setImage(imageFile);
fragments.add(0, f);
notifyDataSetChanged();
}
public void add(ImageFileObject imageFile) {
ImageViewFragment f = new ImageViewFragment();
f.setImage(imageFile);
fragments.add(f);
notifyDataSetChanged();
}
}
But when calling add(0, aImageFile) the item is not prepended to the fragment list. (It's not even appended).
Any ideas?
Update: The problem that you described in comment is real, I missed it in first testing. After analyzing the source code of FragmentPagerAdapter I realized that all we need to do is to Override getItemId() in a way that it won't return same id for different fragment items. E.g. current default implementation would just return position as an id for fragment which won't work for this case:
public long getItemId(int position) {
return position;
}
I am updating this answer, please have a look. As before I have tested this code and the problem you described is not happening now.
Only thing you need is not to keep reference of fragments by yourself in List, This is done for you by FragmentPagerAdapter. And as far as I know its not a good practise either. And also even if you return POSITION_NONE from getItemPosition() as suggested by other answer(s), you will end up with Exception
Caused by: java.lang.IllegalStateException: Can't change tag of fragment.
This is because you are trying to reposition alive Fragments in your List by adding a fragment at 0th index (which causes other fragments to reposition) and ViewPager assigns tags based on position.
Keeping all this in mind, here is a tested and working modified adapter:
public class PagerAdapter extends FragmentPagerAdapter {
public static class FragmentInfo {
public String classz;
public ImageFileObject imageFile;
public static long IDS;
public long id;
public FragmentInfo(){
id = IDS++;
}
}
private final List<FragmentInfo> fragments;
private Context context;
public PagerAdapter(FragmentManager fm, List<FragmentInfo> fragments,
Context context) {
super(fm);
this.fragments = fragments;
this.context = context;
}
#Override
public Fragment getItem(int index) {
FragmentInfo info = fragments.get(index);
ImageViewFragment frag = (ImageViewFragment) Fragment.instantiate(
context, info.classz, /* null arguments*/ null);
frag.setImage(info.imageFile);
return frag;
}
#Override
public long getItemId(int position) {
return fragments.get(position).id;
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
public void add() {
FragmentInfo f = new FragmentInfo();
f.classz = ImageViewFragment.class.getName();
fragments.add(0, f);
notifyDataSetChanged();
}
}
Please change your code accordingly.
The problem is actually with notifyDataSetChanged. Just add to your Adapter:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
However, I think you will get other problems when the Adapter actually tries to call getItem again. These problems will be in the lines of "Fragment Already Added".

Categories

Resources