1

EDIT: It looks like ViewPager does not reflect change of underlying adapter - swapCursor() is called correctly, but getItem() is never called. I found a solution to similar problem on SO, but it does not helped in my case. EDIT 2 & SOLUTION: Thanks to this answer I found out that I'm providing a FragmentManager instead of ChildrenFragmentManager to CalendarPageAdapter.


I had SherlockFragmentActivity, which held a ViewPager. The same activity implemented LoaderCallbacks, which refreshed myAdapter in the onLoadFinished().

I moved this activity to a Fragment - so it extends SherlockFragment and still implements LoaderCallbacks, but swapping cursor stopped working. In onLoadFinished() correct data provided in cursor, but nothing is swapped. I didn't changed anything in my adapter nor fragment for pager filling. Where can be problem?

My new fragment is as follows:

public class MyFragment extends SherlockFragment implements LoaderCallbacks<Cursor> {
    private CalendarPageAdapter myAdapter;
    private ViewPager viewPager;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_fragment, container, false);

        myAdapter = new CalendarPageAdapter(getChildFragmentManager());  // <- EDIT 2
        viewPager = (ViewPager) view.findViewById(R.id.pager);
        viewPager.setAdapter(myAdapter);

        return view;
    }

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        getLoaderManager().initLoader(0, null, this);
    }

    . . . .

    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        myAdapter.swapCursor(data);
            viewPager.setCurrentItem(data.getCount());  // skip to last column
        printoutCursorContent();  // prints out correct cursor content
    }
}

And my adapter is simple just like this:

public class CalendarPageAdapter extends FragmentStatePagerAdapter {
    private Cursor cursor;

    public CalendarPageAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        cursor.moveToPosition(position);
        int calendarId = cursor.getInt(cursor.getColumnIndex(CalendarTable.COLUMN_ID));

        return DayFragment.newInstance(calendarId);
    }

    @Override
    public int getCount() {
        if (cursor == null)
            return 0;
        else
            return cursor.getCount();
    }

    public void swapCursor(Cursor c) {
        if (cursor == c)
            return;

        cursor = c;
        notifyDataSetChanged();
    }

    public Cursor getCursor() {
        return cursor;
    }
}
Community
  • 1
  • 1
shmoula
  • 1,053
  • 2
  • 10
  • 33

3 Answers3

0

If I understood correctly, your Cursor loads the propper data but the AdapterView doesn't reflect that change. If that's the case try adding this line at the end of your onLoadFinished(Loader<Cursor> loader, Cursor data) method:

myAdapter.notifyDataSetChanged();
nstosic
  • 2,584
  • 1
  • 17
  • 21
  • negative, it didn't do nothing; as I said - the same code worked correctly previously - in activity – shmoula Nov 25 '13 at 19:54
  • Could you also post how you call the `Loader` object? – nstosic Nov 25 '13 at 19:58
  • You mean onCreateLoader() method? I'm not sure if I understand your question correctly :). – shmoula Nov 25 '13 at 20:00
  • Yeah I meant the all the Loader methods, however, it occurs to me now that since your implementation worked in your activity and your cursor holds the correct data, the error might simply be in displaying the `Adapter` data. First, use debugging mode to determine if the data from the `Cursor` is passed to the `Adapter`. In case it is, you're missreferencing an `AdapterView` that should display the data, or that View is inaccessible or unmodifiable. Check its attributes during debugging. – nstosic Nov 25 '13 at 20:04
  • So it looks like data from Cursor are correctly passed into my adapter, but getItem() in that adapter is never called! My adapter is a really veri simple extension of FragmentStatePagerAdapter, I'm going to add source of that to my question. – shmoula Nov 25 '13 at 20:41
  • That is puzzling. Your adapter implementation is OK. But I ran out of ideas :( – nstosic Nov 25 '13 at 20:55
  • I'm going to try it with another version of android-support-library - I've already had some problems with recent version, maybe it's some bug inside that. – shmoula Nov 25 '13 at 20:58
  • Still the same. Also tried invalidate() on ViewPager... without results. I found similar problem (added link to question), but it didn't helped with my problem also :(. – shmoula Nov 25 '13 at 21:18
  • A step closer - I provided FragmentManager instead of ChildrenFragmentManager, but still no success. Please see EDIT 2. – shmoula Nov 26 '13 at 12:11
0

Oh my! The second edit was right: use getChildFragmentManager() instead of getFragmentManager(). My change just does not apply, until I uninstalled application and/or cleared the project. Damn you, Eclipse!

shmoula
  • 1,053
  • 2
  • 10
  • 33
0

@shmoula @NitroNbg

I have the same problem as both of you, but in a different situation

I have an activity with a viewpager (calendar too) and every page is a fragment with a loader:

Activity

...
fragmentPagerAdapter = new MainFragmentPagerAdapter(getSupportFragmentManager(), calendarView.getCalendarDays());
...

FragmentStatePagerAdapter

public class MainFragmentPagerAdapter extends FragmentStatePagerAdapter {

...

public MainFragmentPagerAdapter(FragmentManager fm, ArrayList<CalendarDay> calendarDays) {
    super(fm);

    ...
}

public int getCurrentIndex(String currentDate) {
    int index = dateTimes.indexOf(currentDate);
    return index;
}

@Override
public Fragment getItem(int i) {
    return EventByDayFragment.newInstance(dateTimes.get(i));
}

@Override
public int getCount() {
    return dateTimes.size();
}

}

Fragment

public class EventByDayFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    containerView = inflater.inflate(R.layout.fragment_event_by_day, container, false);
    findViews();
    return containerView;
}

...

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mainEventsAdapter.swapCursor(data);
    listView.onRefreshComplete();
    mainEventsAdapter.notifyDataSetChanged();
}

...



 private void setInitData() {
     mainEventsAdapter = new MainEventsAdapter(getActivity());
     listView.setAdapter(mainEventsAdapter);
 }

 ...

}

But In my case I can't use getChildFragmentManager()

cesards
  • 15,882
  • 11
  • 70
  • 65
  • you wrote that you can't use getChildFragmentManager() - so did you try to get that reference in parent and pass it into child fragment or where you want it? – shmoula Jan 02 '14 at 21:43
  • In your case, the PagerAdapter is inside your Fragment, in mine, is inside the Activity You : Fragment -> PagerAdapter Me : Activity -> FragmentStatePagerAdapter -> Fragment -> CursorAdapter So.. What should I do? – cesards Jan 03 '14 at 08:26
  • well, maybe open a question here, why do we trying to solve that here? :D – shmoula Jan 03 '14 at 13:00