简体   繁体   中英

Android's AlertDialog in fragment

I have an app that uses tabbed activity, with 3 tabs, each with a separate fragment and layout. Tab3 has some user-profile settings, like a name for example. Name is displayed inside a cardview, so I made that cardview clickable, and onClick it would open an alertDialog with an edit text to enter the name. to build this dialog I found 2 methods.

First:- (this is run once the cardview is clicked(On clicklistener)) and its working very well and I have no issues with it but it just doesn't feel like a best-practice

AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

                alert.setTitle("Enter your Username");

                LayoutInflater inflater = getActivity().getLayoutInflater();
                View view1 = inflater.inflate(R.layout.editname_layout, null);
                alert.setView(view1);
                final EditText input = view1.findViewById(R.id.editname);
                alert.setPositiveButton("Save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {

                        textView.setText(input.getText().toString());
                    }
                });

                alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // Canceled.
                    }
                });

                alert.show();

Second:- is that I build a separate DialogFragment with an interface to send data back to fragment this one feels like a best practice but i have faced many issues with it, such as.. when data is sent back to my fragment, I can't use the method "textView.setText" on the received data as I receive it outside the onCreateView method and thus textView always returns null.

public class Dialog extends AppCompatDialogFragment {
    
    private Context context;
    public DialogListener listener;

    public Dialog(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public android.app.Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        
            LayoutInflater inflater = getActivity().getLayoutInflater();
            View view = inflater.inflate(R.layout.name_layout, null);
            final EditText name = (EditText) view.findViewById(R.id.editname);
            builder.setView(view)
                    .setTitle("Username")
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {

                        }
                    })
                    .setPositiveButton("Save", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            String text = name.getText().toString();
                            listener.data(text);
                            Toast.makeText(getActivity(), "Saved", Toast.LENGTH_SHORT).show();
                        }
                    });
        
      
         return builder.create();
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        try {
            Fragment fragment = new Tab3();
            listener = (DialogListener) fragment;
        }
        catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement d.l");
        }
    }



    public interface DialogListener {
        void data(String name);
    }
}

So what I'm thinking is that I should go with the first method as it's easier, and it's easier to extract text from it but still not sure if it would be a good practice.

thanks in advance!

It's not a question of best practice, it's just how you want to design your App.

  • The first solution: You can directly interact with your UI. eg: Set the new value in textView . But if you write a lot of dialogs, think about to generify the logic (the second solution).
  • The second solution: If you want just a generic Dialog , you need the use-case for it = multiple calls for dialogs and don't forget: if you instantiate the Dialog class you need to give him the textView if you want to change it in the UI

Prefer second solution:

  1. You can have your custom UI elements.
  2. You have access to lifecycle changes ( onResume , onCreate ,etc.).
  3. It keeps showing even when orientation is changed (the first solution doesn't).

And for sending data to previous fragment you can create listener to fragment.

interface MyFragmentListener {
    fun onSendBackData(data: Any)
}
class MyFragment:Fragment {
    private var listener: MyFragmentListener? = null
    
    override fun onAttach(context: Context) {
        super.onAttach(context)
        listener = when {
            context is MyFragmentListener -> context
            parentFragment is MyFragmentListener -> parentFragment as MyFragmentListener
            else -> error("You should implement MyFragmentListener")

        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        button.setOnClickListener {
            listener?.onSendBackData("Data")
        }
    }
}
class Activity : Activity(), MyFragmentListener {

   override fun onSendBackData(data:Any) {
      textView.text = data.toString()
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM