2012-11-18 75 views
0

我想要一个分页布局,其中每个页面都是一个带有项目列表的片段。数据来自单个调用中的Web服务,并将被分隔(例如,通过关键字)到一个或多个列表中。扩展片段中的FragmentInstantiationException

我的尝试是使用ViewPager创造了“经理”:

其具有(阵列)适配器列表和片段列表。片段的实例:

class Page extends SherlockListFragment implements OnScrollListener 

与构造:

public Page(PagesManager manager, int id) 

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

编辑 这是适配器:

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); 
} 
+0

您可以发布您完全适配器类,你是如何创建适配器的实例? – LuxuryMode

+0

谢谢@LuxuryMode添加了代码 – miki

回答

1

我觉得你这样做是:

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

} 

我在管理器创建片段错误。您需要将FragmentPagerAdapter视为仅执行一件事和一件事:管理碎片处理为页面。现在,恰好是您添加到Fragment适配器的碎片本身具有处理其中的数据的适配器,但这并不意味着这些问题应该相交。您只需将Fragments添加到FragmentPagerAdapter。然后,在ListFragments内部,这些将由它们自己的适配器支持。换句话说,管理PagerAdapter内部的ArrayList<DiscoverListAdapter>()是一个很大的禁忌。 DiscoverListAdapter应该在各个片段的onCreateView上的onCreate中创建。

编辑:

的getItem在FragmentPagerAdapter通过在适配器给您的位置。你需要的是将数据绑定到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); 
} 
+0

谢谢。我如何知道在片段中ViewPager中的位置(或者标题或其他?)?我需要这个,因为它应该显示的数据根据​​它是哪个页面而不同;我想在一个网络请求中获取所有数据,并且每个片段都知道/被告知它的哪个子集要显示在它的列表中。 – miki

+0

@miki查看我的编辑 – LuxuryMode

+0

啊,我明白了,谢谢。所以基本上,如果我得到了这个正确的结论,就需要将我需要的信息传递给片段,这也将在系统重新创建片段时起作用,如http://stackoverflow.com/questions/所示。 9245408 /最佳实践换实例-A-新的Android片段 – miki