FragmentStatePagerAdapter returning wrong position to TextView - android

Ok, I have an Activity where I have viewpager and textview. Then I Have adapter that extends FragmentStatePagerAdapter, here is the code for it:
public AdapterCustomPage(FragmentManager fm, Context context, TextView TV ) {
super(fm);
mContext = context;
mTV = TV;
}
#Override
public Fragment getItem(int position) {
// Create fragment object
Fragment fragment = new ImageFragmentKatalozi();
Bundle args = new Bundle();
Log.i("Poizicija" , String.valueOf(position));
String url = Static.katalozi.getSlikeKataloga().get(position);
args.putString("url", url);
fragment.setArguments(args);
mTV.setText(String.valueOf(position + 1) + "/" + String.valueOf(maxBrojStrana));
String link = Static.katalozi.getUrl();
args.putString("linkKataloga", link);
if(position == 0){
Message.message(mContext, "Na prvoj stranici kataloga ste");
}
if(position == getCount() - 1){
Message.message(mContext, "Na poslednjoj stranici kataloga ste");
}
return fragment;
}
#Override
public int getItemPosition(Object object) {
pozicija = super.getItemPosition(object);
return super.getItemPosition(object);
}
#Override
public int getCount() {
return maxBrojStrana;
}
And finally I have fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_katalozi_slike, container, false);
args = getArguments();
imageView = (TouchImageView) rootView.findViewById(R.id.imageViewAdapterZaListanjeKataloga);
Picasso.with(getActivity()).load(args.getString("url")).placeholder(R.drawable.load).error(R.drawable.error).into(imageView);
return rootView;
}
Now, the problem is, my TextView in the main activity isnt giving me back right positions for the fragment. It gives good getCount position, but when I slide to the right it goes + 1, when I slide to the left, it goes down to 0. When I put the whole textView code and xml in the fragment section, it works good, but then it slides with fragment. Any help?

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
brojStranica.setText(String.valueOf(position + 1) + "/" + String.valueOf(Static.katalozi.getSlikeKataloga().size()));
}
#Override
public void onPageScrollStateChanged(int state) {
}
});

Related

Infinite FragmentStatePagerAdapter with different fragment classes

