0

Ich versuche, AsyncTaskLoader in Fragment zu verwenden, das ein Kind von ViewPager ist. Unterhalb eines Code meiner DayFragment:Wie aktualisiert man Inhalt in Fragment von ViewPager mit AsyncTaskLoader?

public class DayFragment extends Fragment 
     implements LoaderManager.LoaderCallbacks<DayAdapter.DayItem[]> { 

    private static final int CONTENT_LOADER = 0; 

    private DayAdapter mAdapter = null; 
    private int mWeekNumber = 1; 
    private int mDayCode = 1; 
    private Table.Timetable mTimetable; 
    private RecyclerView mRVContent; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     final MainActivity mainActivity = (MainActivity) getActivity(); 
     View v = inflater.inflate(R.layout.content, container, false); 
     mRVContent = (RecyclerView) v.findViewById(R.id.rvContent); 
     RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mainActivity); 
     mRVContent.setLayoutManager(layoutManager); 
     mAdapter = new DayAdapter(getActivity()); 
     mRVContent.setAdapter(mAdapter); 
     //Initialize the cursor loader 
     getLoaderManager().initLoader(CONTENT_LOADER, null, this).forceLoad(); 
     return v; 
    } 

    @Override 
    public Loader<DayAdapter.DayItem[]> onCreateLoader(final int id, Bundle args) { 

     if(CONTENT_LOADER == id) { 
      return new ContentLoader(getContext(), mWeekNumber, mDayCode, mTimetable); 
     } 

     return null; 
    } 

    @Override 
    public void onLoadFinished(Loader loader, DayAdapter.DayItem[] items) { 

     if(CONTENT_LOADER == loader.getId()) { 
      mAdapter.setIs24HourFormat(SettingsManager.is24HourFormat(getContext())); 
      mAdapter.clear(); 

      for (DayAdapter.DayItem item : items) { 
       mAdapter.add(item); 
      } 

      mAdapter.notifyDataSetChanged(); 

      if (items.length == 0) { 
       mRVContent.setBackgroundResource(R.drawable.bg_lesson_empty); 
      } else { 
       mRVContent.setBackgroundColor(0xFFFFFFFF); 
      } 
     } 
    } 

    @Override 
    public void onLoaderReset(Loader loader) { 

    } 

    private static final class ContentLoader extends AsyncTaskLoader<DayAdapter.DayItem[]> { 
     private final int mWeekNumber; 
     private final int mDayCode; 
     private final Table.Timetable mTimetable; 

     public ContentLoader(Context context, final int weekNumber, final int dayCode, 
          Table.Timetable timetable) { 
      super(context); 
      mWeekNumber = weekNumber; 
      mDayCode = dayCode; 
      mTimetable = timetable; 
     } 

     @Override 
     public DayAdapter.DayItem[] loadInBackground() { 
      DatabaseHandler db = new DatabaseHandler(getContext()); 
      db.openReadable(); 
      List<Table.Lesson> lessons = db.findLessons(mDayCode, mWeekNumber, mTimetable.getId()); 
      DayAdapter.DayItem[] items = new DayAdapter.DayItem[lessons.size()]; 

      for (int i = 0; i < items.length; ++i) { 
       Table.Lesson lesson = lessons.get(i); 

       Table.Subject subject = db.getSubject(lesson.getSubjectId()); 
       Table.Teacher teacher = db.getTeacher(lesson.getTeacherId()); 

       if (teacher == null) { 
        teacher = new Table.Teacher(""); //Empty name 
       } 

       items[i] = new DayAdapter.DayItem() 
         .setId(lesson.getId()) 
         .setTitle(subject.getTitle()) 
         .setSubtitle(teacher.getName())); 
      } 

      db.close(); 

      return items; 
     } 
    } 
} 

PageAdapater

public class PageAdapter extends FragmentStatePagerAdapter { 
    public static final int PAGE_COUNT = 7; 

    private int mWeekNumber; 
    private final int[] mDayCodes; 
    private final String[] mDays; 
    private final DayFragment[] mFragments = new DayFragment[7]; 
    private Table.Timetable mTimetable; 
    private boolean mIsRebuildMode = false; 

