扩展片段中的FragmentInstantiationException

时间:2012-11-18 02:40:40

标签: java android actionbarsherlock

我希望有一个分页布局,其中每个页面都是一个包含项目列表的片段。数据来自单个呼叫中的Web服务,并将(通过关键字)分隔为一个或多个列表。

我尝试使用ViewPager并创建了一个“经理”:

class PagesManager extends FragmentPagerAdapter

,它有一个(数组)适配器列表和一个片段列表。片段是以下实例:

class Page extends SherlockListFragment implements OnScrollListener

使用构造函数:

public Page(PagesManager manager, int id)

哪个课程导致FragmentInstantiationException;我可以通过其他方式将引用和id传递给页面并留下一个空构造函数,但即使我在适配器上调用notifyDataSetChanged(),也不会重绘列表。所以我的问题是,如何让具有不同属性的同一Fragment类的多个实例(ViewPager中的页面数量需要可自定义)能够在系统重新实例化后恢复其配置?我意识到这可能过于笼统,但我觉得我的问题是设计,我确实有一些工作正常的代码,除非片段在旋转时被破坏或者应用程序在后台的时间太长。

修改 这是适配器:

public class DiscoverListAdapter extends ArrayAdapter<String> {
    private final Context context;
    private DiscoverPagesManager manager;
    private int id;


    public DiscoverListAdapter(Context context, DiscoverPagesManager manager, int id) {
        super(context, R.layout.note_item);

        this.context = context;
        this.manager = manager;
        this.id = id;
    }

    @Override
    public int getCount() {
        return manager.pageGetCount(id);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // load up the stuff
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.note_item, parent, false);

        // now fill it up
        Note note = manager.pageGetNote(id, position);
        ((TextView) rowView.findViewById(R.id.note_item_displayname))
                .setText(note.getUser().getUsername());
        return rowView;
    }

}

我在经理中创建片段:

public DiscoverPagesManager(Context context, FragmentManager fm) {
        super(fm);

        pages = new ArrayList<Fragment>();
        pages.add( new SearchPage() );

        adapters = new ArrayList<DiscoverListAdapter>();
        adapters.add(null);

        notes = new ArrayList<List<Note>>();
        notes.add(null);
DiscoverPage page;
        for(int i=1; i<titles.length; i+=1) {
            page = new DiscoverPage(this, i);
            this.pages.add( page );
            this.adapters.add( new DiscoverListAdapter(context, this, i) );
            this.notes.add(null);
        }

@Override
public Fragment getItem(int position) {
    return this.pages.get(position);
}

1 个答案:

答案 0 :(得分:1)

我认为你做错了。您需要将FragmentPagerAdapter视为只做一件事而且只做一件事:将Fragments的处理作为页面进行管理。现在,恰好是你添加到Fragment适配器的Fragments本身就有处理它们内部数据的适配器,但这并不意味着这些问题应该相互交叉。您只需将Fragments添加到FragmentPagerAdapter即可。然后,在ListFragments内部,它们将由自己的适配器支持。换句话说,在PagerAdapter内部管理ArrayList<DiscoverListAdapter>()是一个很大的禁忌。应在单个片段的onCreateView上的onCreate内创建DiscoverListAdapter。

编辑:

FragmentPagerAdapter中的

getItem将适配器中的位置传递给您。你需要的是将数据绑定到Fragment。使用这样一个简单,干净的模式:

public class MyFragment extends Fragment {
 private int mPosition;
public static MyFragment newInstance(int position) {
   MyFragment fragment = new MyFragment();
   Bundle bundle = new Bundle();
   bundle.putInt("position", position);
   fragment.setArguments(bundle);
   return fragment;
}

public void onCreate(Bundle savedState) {
  super.onCreate(savedState);
  Bundle data = getArguments();
  mPosition = data.getInt("position");
  //do something based on position

}
}

//在你的PagerAdapter:

@Override
public Fragment getItem(int position) {
    return MyFragment.newInstance(position);
}