I came across a strange issue in my project.
I have implemented infinite viewpager adapter using FragmentStatePagerAdapter
Code for same is:
public class DashBoardAdapter extends FragmentStatePagerAdapter {
ArrayList<AbstractFragment> fragments;
private int MAXFRAGMENTS=0;
public DashBoardAdapter(FragmentManager fm, ArrayList<AbstractFragment> fragments) {
super(fm);
this.fragments = fragments;
MAXFRAGMENTS=fragments.size();
}
#Override
public AbstractFragment getItem(int position) {
return fragments.get(position%MAXFRAGMENTS);
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
#Override
public CharSequence getPageTitle(int position) {
return fragments.get(position%MAXFRAGMENTS).getTitle();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
int virtualPosition = position % MAXFRAGMENTS;
return super.instantiateItem(container, virtualPosition);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
int virtualPosition = position % MAXFRAGMENTS;
super.destroyItem(container, virtualPosition, object);
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
MAXFRAGMENTS = fragments.size();
}
}
And the Main Activitycode(Function only) is something like this:
public void initializeViewPager()
{
verticalViewPager = (VerticalViewPager) findViewById(R.id.verticalviewpager);
enabledPages=new ArrayList<>();
enabledPages.addAll(getEnabledPages(false));
adapter=new DashBoardAdapter(getSupportFragmentManager(),enabledPages);
verticalViewPager.setAdapter(adapter);
verticalViewPager.setPageTransformer(true, new PageTransformer());
verticalViewPager.setCurrentItem(999+position);
verticalViewPager.setOffscreenPageLimit(1);
verticalViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(adapter!=null)
title.setText(adapter.getPageTitle(position));
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private ArrayList<AbstractFragment> getEnabledPages(boolean a)
{
ArrayList<AbstractFragment> fragments=new ArrayList<>();
fragments.add(FragmentAttendance.newInstance(fragments.size()));
fragments.add(FragmentCompensation.newInstance(fragments.size()));
if(a)
fragments.add(FragmentTimeOff.newInstance(fragments.size()));
if(a)
fragments.add(FragmentCalendar.newInstance(fragments.size()));
if(a)
fragments.add(FragmentPeople.newInstance(fragments.size()));
if(a)
fragments.add(FragmentProvisions.newInstance(fragments.size()));
position = fragments.size()-(999+position)%fragments.size();
return fragments;
}
Layout of activity contains just a Viewpager.
And the Fragments, I have used is just copy of below fragment with different names
public class FragmentAttendance extends AbstractFragment {
public static final String ARG_SECTION_NUMBER = "section_number";
String title ="Testing";
public static FragmentAttendance newInstance(int sectionNumber) {
FragmentAttendance fragment = new FragmentAttendance();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public FragmentAttendance() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.card_attendance, container, false);
return rootView;
}
#Override
public String getTitle() {
return title;
}
}
Layout of fragment has just LinearLayout with a TextView.
The code is running superb if I am adding fragments more than three fragments. Howsoever as soon as the number of added fragments gets below four. My code Works in strange behavior.
Some of errors are Fragment already initialised
Other are Forward scrolling shows fragement View Howsoever when I scroll backward No view appears.
The working code can be tested by passing true to getEnabledPages(true);
And the non working code can be tested by passing false to getEnabledPages(false);
Please someone help me in this strange behaviour.

android viewpager like image gallery

im trying to create an image gallery.
i have a ViewPager that each Fragment contains an image (swipable image gallery is what im trying to accomplish).
i also have a GridView that onitemclick triggers the ViewPager in the selected position showing the clicked image.
my problem is that one swipe to right and one swipe to left shows the same image as the clicked one.
ive tried setoffscreenpagelimit with no success.
this is my viewpager activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
helper = new WeddHelper(this,"wedd.db",null,1);
pager = (ViewPager) findViewById(R.id.pager);
pager.setOnPageChangeListener(this);
Intent ing = getIntent();
curr = ing.getIntExtra("curr", 0);
byto = helper.getPhotos();
count = byto.size();
FragmentManager mg = getSupportFragmentManager();
fragments = new Vector<Fragment>();
for(int i = 0; i<count;i++){
fragments.add(Fragment.instantiate(this,GalleryFrag.class.getName()));
}
mAdapter = new FragmentAdapter(getSupportFragmentManager(), fragments, this);
pager.setAdapter(mAdapter);
pager.setOffscreenPageLimit(1);
pager.setCurrentItem(curr);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mCurrentPosition = position;
curr = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
public int getClicked(){
return curr;
}
public byte[] getPhotoToBeDisplayed(){
return byto.get(curr);
}
}
this is my custom adapter:
public class FragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments=null;
private FragmentManager fragmentManager=null;
private Context context;
public FragmentAdapter(FragmentManager fragmentManager,List<Fragment> fragments, Context context) {
super(fragmentManager);
this.fragments=fragments;
this.fragmentManager=fragmentManager;
this.context = context;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
{
super.setPrimaryItem(container,0,object);
}
#Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
fragmentManager.executePendingTransactions();
fragmentManager.saveFragmentInstanceState(fragments.get(position));
}
public void replaceItem(int position,Fragment fragment)
{
fragments.set(position, fragment);
this.notifyDataSetChanged();
}
}
and this is the fragment:
public class GalleryFrag extends Fragment {
WeddHelper helper;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.gallery_fragment, container, false);
ImageGallery myActivity = (ImageGallery) getActivity();
int curr = myActivity.getClicked();
byte[] photoToBeDisplayed = myActivity.getPhotoToBeDisplayed();
helper = new WeddHelper(getActivity(),"wedd.db", null, 1);
ArrayList<byte[]> imgs = helper.getPhotos();
Bitmap br = BitmapFactory.decodeByteArray(photoToBeDisplayed,0,photoToBeDisplayed.length);
Bitmap bi = BitmapFactory.decodeByteArray(imgs.get(curr),0,imgs.get(curr).length);
Toast.makeText(getActivity(), curr+"this is from frag", Toast.LENGTH_SHORT).show();
ImageView iv = (ImageView) v.findViewById(R.id.fragImage);
iv.setImageBitmap(br);
return v;
}
}

Android Viewpager.setCurrentitem() and FragmentPagerAdapter instantiateItem() fragments initailize mismatch

