0

I'm trying to build a basic ListFragment based application which transitions from one ListFragment to another, based upon user input.

I make use of the default ListView that the Android system inflates for a ListFragment, thus I dont over-ride onCreateView().

To set the margins around the ListFragment, I add a GlobalLayoutListener.

Now, when I launch the application, the first screen containing the default fragment shows up properly, with the margins set correctly.

But as soon as I click an image in the main layout, which invokes a transition to a second fragment having the same onActivityCreated() method and the GlobalLayoutListener as the first fragment, I get the dreaded Content View not created yet error in the OnGlobalLayout() method when I try to access the ListView in the second fragment.

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

    }

};

Here's the main layout: (Default fragment gets added through FragmentTransaction.add() to first 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>

Any thoughts on what I should be doing to avoid running into this error?

Should I be over-riding onCreateView() after all and inflate a custom list view (but I have no such need)?

EDIT:

Here's how I add the default fragment to the main activity's 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();

To perform the transition, this is what I do:

    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();
lucian.pantelimon
  • 3,673
  • 4
  • 29
  • 46
HungryTux
  • 355
  • 3
  • 14
  • Could you show the code where you are adding the fragments to the layout? I think the issue might be in there. – Barak Mar 26 '12 at 12:59
  • I added the code showing the addition/replacement of fragments. Could you explain why the default inflated view(android.R.layout.list_content I suppose for ListFragment) is not sufficient here? Also I'm a little puzzled, how getListView() doesn't crash the application in onActivityCreated()? – HungryTux Mar 26 '12 at 16:25
  • The default view should be fine, sorry if my answer confused you since it used a custom layout. See my ameneded answer below for further explanation on your last question. – Barak Mar 26 '12 at 16:45
  • I'm sorry but I don't see an edit to the answer below. :) – HungryTux Mar 26 '12 at 16:58
  • Ran out of time trying to research for a better answer for you. I'll try to get back to it tomorrow if you don't have it sorted by then. Inflate your list layout in the onCreateView though and I think you'll be fine. – Barak Mar 26 '12 at 17:02
  • I actually did give it a try after seeing your answer. I used the default view android.R.layout.list_content. Didn't help with the problem though :( – HungryTux Mar 26 '12 at 17:09

2 Answers2

0

Since you didn't mention it and haven't shown your full code, I'm guessing a bit here, but the following could be the cause of your issue.

I think you need to create your view first before you can access elements of it. See here and here.

An example from one of my projects:

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

EDIT

Maybe the issue is the way you are creating the fragment (I'm not familiar with the method you are using with tags). Maybe this might work for you too:

        titleFrag = new TitlesFragment();
        getFragmentManager().beginTransaction()
                .replace(R.id.TitlesContainer, titleFrag, SECOND_FRAGMENT_TAG).commit();
Community
  • 1
  • 1
Barak
  • 16,318
  • 9
  • 52
  • 84
0

I got rid of the OnGlobalLayoutListener. Instead I set 'layout_padding' attribute on the first FrameLayout to set the margins on the Fragment that it encloses.

HungryTux
  • 355
  • 3
  • 14