Issue
I know there are similar questions but I couldn't find an answer to solve my problem.
I have a DialogUpdateEmail which I want to be opened from ProfileFragment. In the dialog I want to enter my new email and send it to my ProfileFragment in order to change it also in the database.
ProfileFragment.java :
import androidx.fragment.app.Fragment;
public class ProfileFragment extends Fragment implements SendInputEmail {
public static final int PROFILE_FRAGMENT = 1;
private static final String TAG = "ProfileFragment";
private TextView TVHello, TVUsernameMessage, TVusernameinfo, TVemailinfo, TVbirthdate;
public void sendInput(String input) {
Log.d(TAG, "sendInput: found incoming input: " + input);
TVemailinfo.setText(input);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_profile, container, false);
Button Bsignout = (Button) v.findViewById(R.id.signoutbutton);
Button Beditusername = (Button) v.findViewById(R.id.editusernamebutton);
Button Beditemail = (Button) v.findViewById(R.id.editemailbutton);
Beditemail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: opening email dialog");
DialogUpdateEmail dialog = new DialogUpdateEmail();
dialog.setTargetFragment(ProfileFragment.this,PROFILE_FRAGMENT);
dialog.show(getActivity().getFragmentManager(), "DialogUpdateEmail");
}
});
return v;
}
DialogUpdateEmail.java :
public class DialogUpdateEmail extends DialogFragment implements SendInputEmail {
private static final String TAG = "DialogUpdateEmail";
SendInputEmail mHost = (SendInputEmail)getTargetFragment();
public View onCreateView(final LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.popup, container, false);
EditText UpdateEmail = (EditText) view.findViewById(R.id.emailinfoupdate);
Button Beditemail = (Button) view.findViewById(R.id.updatesavebutton);
Button Bcancelemail = (Button) view.findViewById(R.id.updatecancelbutton);
Beditemail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: capturing input.");
String input = UpdateEmail.getText().toString();
Log.d(TAG, "input : "+input);
mHost.sendInput(input);
getDialog().dismiss();
}
});
return view ;
}
public void onAttach(Context context) {
super.onAttach(context);
try{
mHost = (SendInputEmail) getTargetFragment();
}catch (ClassCastException e){
Log.e(TAG, "onAttach: ClassCastException : " + e.getMessage() );
}
}
@Override
public void sendInput(String input) {
}
}
SendInputEmail Interface :
public interface SendInputEmail {
void sendInput(String input);
}
My problem is that I have an error when I try to use setTargetFragment in ProfileFragment. It says that Profile Fragment is not a Fragment, I really don't know why.
Solution
From doc in here :
public class DialogUpdateEmail extends DialogFragment {
private DialogEditListener listener;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = requireActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View view = inflater.inflate(R.layout.popup, null);
builder.setView(view);
EditText UpdateEmail = (EditText) view.findViewById(R.id.emailinfoupdate);
Button Beditemail = (Button) view.findViewById(R.id.updatesavebutton);
Button Bcancelemail = (Button) view.findViewById(R.id.updatecancelbutton);
Beditemail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onDialogEditClick(UpdateEmail.getText().toString());
DialogUpdateEmail.this.getDialog().dismiss();
}
}
});
Bcancelemail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogUpdateEmail.this.getDialog().cancel();
}
});
return builder.create();
}
public interface DialogEditListener {
void onDialogEditClick(String email);
}
public void setListener(DialogEditListener listener) {
this.listener = listener;
}
}
We send the email from the dialog to the fragment using the observer/listener pattern.
And in your ProfileFragment
just implement DialogEditListener
and subscribe it to listen for click button in the dialog like so:
public class ProfileFragment extends Fragment
implements SendInputEmail, DialogUpdateEmail.DialogEditListener {
public static final int PROFILE_FRAGMENT = 1;
private static final String TAG = "ProfileFragment";
private TextView TVHello, TVUsernameMessage, TVusernameinfo, TVemailinfo, TVbirthdate;
public void sendInput(String input) {
Log.d(TAG, "sendInput: found incoming input: " + input);
TVemailinfo.setText(input);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_profile, container, false);
Button Bsignout = (Button) v.findViewById(R.id.signoutbutton);
Button Beditusername = (Button) v.findViewById(R.id.editusernamebutton);
Button Beditemail = (Button) v.findViewById(R.id.editemailbutton);
Beditemail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: opening email dialog");
//show your dialog
DialogUpdateEmail dialogUpdateEmail = new DialogUpdateEmail();
dialogUpdateEmail.setListener(ProfileFragment.this);
dialogUpdateEmail.show(getActivity().getSupportFragmentManager(), "DialogUpdateEmail");
}
});
return v;
}
@Override
public void onDialogEditClick(String email) {
//use your email here
Toast.makeText(getContext(), "My email: " + email, Toast.LENGTH_SHORT).show();
}
}
Answered By - Abdo21
Answer Checked By - Terry (JavaFixing Volunteer)