2012-03-26 1 views
0

Я пытаюсь создать базовое приложение на основе ListFragment, которое переходит от одного ListFragment к другому, основываясь на пользовательском вводе.Переход от одного ListFragment к другому

Я использую по умолчанию ListView, что система Android раздувается для ListFragment, таким образом я не переезжаю onCreateView().

Чтобы установить поля вокруг ListFragment, я добавляю GlobalLayoutListener.

Теперь, когда я запускаю приложение, первый экран, содержащий фрагмент по умолчанию, отображается правильно, а поля заданы правильно.

Но как только я нажимаю изображение в основной раскладке, которая вызывает переход к второму фрагменту, имеющие один и те же onActivityCreated() метод и GlobalLayoutListener в качестве первого фрагмента, я получаю страшную Content View not created yet ошибку в методе OnGlobalLayout(), когда я попытайтесь получить доступ к ListView во втором фрагменте.

public void onActivityCreated(Bundle savedInstanceState){ 

    super.onActivityCreated(savedInstanceState); 



    setListAdapter(new ArrayAdapter<String>(getActivity(), 
        R.layout.listcommon, R.id.label, MAIN_TITLES)); 




    ListView lv = getListView(); 

    lv.setDivider(null); 
    lv.setDividerHeight(0); 
    lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
    lv.setItemChecked(0, true); 
    lv.setSelection(0); 



    ViewTreeObserver observer = getListView().getViewTreeObserver(); 

    observer.addOnGlobalLayoutListener(fragmentLayoutListener); 

} 

ViewTreeObserver.OnGlobalLayoutListener fragmentLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener(){ 

    public void onGlobalLayout() { 

    //Crashes here for second fragment 
    ListView listView = getListView(); 

    FrameLayout.LayoutParams params = (LayoutParams) listView.getLayoutParams(); 

    params.setMargins(10, 10, 10, 10); 

    } 

}; 

Вот основной макет: (фрагмент по умолчанию добавляется через FragmentTransaction.add() к первому FrameLayout)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:baselineAligned="false" 
android:background="#00000000"> 


<FrameLayout 
    android:id="@+id/TitlesContainer" 
    android:layout_width="match_parent" 
    android:layout_height="0px" 
    android:layout_weight="40" 
    android:layout_margin="10dip" 
    android:background="@drawable/titlesbg" 
    > 


</FrameLayout> 


<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="0px" 
    android:layout_weight="60" 
    android:background="#00000000" 
    > 

<ImageView 
    android:id="@+id/imageView_clickWheel" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:src="@drawable/clickImage" /> 

</FrameLayout> 


</LinearLayout> 

Любые мысли о том, что я должен делать, чтобы избежать запуска в эту ошибку?

Должен ли я переезжать onCreateView() в конце концов и раздувать пользовательский просмотр списка (но у меня нет такой необходимости)?

EDIT:

Вот как я добавляю фрагмент по умолчанию основной данный вид деятельности onCreate():

FragmentManager fragmentManager = getFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    TitlesFragment fragment = (TitlesFragment) fragmentManager.findFragmentByTag(MAIN_SCREEN_TAG); 
    if (fragment == null){ 
     fragment = TitlesFragment.newInstance(SCREEN_MAIN); 
     fragmentTransaction.add(R.id.TitlesContainer, fragment, MAIN_SCREEN_TAG); 

    } else {  
     fragmentTransaction.add(R.id.TitlesContainer, fragment); 
    } 

    fragmentTransaction.commit(); 

Чтобы выполнить переход, это то, что я делаю:

fragment = (TitlesFragment) fragmentManager.findFragmentByTag(SECOND_FRAGMENT_TAG); 
       if (fragment == null){ 

        fragment = TitlesFragment.newInstance(SECOND_FRAGMENT); 
        fragmentTransaction.replace(R.id.TitlesContainer, fragment, SECOND_FRAGMENT_TAG); 
       } else { 
        fragmentTransaction.replace(R.id.TitlesContainer, fragment); 
       } 
    fragmentTransaction.commit(); 
+0

Не могли бы вы показать код, в котором вы добавляете фрагменты в макет? Я думаю, что проблема может быть там. – Barak

+0

Я добавил код, показывающий добавление/замену фрагментов. Не могли бы вы объяснить, почему здесь недостаточно заполненного представления по умолчанию (android.R.layout.list_content, которого я предполагаю для ListFragment)? Также я немного озадачен, как getListView() не разбивает приложение в onActivityCreated()? – HungryTux

+0

В представлении по умолчанию должно быть хорошо, извините, если мой ответ смутил вас, поскольку он использовал пользовательский макет. См. Мой расширенный ответ ниже для дальнейшего объяснения вашего последнего вопроса. – Barak

ответ

0

Я избавился от OnGlobalLayoutListener. Вместо этого я установил атрибут layout_padding на первом FrameLayout, чтобы установить поля на фрагменте, который он охватывает.

0

С вами не упоминал об этом и не показывал ваш полный код, я угадываю здесь немного, но причиной может стать следующая проблема.

Мне кажется, вам нужно создать свое представление прежде, чем вы сможете получить доступ к его элементам. См. here и here.

Пример одного из моих проектов:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.leftlistfragment, container, false); 
    return v; 
} 

EDIT

Может быть, этот вопрос так, как вы создаете фрагмент (я не знаком с методом, который вы используете с теги). Возможно, это может сработать и для вас:

 titleFrag = new TitlesFragment(); 
     getFragmentManager().beginTransaction() 
       .replace(R.id.TitlesContainer, titleFrag, SECOND_FRAGMENT_TAG).commit();