I have problem with FragmentPagerAdapter ,I have set fragments in viewpager through FragmentPagerAdapter,
I have to show viewpager dynamically,I have listview data , which I need to show in viewpager,
when I click on the listview , I have to load exact position in the viewpager
so i just set the total size of the item to show in FragmentPagerAdapter, But the problem is that when I select the viewpager position through mPager.setCurrentItem(listposition) it show correct position of the viewpager,
but the data load at wrong place, it load in next fragement in viewpager position,after some tracking in FragmentPagerAdapter, I show that instantiateItem method initailize one fragment in advance, like i set the currentitem (from listview)of viewpager 2
then instantiateItem method initalize 0 to 3 fragment, I think that the reason the data load in 3rd fragment,I tried a lot with FragmentStatePagerAdapter also but no any success , please help me , thanks in advance.
Mainactivity class(Fragmnetactivity) :
public class NewsDetail extends FragmentActivity implements OnClickListener {
public static ViewPager mPager;
private static int NUM_PAGES;
private PagerAdapter mPagerAdapter;
public static ArrayList<Integer> exist_detail = new ArrayList<Integer>();
public static ArrayList<PageFragment> detailfragment = new ArrayList<PageFragment>();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
NUM_PAGES = topList.size();
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putInt("page", i);
fragment.setArguments(args);
detailfragment.add(fragment);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
if (PageFragment.getInstance() != null) {
Log.d("LOG","PageFragment || "+ PageFragment.getInstance());
PageFragment.getInstance().startLoadingNews(
MusicList.topMusicList.get(arg0)._id);
}
return;
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
#Override
public void onPageScrollStateChanged(int arg0) {}
});
mPagerAdapter.notifyDataSetChanged();
mPager.setCurrentItem(listposition);// setcurrent item from here , it is selected from list. "listposition" indicate list position click
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
private FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;
private static final boolean DEBUG = false;
public ScreenSlidePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.mFragmentManager = fragmentManager;
}
#Override
public Fragment getItem(int position) {
return detailfragment.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return super.getItemId(position);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Log.v("LOG", "On InstantiateItem " + position);// it indicate that this method initialize one fragment in advance.
return super.instantiateItem(container, position);
}
public String makeFragmentName(int viewId, long index) {
return "android:switcher:" + viewId + ":" + index;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG)
Log.e("LOG", "Detaching item #" + position + ": f=" + object
+ " v=" + ((Fragment) object).getView());
mCurTransaction.detach((Fragment) object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
PageFragment
public class PageFragment extends Fragment implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
mDetailPageFragment = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
rootView = (ViewGroup) inflater.inflate(R.layout.newsdetail, container,
false);
//init();
return rootView;
}
public void startLoadingNews(String _id) {
if (NetworkUtil.cheackNetwork(mActivity)) {
executeTask(_id);
} else {
showRetryCancelDialog();
}
}
}
I can see two issues in the code you've posted:
Only instantiate your fragments in FragmentPagerAdapter.getItem. Don't instantiate them and save them to some list or array, let the FragmentPagerAdapter do that for you. In FragmentPagerAdapter.instantiateItem it checks if the Fragment was already created and if so it returns it, if not, it'll call your getItem to create the fragment.
Don't use the Singleton scheme for your fragment, create a new fragment using a constructor or a .newInstance() static helper.

Android animating ImageViews within a ViewPager

