Show dialog from fragment?

前端 未结 7 758
再見小時候
再見小時候 2020-11-30 19:17

I have some fragments that need to show a regular dialog. On these dialogs the user can choose a yes/no answer, and then the fragment should behave accordingly.

Now,

相关标签:
7条回答
  • 2020-11-30 19:57

    I must cautiously doubt the previously accepted answer that using a DialogFragment is the best option. The intended (primary) purpose of the DialogFragment seems to be to display fragments that are dialogs themselves, not to display fragments that have dialogs to display.

    I believe that using the fragment's activity to mediate between the dialog and the fragment is the preferable option.

    0 讨论(0)
  • 2020-11-30 19:59

    For me, it was the following-

    MyFragment:

    public class MyFragment extends Fragment implements MyDialog.Callback
    {
        ShowDialog activity_showDialog;
    
        @Override
        public void onAttach(Activity activity)
        {
            super.onAttach(activity);
            try
            {
                activity_showDialog = (ShowDialog)activity;
            }
            catch(ClassCastException e)
            {
                Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
                throw e;
            }
        }
    
        @Override
        public void onClick(View view) 
        {
            ...
            MyDialog dialog = new MyDialog();
            dialog.setTargetFragment(this, 1); //request code
            activity_showDialog.showDialog(dialog);
            ...
        }
    
        @Override
        public void accept()
        {
            //accept
        }
    
        @Override
        public void decline()
        {
            //decline
        }
    
        @Override
        public void cancel()
        {
            //cancel
        }
    
    }
    

    MyDialog:

    public class MyDialog extends DialogFragment implements View.OnClickListener
    {
        private EditText mEditText;
        private Button acceptButton;
        private Button rejectButton;
        private Button cancelButton;
    
        public static interface Callback
        {
            public void accept();
            public void decline();
            public void cancel();
        }
    
        public MyDialog()
        {
            // Empty constructor required for DialogFragment
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View view = inflater.inflate(R.layout.dialogfragment, container);
            acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
            rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
            cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
            acceptButton.setOnClickListener(this);
            rejectButton.setOnClickListener(this);
            cancelButton.setOnClickListener(this);
            getDialog().setTitle(R.string.dialog_title);
            return view;
        }
    
        @Override
        public void onClick(View v)
        {
            Callback callback = null;
            try
            {
                callback = (Callback) getTargetFragment();
            }
            catch (ClassCastException e)
            {
                Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
                throw e;
            }
    
            if (callback != null)
            {
                if (v == acceptButton)
                {   
                    callback.accept();
                    this.dismiss();
                }
                else if (v == rejectButton)
                {
                    callback.decline();
                    this.dismiss();
                }
                else if (v == cancelButton)
                {
                    callback.cancel();
                    this.dismiss();
                }
            }
        }
    }
    

    Activity:

    public class MyActivity extends ActionBarActivity implements ShowDialog
    {
        ..
    
        @Override
        public void showDialog(DialogFragment dialogFragment)
        {
            FragmentManager fragmentManager = getSupportFragmentManager();
            dialogFragment.show(fragmentManager, "dialog");
        }
    }
    

    DialogFragment layout:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/dialogfragment_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp"
            android:text="@string/example"/>
    
        <Button
            android:id="@+id/dialogfragment_acceptbtn"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/dialogfragment_textview"
            android:text="@string/accept"
            />
    
        <Button
            android:id="@+id/dialogfragment_rejectbtn"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
            android:layout_below="@+id/dialogfragment_acceptbtn"
            android:text="@string/decline" />
    
         <Button
            android:id="@+id/dialogfragment_cancelbtn"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="20dp"
            android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
            android:layout_below="@+id/dialogfragment_rejectbtn"
            android:text="@string/cancel" />
    
         <Button
            android:id="@+id/dialogfragment_heightfixhiddenbtn"
            android:layout_width="200dp"
            android:layout_height="20dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="20dp"
            android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
            android:layout_below="@+id/dialogfragment_cancelbtn"
            android:background="@android:color/transparent"
            android:enabled="false"
            android:text=" " />
    </RelativeLayout>
    

    As the name dialogfragment_heightfixhiddenbtn shows, I just couldn't figure out a way to fix that the bottom button's height was cut in half despite saying wrap_content, so I added a hidden button to be "cut" in half instead. Sorry for the hack.

    0 讨论(0)
  • 2020-11-30 20:04
        public static void OpenDialog (Activity activity, DialogFragment fragment){
    
        final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
    
        fragment.show(fm, "tag");
    }
    
    0 讨论(0)
  • 2020-11-30 20:06

    You should use a DialogFragment instead.

    0 讨论(0)
  • 2020-11-30 20:10

    Here is a full example of a yes/no DialogFragment:

    The class:

    public class SomeDialog extends DialogFragment {
    
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return new AlertDialog.Builder(getActivity())
                .setTitle("Title")
                .setMessage("Sure you wanna do this!")
                .setNegativeButton(android.R.string.no, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // do nothing (will close dialog)
                    }
                })
                .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // do something
                    }
                })
                .create();
        }
    }
    

    To start dialog:

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            // Create and show the dialog.
            SomeDialog newFragment = new SomeDialog ();
            newFragment.show(ft, "dialog");
    

    You could also let the class implement onClickListener and use that instead of embedded listeners.

    Callback to Activity

    If you want to implement callback this is how it is done In your activity:

    YourActivity extends Activity implements OnFragmentClickListener
    

    and

    @Override
    public void onFragmentClick(int action, Object object) {
        switch(action) {
            case SOME_ACTION:
            //Do your action here
            break;
        }
    }
    

    The callback class:

    public interface OnFragmentClickListener {
        public void onFragmentClick(int action, Object object);
    }
    

    Then to perform a callback from a fragment you need to make sure the listener is attached like this:

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentClickListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement listeners!");
        }
    }
    

    And a callback is performed like this:

    mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.
    
    0 讨论(0)
  • 2020-11-30 20:21
     public void showAlert(){
    
    
         AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
         LayoutInflater inflater = getActivity().getLayoutInflater();
         View alertDialogView = inflater.inflate(R.layout.test_dialog, null);
         alertDialog.setView(alertDialogView);
    
         TextView textDialog = (TextView) alertDialogView.findViewById(R.id.text_testDialogMsg);
         textDialog.setText(questionMissing);
    
         alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int which) {
                 dialog.cancel();
             }
         });
         alertDialog.show();
    
    }
    

    where .test_dialog is of xml custom

    0 讨论(0)
提交回复
热议问题