    public PageAdapter(Context context, FragmentManager fm, 
         Table.Timetable timetable, final int weekNumber) { 
     super(fm); 
     //Initialize class members 
    } 

    @Override 
    public Fragment getItem(int position) { 
     DayFragment dayFragment; 

     if (mFragments[position] == null) { 
      dayFragment = new DayFragment(); 
      Bundle args = new Bundle(); 
      args.putSerializable(Keys.TIMETABLE, mTimetable); 
      dayFragment.setArguments(args); 
      dayFragment.setWeekNumber(mWeekNumber); 
      dayFragment.setDayCode(mDayCodes[position]); 
      mFragments[position]= dayFragment; 
     } else { 
      dayFragment = mFragments[position]; 
     } 

     return dayFragment; 
    } 

    @Override 
    public void restoreState(Parcelable arg0, ClassLoader arg1) { 
     //do nothing here! no call to super.restoreState(arg0, arg1); 
    } 

    public void setWeekNumber(final int weekNumber) { 
     mWeekNumber = weekNumber; 
     Arrays.fill(mFragments, null); 
    } 

    public void setIsRebuildMode(final boolean isRebuildMode) { 
     mIsRebuildMode = isRebuildMode; 
    } 

    @Override 
    public CharSequence getPageTitle(final int position) { 
     return mDays[position]; 
    } 

    @Override 
    public int getCount() { 
     return PAGE_COUNT; 
    } 

    @Override 
    public int getItemPosition(Object object) { 

     if(mIsRebuildMode) { 
      return POSITION_NONE; 
     } 

     return super.getItemPosition(object); 
    } 
} 

Aber es ist nicht onLoadFinished Methode nicht nennen. Ich überprüfte Log Ausgang ... LoaderManager Anrufe onCreateLoader, aber es ruft nie onLoadFinished außer dem ersten Lauf (wenn App begann und ViewPager zeigt eine erste Seite (Fragment)). Es ist alles! Nach, wenn ich eine Seite zu einer nächsten und nächsten wechseln und auf eine erste Seite LoaderManager nicht onLoadFinished für die erste Seite auch aufrufen. Aber es erstellt Loader aufrufen onCreateLoader und setzt Loader aufrufen onLoaderReset. Ist es ein Witz von Google?

+0

Erstellen Sie neue DayFragment jedes Mal in getItem() Ihres PagerAdapter? Ich habe einen sehr vereinfachten Test Ihres Codes gemacht und er funktioniert, er zeigt onLoadFinished. Und, btw, no onLoaderReset wurde in Protokollen angezeigt –

+0

Nein, Fragment-Instanzen enthalten in der Liste. Adapter gibt das bereits erstellte Fragment zurück –

+0

Wenn Sie Ihren Adapter in FragmentPagerAdapter ändern, wurde etwas geändert? Ich kann das nicht reproduzieren (setze meine Fragment-Implementierung, weil nicht alle deine Felder vorhanden sind). Und verwenden Sie support.v4 überall? –

Antwort

1

Siehe Fragment Lebenszyklus. ViewPager do re nicht Fragment erstellen, nur swipe sie

- Beginn ViewPager : create : create : Start : wieder aufnehmen

nicht geändert, wenn Sie Fragmente Swipe

--- Schlaf Smartphone : Pause :

--- Wakeup Smartphone stoppen: Start : wieder aufnehmen : pa verwenden

--- Schließen ViewPager : stop : abzulösen

+0

Warum erstellt mein' ViewPager' jedes Mal eine Ansicht? –

+0

Ich weiß es nicht Sie können es selbst überprüfen. Fügen Sie das Einloggen in das interne Fragment hinzu und sehen Sie den Lebenszyklus. Ich benutze auch ViewPager und mache diese Erfahrung gerade jetzt. Das Ergebnis, das Sie oben sehen können – koa73

+0

Mein Adapter ruft in Fragmenten 'onCreate' und' onCreateView' Methoden für alle Fragmente, wenn es nicht die zwischengespeicherte Ansicht hat, überprüfte ich die Ausgabe. Die Variable 'mIsRebuildMode' hat den Wert' false'. –