Hi i have a view pager that loads fragments and i'm wanting to add a bit of animation to an ImageView make it move up as the ViewPager scrolls. problem i'm having is that the viewPager creates the views for the first two pages so the animation doesnt happen on those pages. Is there is a way to detect if viewpager is scrolling or if the page has changed?
heres what i have tried so far - heres my viewPagerAdapter
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(page == 0){
view = inflater.inflate(R.layout.layout_tutorial, container, false);
}else if(page == 1){
view = inflater.inflate(R.layout.layout_tutorial, container, false);
tutImage = (ImageView)view.findViewById(R.id.tutImage);
int imageResource = getResources().getIdentifier("tut_view_2", "drawable", context.getPackageName());
Drawable tutImageDrawable = getResources().getDrawable(imageResource);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
tutImage.setBackground(tutImageDrawable);
}else{
tutImage.setBackgroundDrawable(tutImageDrawable);
}
}else if(page == 2){
view = inflater.inflate(R.layout.layout_tutorial, container, false);
tutImage = (ImageView)view.findViewById(R.id.tutImage);
int imageResource = getResources().getIdentifier("tut_view_3", "drawable", context.getPackageName());
Drawable tutImageDrawable = getResources().getDrawable(imageResource);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
tutImage.setBackground(tutImageDrawable);
}else{
tutImage.setBackgroundDrawable(tutImageDrawable);
}
heres my viewpager
public static class MyPagerAdapter extends FragmentPagerAdapter {
private Context context;
public MyPagerAdapter(android.support.v4.app.FragmentManager fragmentManager,Context c) {
super(fragmentManager);
context = c;
}
#Override
public int getCount() {
int levelCount = 4;
return levelCount;
}
// Returns the fragment to display for that page
#Override
public TutorialAdapter getItem(int position) {
String data = null;
return TutorialAdapter.newInstance(position, data, context);
}
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
You need to use a OnPageChangeListener, set it to your viewpager:
viewPager.setOnPageChangeListener(myOnPageChangeListener);
The OnPageChangeListener implements some methods like:
#Override
public void onPageScrollStateChanged(int state) {}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageSelected(int position) {}
They can help you. Check this for more information: ViewPager.OnPageChangeListener!

PagerAdapter not called inside fragment when I move to the fragment for the second time in Android

I'm working with viewpager inside fragments. I'm using pagerAdapter to switch between two pages via XML. Here is the code:
public class DemoPagerAdapter extends FragmentPagerAdapter {
public DemoPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
Fragment f;
switch (index) {
case 0:
f = new FirstFragment();
break;
case 1:
f = new SecondFragment();
break;
}
return f;
}
#Override
public int getCount() {
return 2;
}
}
And I'm calling it like this:
public class DemoFragment1 extends Fragment {
private ViewPager viewPager;
private DemoPagerAdapter mAdapter;
public DemoFragment1() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.security, container, false);
mAdapter = new DemoPagerAdapter(getActivity().getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
showPages(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
return rootView;
}
Everything works fine. But if I move to DemoFragment2 and then come back to DemoFragment1, PagerAdapter is not called.
Your ViewPager is nested in a Fragment, you should use the ChildFragmentManager, modify:
mAdapter = new DemoPagerAdapter(getChildFragmentManager());
I also assume the ViewPager will keep the off screen fragment in memory, thus it might not call getItem(int index) again. Add
viewPager.setOffscreenPageLimit(0);
return rootView;
Well, I encontered this issue last week.
When I put the ViewPager in the fragment with a FragmentPagerAdapter, after I move forward to anoter Fragment and back, the pager' s view not exists.
I supposed is the FragmentPagerAdapter won' t retain its view in the ViewPager ' s host Fragment, Their life cycle is not the same. Though you put the VewPager' s host Fragment in the back stack, but the FragmentPagerAdapter' s fragment not. And Then, I gave up FragmentPagerAdapter and tried android.support.v4.view.PagerAdapter, (note, it wont' t use fragment to inject view!), everything is fine!
below is the sample:
private final PagerAdapter coverPager = new PagerAdapter() {
private LayoutInflater mLayoutInflater;
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
if (mLayoutInflater == null) {
mLayoutInflater = LayoutInflater.from(getActivity());
}
switch (position) {
case 0:
View frontPage = mLayoutInflater.inflate(R.layout.profile_cover, container, false);
ImageView avatar = (ImageView) frontPage.findViewById(R.id.avatar);
Picasso.with(getActivity())
.load(mAvatarUrl)
.placeholder(R.drawable.error)
.error(R.drawable.error)
.into(avatar);
TextView screenName = (TextView) frontPage.findViewById(R.id.screen_name);
screenName.setText("#" + mScreenName);
TextView remark = (TextView) frontPage.findViewById(R.id.remark);
remark.setText(TextUtils.isEmpty(mRemark) ? mScreenName : mRemark);
if (mVerified) {
frontPage.findViewById(R.id.verified).setVisibility(View.VISIBLE);
}
container.addView(frontPage);
return frontPage;
case 1:
View introPage = mLayoutInflater.inflate(R.layout.profile_intro, container, false);
CatnutUtils.setText(introPage, R.id.description, TextUtils.isEmpty(mDescription)
? getString(R.string.no_description) : mDescription);
CatnutUtils.setText(introPage, R.id.location, mLocation);
CatnutUtils.setText(introPage, R.id.profile_url, Constants.WEIBO_DOMAIN + mProfileUrl);
container.addView(introPage);
return introPage;
default:
return null;
}
}
};
and then in your onViewCreate or OnCreateView, put mViewPager.setAdapter(coverPager);
the instantiateItem is the place to put the page' s view, similar like the FragmentPagerAdapter!
It' s just like put the FragmentAdapter' s view int the ViewPager' s host Fragment, not the other fragment!
Hope it' s helpful!

Categories

Resources