2013-10-28 35 views
0

我正在使用此实现http://developer.android.com/training/implementing-navigation/lateral.html#horizontal-paging创建一个像查看视图与查看分页器和片段的图库。在ViewPager中导航时应用程序崩溃

在我的代码中,我将从Web服务器中为特定的登录用户从viewpager中获取NUM_PAGES(整数)。

我在做什么:

我的网页与信息填充时的应用程序,它做了很多检查,以填充一个页面的用户登录,所以我创建的所有视图时的onCreate()被调用,并在每次片段需要它们时重复使用它们。

当我在viewpager中使用多个页面启动我的应用程序,浏览页面1到页面5时,该应用程序正常工作,当我尝试重新访问上一页时,应用程序与“java.lang.IllegalStateException”崩溃。

我是新来的碎片和viewpager,请帮我解决这个问题。

在此先感谢。

基兰

FATAL EXCEPTION: main 
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
    at android.view.ViewGroup.addViewInner(ViewGroup.java:3435) 
    at android.view.ViewGroup.addView(ViewGroup.java:3306) 
    at android.view.ViewGroup.addView(ViewGroup.java:3251) 
    at android.view.ViewGroup.addView(ViewGroup.java:3227) 
    at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 

我的代码:

protected void onCreate(Bundle savedInstance){ 

    //my code here 

    //prepare views to be used with viewpager 
    setupViews(); 

    //setup viewpager stuff 
    mAdapter = new ViewsAdapter(getSupportFragmentManager()); 

    mPager = (ViewPager) findViewById(R.id.pager); 
    mPager.setAdapter(mAdapter); 

    setContentView(R.layout.activity_main); 

    //other initializations here 
} 

public static class ViewsAdapter extends FragmentStatePagerAdapter{ 


    public ViewsAdapter(FragmentManager fragmentManager) { 
     super(fragmentManager); 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // TODO Auto-generated method stub 
     Fragment fragment = new VehicleFragment(); 
     Bundle args = new Bundle(); 

     args.putInt(VehicleFragment.VEHICLE_INDEX, position); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return NUM_PAGES;// this value will be fetched at runtime from a server. 
    } 

} 

public class VehicleFragment extends Fragment { 

    public static final String VEHICLE_INDEX = "VEHICLE_INDEX"; 

    @Override 
    public View onCreateView(LayoutInflater inflater, 
      ViewGroup container, Bundle savedInstanceState) { 
     Bundle args = getArguments(); 
     int position = args.getInt(VEHICLE_INDEX); 
     Log.i("VehicleHome", "retrieving position : "+position+" in viewsList, where viewsList size = "+viewsList.size()); 
     return viewsList.get(position); 
    } 
} 

private void setupViews() { 

//prepare Views here, the views are created at runtime and added to viewsList (ArrayList) 
//for reuse with fragments. So that each time a new instance of fragment is created we won't endup 
//inflating layout file and initializing the view again and again.. 

//views logic 

viewsList.add(view); 

} 
+0

如果你清理这个问题,删除代码是多余的理解问题,并显示什么是从调用堆栈相关的它可能会有所帮助。 –

回答

0

我想你不应该创建一个新片段在每次请求页面时。相反,一次创建所有这些,然后就返回正确的一个:

public static class ViewsAdapter extends FragmentStatePagerAdapter{ 

    private ArrayList<Fragment> fragments; 

    public ViewsAdapter(FragmentManager fragmentManager) { 
     super(fragmentManager); 
     fragments = new ArrayList<Fragment>(); 
     for (int i = 0; i < NUM_PAGES; i++) { 
      Fragment fragment = new VehicleFragment(); 
      Bundle args = new Bundle(); 

      args.putInt(VehicleFragment.VEHICLE_INDEX, position); 
      fragment.setArguments(args); 
      fragments.add(fragment); 
     } 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // in case dynamic amount of fragments is needed, you can create 
     // new ones here if necessary (checking e.g. if position > fragments.size()-1) 
     fragments.get(position); 
    } 

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

} 
+0

嗨Nieminen,试着说你的话,仍然存在问题。我认为问题在于Iam将视图与片段联系起来的方式。因为我第一次返回一个视图时,底层viewpager impl可能试图将视图重新添加到片段中以供后续调用... –

+0

嗯。再看看,'setupViews'看起来有点可疑。据我所知,你不能重用特定的视图,这可能会解释'IllegalStateException'。一旦视图拥有父视图,则不能在其他位置使用相同的视图。接下来我要做的是删除您拥有的视图优化,并为每个片段分别创建视图。 –

+0

终于我能解决我的问题,我改变了我的实现使用FragmentPagerAdapter而不是FragmentStatePagerAdapter并停止重用视图。它现在工作正常(虽然我无法优化我的代码)。 –

相关问题