Properly creating a fragment in a PopupWindow

Mark Rausch picture Mark Rausch · Nov 8, 2011 · Viewed 14.7k times · Source

I’m new to Android development and am confused about how to accomplish what I’m trying to do. I’ve done some reading and learning about fragments so I can share layout and code between various screen size designs. I’ve got a couple of fragments created and have used them successfully. But I’ve got a situation where I want to show a fragment in a normal activity on the phone, but want to show the fragment in a PopupWindow (or something similar if there’s a better choice) on a tablet.

I’ve managed to figure out how to inflate the fragment and display it in a PopupWindow when a button is clicked. My code looks like this:

public void onClick(View v) {
    LayoutInflater inflater = (LayoutInflater) BrowsingActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View popupLayout = inflater.inflate(R.layout.serverconnection_fragment, null, false);
    connectionListPopup = new PopupWindow(popupLayout, 300, 470, true);
    connectionListPopup.showAtLocation(BrowsingActivity.this.findViewById(R.id.connectionListImage), Gravity.CENTER, 0, 0);
}

The popup appears and contains the UI described in serverconnection_fragment.xml. The problem is that by creating it this way, the Fragment class ServerConnectionFragment.java is never instantiated so there are no items in the list in my UI, no listeners on buttons, and so on. It seems like there should be a way for me to instantiate the java class, have it inflate the fragment normally and attach event listeners, then pass the view created there into the PopupWindow constructor, but I can’t figure out how. Can anyone help me out?

FYI, I’m building this for Android 2.1 using the Android-support-v4.jar file for the Fragment classes.

Answer

antonyt picture antonyt · Mar 11, 2012

Inflating the layout directly will not cause it it to instantiate the fragment; Android would just consider it a mere coincidence that both the fragment and the activity are trying to refer to the same layout file.

Ordinarily, you would use FragmentManager.add(int,Fragment) to add a fragment to a layout. However, the container id that you specify has to be part of the layout of the current Activity, and this is not the case with a PopupWindow. Instead, you would have to add the fragment to the fragment manager without specifying a container, and then sometime later in the fragment (e.g. onStart()) you can show a PopupWindow. This is precisely how DialogFragment works, and since there is already lots of support for it, I would suggest you switch to using a DialogFragment instead.

With your Fragment code, simply extend DialogFragment instead of Fragment, and use DialogFragment.show(FragmentManager,String) to display it. You can get rid of the default border by calling setStyle(DialogFragment.STYLE_NO_FRAME, getTheme()) in the onCreate method. You can still add this Fragment to a layout (as you say, on a phone you do not want it to be shown as a popup) and it will work as how you expect.