What I am trying to achieve is to have a fragment that on tablet it shows as a DialogFragment
, while on smartphone it would be shown as a regular fragment. I am
This issue can be easily fixed if instead of trying to make a Fragment
look like a DialogFragment
I would look from the opposite angle: make a DialogFragment
look like a Fragment
- after all, a DialogFragment
is a Fragment
!
The key of this fix is to call or not DialogFragment.setShowsDialog();
So changing the DetailedFragment
to:
public class DetailedFragment extends DialogFragment {
private static final String ARG_SHOW_AS_DIALOG = "DetailedFragment.ARG_SHOW_AS_DIALOG";
public static DetailedFragment newInstance(boolean showAsDialog) {
DetailedFragment fragment = new DetailedFragment();
Bundle args = new Bundle();
args.putBoolean(ARG_SHOW_AS_DIALOG, showAsDialog);
fragment.setArguments(args);
return fragment;
}
public static DetailedFragment newInstance() {
return newInstance(true);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
setShowsDialog(args.getBoolean(ARG_SHOW_AS_DIALOG, true));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.detailed_fragment, container, false);
}
}
its layout remains as it was, DetailedActivity
changes to:
public class DetailedActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detailed_activity);
if (savedInstanceState == null) {
DetailedFragment fragment = DetailedFragment.newInstance(false);
getSupportFragmentManager().beginTransaction().add(R.id.root_layout_details, fragment, "Some_tag").commit();
}
}
}
its layout as well:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout_details"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and the caller activity does only:
private void decideToNext() {
String device = getString(R.string.device);
if ("normal".equalsIgnoreCase(device)) {
Intent intent = new Intent(this, DetailedActivity.class);
startActivity(intent);
} else if ("large".equalsIgnoreCase(device)) {
DetailedFragment fragment = DetailedFragment.newInstance();
fragment.show(getSupportFragmentManager(), "Tablet_specific");
}
}
To make a DialogFragment
show as a regular Fragment
, call add()
or replace()
using a resource ID for the fragment container, e.g
beginTransaction().add(R.id.fragment_container, fragment)
But to make the DialogFragment display as a dialog, call add(fragment, "Fragment Tag")
. Behind the scenes this results in a call to add(resId, fragment)
, setting the resource ID for the fragment container to 0, which causes the DialogFragment
to set its showAsDialog
option to true.
As a consequence you can use a dialog fragment as a dialog or a regular fragment - depending on your needs - without needing to create any special logic to do it.
OK, I have been there and done that. To make a DialogFragment
you need a layout defined in XML. Say, for this you have LinearLayout
as root. In this LinearLayout
you can add a fragment class="...."
and when you display your DialogFragment
, it will be the same Fragment
you displayed side by side on the tablet now displayed in a DialogFragment
.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<fragment class="com.example.tqafragments.FeedFragment" android:id="@+id/feedFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"/>
</LinearLayout>
Like so. And inflate this in your DialogFragment