Explain the basic usage of DialogFragment in Android application in detail

  • 2021-07-10 20:43:27
  • OfStack

Basic Usage of DialogFragment
1. Create an DialogFragment


public class DialogA extends DialogFragment implements DialogInterface.OnClickListener {

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  builder.setMessage(R.string.dialoga_title)
    .setPositiveButton(R.string.ok, this)
    .setNegativeButton(R.string.cancel, this);

  return builder.create();
 } 

 @Override
 public void onClick(DialogInterface dialog, int id) {
  switch(id) {
   case AlertDialog.BUTTON_NEGATIVE:
    Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
    break;
   case AlertDialog.BUTTON_POSITIVE:
    Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
    break;
   default:
    break;
  } 
 } 
}

Description: Customize an DialogFragment and override its onCreateDialog () method.
2. Call the DialogFragment
The following is the call to the DialogFragment dialog box in FragmentActivity.


public class DialogTest extends FragmentActivity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  showDialog();
 }

 private void showDialog() {
  FragmentManager fm = getSupportFragmentManager();
  DialogA dialoga = new DialogA();
  dialoga.show(fm, "fragmenta");
 }
}

Custom DialogFragment layout
Here's how to customize the layout of DialogFragment
Click to view: Complete code for customizing DialogFragment layout
1. Set up the layout file


<?xml version="1.0" encoding="utf-8"?>
<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" >

 <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/dialoga_intro" />

 <ImageView
  android:id="@+id/image"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/ic_action_video" />

</LinearLayout>

2. Use the layout


public class DialogA extends DialogFragment implements DialogInterface.OnClickListener {

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  LayoutInflater inflater = getActivity().getLayoutInflater();
  builder.setView(inflater.inflate(R.layout.dialoga, null))
    .setMessage(R.string.dialoga_title)
    .setPositiveButton(R.string.ok, this)
    .setNegativeButton(R.string.cancel, this);

  return builder.create();
 }

 @Override
 public void onClick(DialogInterface dialog, int id) {
  switch(id) {
   case AlertDialog.BUTTON_NEGATIVE:
    Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
    break;
   case AlertDialog.BUTTON_POSITIVE:
    Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
    break;
   default:
    break;
  }
 }
}

Interaction between DialogFragment and Activity
Here's how to customize DialogFragment and Activity interactions
Click to view: The complete code of DialogFragment and Activity interaction
1. Define communication interfaces
The communication interface between them is defined in DialogFragment.


public interface NoticeDialogListener {
 public void onDialogPositiveClick(DialogFragment dialog);
 public void onDialogNegativeClick(DialogFragment dialog);
} 

// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;

// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
@Override
public void onAttach(Activity activity) {
 super.onAttach(activity);
 // Verify that the host activity implements the callback interface
 try {
  // Instantiate the NoticeDialogListener so we can send events to the host
  mListener = (NoticeDialogListener) activity;
 } catch (ClassCastException e) {
  // The activity doesn't implement the interface, throw exception
  throw new ClassCastException(activity.toString()
    + " must implement NoticeDialogListener");
 } 
} 

2. Call the interface in DialogFragment


@Override
public void onClick(DialogInterface dialog, int id) {
 switch(id) {
  case AlertDialog.BUTTON_POSITIVE:
   //Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
   mListener.onDialogPositiveClick(DialogA.this);
   break;
  case AlertDialog.BUTTON_NEGATIVE:
   //Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
   mListener.onDialogNegativeClick(DialogA.this);
   break;
  default:
   break;
 } 
}

3. Implement the interface in Activity


public class DialogTest extends FragmentActivity 
 implements DialogA.NoticeDialogListener {

 ...

 @Override
 public void onDialogPositiveClick(DialogFragment dialog) {
  Toast.makeText(this, "Positive Callback", Toast.LENGTH_SHORT).show();
 }
 @Override
 public void onDialogNegativeClick(DialogFragment dialog) {
  Toast.makeText(this, "Negative Callback", Toast.LENGTH_SHORT).show();
 }
}

Comparison between Dialog and DialogFragment
From a coding perspective, Dialog is easier to use, but Google is recommended to use DialogFragment as much as possible (for Android versions below 3.0, you can use DialogFragment and FragmentActivity provided in support package together). Today, I tried to create dialog boxes in these two ways, and found that DialogFragment really has a very good feature (when Activity needs to be recreated due to the change of mobile phone configuration, such as rotating screen, the dialog box based on DialogFragment will be automatically rebuilt by FragmentManager, but the dialog box based on Dialog does not have such ability).

Here are two examples of code:

They all use one interface: (dialog. xml)


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >
 
 <ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/ic_launcher" />
 
</LinearLayout>

1. Dialog box based on Dialog


public class MainActivity extends Activity {
 private Button clk;
 private Dialog dialog;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   
  clk = (Button) findViewById(R.id.clk);
  dialog = new Dialog(this);
  dialog.setContentView(R.layout.dialog);
  clk.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    dialog.show();
   }
  });
 }
}

When we click the button, a dialog box will pop up (the content is android logo). When we rotate the screen, Activity will be recreated, and the whole interface of Activity will be fine, but the dialog box will disappear.
In addition, there is actually another problem, that is, you will see exception information in logcat: Android... leaked.. window, because Android requires all Dialog to be turned off before Activity ends. After we rotate the screen, Activity will be rebuilt, and the above code logic does not consider the state of the dialog box and whether it is closed or not.

So the above code is modified to:


public class MainActivity extends Activity {
 private Button clk;
 private Dialog dialog;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   
  clk = (Button) findViewById(R.id.clk);
  dialog = new Dialog(this);
  dialog.setContentView(R.layout.dialog);
  clk.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    dialog.show();
   }
  });
 
  // Status of the User Recovery Dialog Box 
  if(savedInstanceState != null && savedInstanceState.getBoolean("dialog_show"))
   clk.performClick();
 }
 
 /**
  *  Used to save the state of the dialog box for recovery 
  */
 @Override
 protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if(dialog != null && dialog.isShowing())
   outState.putBoolean("dialog_show", true);
  else
   outState.putBoolean("dialog_show", false);
 }
 
 /**
  *  In Activity Before destroying, make sure the dialog box is closed 
  */
 @Override
 protected void onDestroy() {
  super.onDestroy();
  if(dialog != null && dialog.isShowing())
   dialog.dismiss();
 }
}


2. Dialog Box Based on DialogFragment

Using the same interface layout as the above dialog box, only one simple dialog box is presented here, so only the onCreateView method is overridden


public class DialogTest extends FragmentActivity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  showDialog();
 }

 private void showDialog() {
  FragmentManager fm = getSupportFragmentManager();
  DialogA dialoga = new DialogA();
  dialoga.show(fm, "fragmenta");
 }
}

0


These two pieces of code can achieve the same function in the first way. We don't care about the reconstruction of the dialog box here, and whether the dialog box was closed before Activity was destroyed. This one is managed by FragmentManager.
In fact, DialogFragment also has the advantage of fragment, that is, it can implement fallback within one Activity (because FragmentManager manages one fallback stack)


Related articles: