【问题标题】:Loader does not refresh adapter after finishing in fragment加载器在片段中完成后不刷新适配器
【发布时间】:2013-11-25 19:48:37
【问题描述】:

编辑:看起来 ViewPager 没有反映底层适配器的变化 - swapCursor() 被正确调用,但 getItem() 从未被调用。我在 SO 上找到了similar problem 的解决方案,但对我来说没有帮助。 编辑 2 和解决方案:感谢 this answer 我发现我正在向 CalendarPageAdapter 提供 FragmentManager 而不是 ChildrenFragmentManager。


我有 SherlockFragmentActivity,它拥有一个 ViewPager。相同的活动实现了 LoaderCallbacks,它在 onLoadFinished() 中刷新了 myAdapter。

我将此活动移至 Fragment - 因此它扩展了 SherlockFragment 并仍实现 LoaderCallbacks,但交换光标停止工作。在 onLoadFinished() 中,游标中提供了正确的数据,但没有交换任何内容。我没有更改适配器中的任何内容,也没有更改寻呼机填充的片段。哪里有问题?

我的新片段如下:

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
    }
}

我的适配器很简单,就像这样:

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;
    }
}

【问题讨论】:

    标签: android android-fragments actionbarsherlock


    【解决方案1】:

    如果我理解正确,您的Cursor 会加载propper 数据,但AdapterView 不会反映该更改。如果是这种情况,请尝试在 onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) 方法的末尾添加这一行:

    myAdapter.notifyDataSetChanged();
    

    【讨论】:

    • 否定的,它什么也没做;正如我所说 - 相同的代码以前可以正常工作 - 在活动中
    • 您能否也发布您如何调用Loader&lt;Cursor&gt; 对象?
    • 你的意思是 onCreateLoader() 方法?我不确定我是否正确理解了您的问题:)。
    • 是的,我的意思是所有 Loader 方法,但是,我现在想到,由于您的实现在您的活动中工作并且您的光标包含正确的数据,错误可能只是显示 @987654326 @ 数据。首先,使用调试模式确定来自Cursor 的数据是否传递给Adapter。如果是这样,您将错误引用应该显示数据的AdapterView,或者该视图不可访问或不可修改。在调试期间检查其属性。
    • 所以看起来来自 Cursor 的数据已正确传递到我的适配器中,但该适配器中的 getItem() 从未被调用!我的适配器是 FragmentStatePagerAdapter 的一个非常简单的扩展,我将在我的问题中添加它的来源。
    【解决方案2】:

    天哪!第二个编辑是正确的:使用 getChildFragmentManager() 而不是 getFragmentManager()。在我卸载应用程序和/或清除项目之前,我的更改并不适用。该死的,Eclipse!

    【讨论】:

      【解决方案3】:

      @shmoula @NitroNbg

      我和你们两个有同样的问题,但情况不同

      我有一个带有 viewpager(日历)的活动,每个页面都是一个带有加载器的片段:

      活动

      ...
      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();
      }
      

      }

      片段

      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);
       }
      
       ...
      
      }
      

      但就我而言,我不能使用 getChildFragmentManager()

      【讨论】:

      • 您写道您不能使用 getChildFragmentManager() - 那么您是否尝试在父片段中获取该引用并将其传递到子片段或您想要的地方?
      • 在您的情况下,PagerAdapter 在您的 Fragment 内,在我的情况下,在 Activity 内您:Fragment -> PagerAdapter Me:Activity -> FragmentStatePagerAdapter -> Fragment -> CursorAdapter 所以.. 我应该怎么做做什么?
      • 好吧,也许在这里打开一个问题,我们为什么要在这里解决这个问题? :D
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多