I'm building a FragmentPagerAdapter (The one with the small icons) which I want;
To the first item in the middle (Horizontal) of the screen
To swipe through it and make them go one 5th of the screen to the left/right
What would be the best way to achieve this?
This is a visual representation:
This is the code of the FragmentPagerAdapter:
public class NavigationPagerAdapter extends FragmentPagerAdapter {
public NavigationPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return NavigationFragment.newInstance(position);
}
#Override
public int getCount() {
return stores.size();
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public float getPageWidth(int position) {
return 0.2f;
}
}
I hope I understood this right. Try to add the following configuration to your `ViewPager.
pager.setOffScreenPageLimit(4);
pager.setClipToPadding(false);
pager.setPageMargin(-500);
pager.setHorizontalFadingEdgeEnabled(true);
pager.setFadingEdgeLength(20);
Feel free to customize the values and get your desired effect
Related
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();
}
}
I have implemented the first row of tab.
Inside that tab i have another set of Tabs.
Specifically two more tabs.
Please refer to these images.
The Picture above is the dog tab is selected.
The picture above is I want to select the Cat tab.
But unfortunately, the tab is not sliding properly.
its like its just a slowly scrolling.
but it should be on just one slide it should be on the cat tab.
My First layer of tab is inside Fragment.
The second row of tab is also in Fragment.
public class AdapterFragmentPagerItem extends FragmentStatePagerAdapter {
String[] pageTitle={"Do's","Dont's","First Aid"};
public AdapterFragmentPagerItem(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
return new FragmentDo();
case 1:
return new FragmentDonts();
case 2:
return new FragmentFirstAid();
}
return null;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
return pageTitle[position];
}
}
The above code is for the first image.
public class AdapterFragmentDos extends FragmentStatePagerAdapter {
String[] pageTitle = {"Dog", "Cat"};
public AdapterFragmentDos(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(position==0){
return new FragmentDonts();
}else{
return new FragmentFirstAid();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return pageTitle[position];
}
}
And this is for the second image.
I using view pager for swipe view for android app. I build view pager Dynamically. Like add and remove item. Now i want to know how to get exactly position of view pager items.For example, I have 3 items, i want to get 3rd number position when i am in 2nd or 1st item. i used viewPager.getCurrentItem() but it return where i am.
Please suggest me how to give personal ids of every viewpager items and used it in when item is background or on screen.Thanks please help me about this, i left 2 weeks already for this. Thanks in advance
public TabsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
return new MyWebBrowser();
}
#Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
#Override
public int getCount() {
return COUNT_TAB;
}
}
Now this code Under my fragment class, from WebView chrom class i want to set up title as website title.
#Override
public void onReceivedTitle(WebView view, String title) {
TAB_TITLE=title;
Toast.makeText(HomeActivity.this,title,Toast.LENGTH_LONG).show();
super.onReceivedTitle(view, title);
}
take a look at this Adapter:
class MyAdapter extends FragmentStatePagerAdapter
{
private final SparseArray<WeakReference<YourFragment>> mPageReferences;
public MyAdapter(FragmentManager fm) {
super(fm);
mPageReferences = new SparseArray<WeakReference<YourFragment>>();
}
#Override
public Fragment getItem(int i) {
WeakReference<YourFragment> fragment =
new WeakReference<YourFragment>(YourFragment.newInstance());
mPageReferences.put(i, fragment);
return fragment.get();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferences.remove(position);
}
#Override
public int getCount() {
return number of fragment;
}
public YourFragment getFragment(int key) {
return mPageReferences.get(key).get();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
WeakReference<YourFragment> fragment = new WeakReference<YourFragment>((YourFragment) super.instantiateItem(container,
position));
mPageReferences.put(position, fragment);
return fragment.get();
}
}
you can easily get the reference of any pages from mPageReferences BUT be careful because it may be null because it is possible that it has not created when you call it. you can use (getFragment(int key) to get the item at the position of key)
you can know the current position from the PagerAdapter.
by calling pageAdapter.getItemPosition(itemNumber)
link to the documentation
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".
Let's say I have two pages in my viewpager, is it any way to move from page 2 to page 1, but doing this like user is accesing page 3 (with all the animation)
You can achieve this by using a custom FragmentPagerAdapter that provides the same fragments over and over again:
private class EndlessPagerAdapter extends FragmentPagerAdapter {
private EndlessPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position % 2 == 0) {
return fragmentOne;
} else {
return fragmentTwo;
}
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
}
Set the adapter for your ViewPager and start somewhere in the middle to allow almost endless swiping in either direction:
mViewPager.setAdapter(new EndlessPagerAdapter(getChildFragmentManager()));
mViewPager.setCurrentItem(Integer.MAX_VALUE/2);