I have a form in a dialog fragment. One of the fields open a custom date picker dialog, which returns the selected date via setFragmentResult()
. I want to set this date as the value of the given text field.
When I create the dialog fragment, which contains the form, I can change the value of the given field using getEditText().setText()
, but the same thing does not work in the FragmentResultListener
.
I have tried to use both view binding and findViewById()
.
DateDialog
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
binding = DialogDateBinding.inflate(getLayoutInflater());
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(getContext());
dialogBuilder.setView(binding.getRoot());
dialogBuilder.setPositiveButton("Select", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Bundle result = new Bundle();
result.putString("bundleKey", "DATE_STRING"); // it's just temporary
getParentFragmentManager().setFragmentResult("request_key", result);
}
});
return dialogBuilder.create();
}
DialogFragment
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
binding = DialogPatientBinding.inflate(getLayoutInflater());
binding.date.getEditText().setText("SOMETHING"); // it works!
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(getContext());
dialogBuilder.setView(binding.getRoot());
binding.date.getEditText().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DateDialog dateDialog = new DateDialog();
dateDialog.show(getParentFragmentManager(), "date_dialog");
}
});
getParentFragmentManager().setFragmentResultListener("request_key", getActivity(), new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
String value = result.getString("bundle_key");
Log.d("TEST", result.getString(value)); //logs "DATE_STRING"
binding.date.getEditText().setText(value); // does not work
((TextInputLayout)getView().findViewById(R.id.date)).getEditText().setText(value); // does not work
}
});
return dialogBuilder.create();
}
CodePudding user response:
You can add an EditText inside the TextInputLayout and give it an id like the below:
//Your XML layout file:
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:id="@ id/date"
android:layout_width="270dp"
android:layout_height="48dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="@ id/editTextId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
and in your listener:
binding.editTextId.setText(value);
CodePudding user response:
The problem was that I used view binding in both onCrateView
and onCreateDialog
.
private DialogBinding binding;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// instead of this
binding = DialogBinding.inflate(inflater, container, false);
View view = binding.getRoot();
return view;
// do this
View view = inflater.inflate(R.layout.dialog_layout, container, false);
return view;
}
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
binding = DialogBinding.inflate(getLayoutInflater()); // do it here
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(getContext());
dialogBuilder.setView(binding.getRoot());
return dialogBuilder.create();
}
In the fragment lifecycle onCreateDialog
runs first, then onCreateView
. I guess the binding in onCreateView
created a new object, and I lost the reference to the original one.
Possibly an amateur mistake. But if anyone faces the same problem, just don't do it in both methods! Just use inflater.inflate()
in onCreateView
!