2014-04-17 4 views
2

루트보기에 3 개의 탭이있는 응용 프로그램을 빌드하고 있습니다. 탭 기능 변경을 위해 스 와이프를 포함 시켜서 Android 교육 문서에 제안 된대로 지원 프레임 워크와 FragmentPagerAdapter를 사용하고 싶습니다. 처음 두 탭은 맞춤 어댑터를 사용하여 문제없이 구축되었습니다. 그러나 ArrayAdapter를 사용하여 세 번째 탭을 추가 할 때 두 번 이상 탭을 변경하면 IllegalStateException이 발생합니다.ArrayAdapter에서 FragmentPagerAdapter를 사용할 때 IllegalStateException이 발생했습니다.

04-17 17:17:13.792: E/AndroidRuntime(2158): FATAL EXCEPTION: main 
04-17 17:17:13.792: E/AndroidRuntime(2158): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.ViewGroup.addViewInner(ViewGroup.java:3509) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.ViewGroup.addView(ViewGroup.java:3380) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.ViewGroup.addView(ViewGroup.java:3325) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.ViewGroup.addView(ViewGroup.java:3301) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.view.ViewPager.populate(ViewPager.java:1068) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.view.ViewPager.populate(ViewPager.java:914) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.support.v4.view.ViewPager$3.run(ViewPager.java:244) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.Choreographer.doFrame(Choreographer.java:531) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.os.Handler.handleCallback(Handler.java:730) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.os.Handler.dispatchMessage(Handler.java:92) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.os.Looper.loop(Looper.java:137) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at android.app.ActivityThread.main(ActivityThread.java:5103) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at java.lang.reflect.Method.invoke(Method.java:525) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
04-17 17:17:13.792: E/AndroidRuntime(2158):  at dalvik.system.NativeStart.main(Native Method) 

위의 코드에서 알 수 있듯이 Android 라이브러리 코드 만 있습니다. 아무도 그것을 고칠 수있는 방법에 대한 아이디어가 있습니까? 나는이 포럼에서 찾은 모든 것을 시도했지만 아무 것도 나를 위해 일하지 못했습니다.

public class PreciousTrackerPagerAdapter extends FragmentPagerAdapter { 

public static final int TAB_COUNT = 3; 
public static final int TAB_PRECIOUS_MOVES = 0; 
public static final int TAB_PRECIOUS_ITEMS = 1; 
public static final int TAB_PRECIOUS_CATEGORY = 2; 

private PreciousMovesFragment movesFragment; 
private PreciousItemsFragment itemsFragment; 
private PreciousCategoryFragment categoryFragment; 

public PreciousTrackerPagerAdapter(FragmentManager fm) { 
    super(fm); 
} 

@Override 
public Fragment getItem(int index) { 
    switch (index) { 
    case TAB_PRECIOUS_MOVES: 
     if (movesFragment == null) { 
      movesFragment = new PreciousMovesFragment(); 
     } 
     return movesFragment; 
    case TAB_PRECIOUS_ITEMS: 
     if (itemsFragment == null) { 
      itemsFragment = new PreciousItemsFragment(); 
     } 
     return itemsFragment; 
    case TAB_PRECIOUS_CATEGORY: 
     if (categoryFragment == null) { 
      categoryFragment = new PreciousCategoryFragment(); 
     } 
     return categoryFragment; 
    default: 
     return null; 
    } 
} 

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


} 

여기에서 문제를 일으킨 것으로 보이는 세 번째 탭에 추가 한 부분.

public class PreciousCategoryFragment extends Fragment { 

private List<PreciousCategory> categoryList; 
private View rootView; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState); 

    if (rootView == null) { 
     rootView = inflater.inflate(R.layout.category_list, null); 
    } 

    return rootView; 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    refreshList(); 
} 

private void refreshList() { 
    PreciousTrackerModel model = PreciousTrackerModel.getInstance(getActivity()); 
    categoryList = model.getCategoryList(); 
    ArrayAdapter<PreciousCategory> adapter = new ArrayAdapter<PreciousCategory>(getActivity(), android.R.layout.simple_list_item_1, categoryList); 
    ListView listView = (ListView) getActivity().findViewById(R.id.lstCategory); 
    listView.setAdapter(adapter); 
} 

}

을 어떻게 나는 주요 활동에 탭을 추가했다. 각 탭은 전체 콘텐츠 공간을 차지합니다.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_main); 
    model = PreciousTrackerModel.getInstance(this); 

    pagerAdapter = new PreciousTrackerPagerAdapter(getSupportFragmentManager()); 
    viewPager = (ViewPager) findViewById(R.id.pager); 
    viewPager.setAdapter(pagerAdapter); 
    viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
     public void onPageSelected(int position) { 
      // When swiping between pages, select the 
      // corresponding tab. 
      getActionBar().setSelectedNavigationItem(position); 
     } 
    }); 

    // enable tabs in action bar 
    final ActionBar actionBar = getActionBar(); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    // add tabs with listener 
    actionBar.addTab(actionBar.newTab().setText(R.string.moves).setTabListener(this)); 
    actionBar.addTab(actionBar.newTab().setText(R.string.items).setTabListener(this)); 
    actionBar.addTab(actionBar.newTab().setText(R.string.category).setTabListener(this)); 
} 
+0

이 코드가 해당 예외를 일으키는 것으로 의심됩니다. 그래도 내가 당신이라면 onCreateView 내부의 검사를 제거하기 시작합니다. 또한 refresh() 목록에서 Activity 내부의 ListView를 찾고 있습니다. 아마도 category_list.xml에 속해 있기 때문에 getActivity 대신 getView를 사용해야합니다. – Blackbelt

+0

당신도 그랬습니다. 당신의 도움을 주셔서 감사합니다. – Max

답변

2

저는 PreciousCategoryFragment :: onCreateView가 문제라고 생각합니다.

은 다음과 같아야합니다 : 당신은 왜 당신이 3 개 이상의 탭이있을 때 당신이 2 개의 탭이없는 경우는 일이 요구하는

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment_messages, null, false); 
} 
+0

그랬어! 아직도 2 개의 탭이 더 이상 문제가 아니었지만 더 이상 중요하지 않은 이유가 궁금합니다. – Max

1

.

두 개의 탭이있을 때 onCreateView와 onResume 작업을 시작할 때 초기화됩니다. 탭을 전환하면 더 이상 호출되지 않습니다.

탭을 사용하면 Android에서 인접 항목을로드하기 때문에! onCreateView, onResume 등에서 트리거합니다.하지만 탭이 2 개인 경우 항상 인접 해 있습니다.

이제 3 개의 탭이있는 경우 세 번째 탭이 즉시로드되지 않습니다. 전환 할 때로드되거나 인접한 두 번째로드 할 때로드됩니다!

안드로이드가 그렇기 때문에 그 이유는 간단합니다. 다음 글이 준비되지 않았다면, "스 와이프 효과"를 할 수 없습니다!

+0

자세한 설명 주셔서 감사합니다! – Max

관련 문제