Reputation: 452
How can I add a custom button to material date range picker?
I'm trying to get view of the dialog so that I can add button programmatically, but I can't get any view from the picker.
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
dateRangeTV.setOnClickListener(v -> {
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
View root = materialDatePicker.requireView();
});
But I'm getting error saying.
java.lang.IllegalStateException: Fragment MaterialDatePicker{e52ecfc} (40593b4f-a55a-4d6c-aa3b-2b778e721149 tag=DATE_PICKER) did not return a View from onCreateView() or this was called before onCreateView().
Upvotes: 2
Views: 2596
Reputation: 9113
This error occurred because the materialDatePicker.show()
is an asynchronous call and the MaterialDatePicker
(DialogFragment) was not created yet to be able to access its root View. To avoid this error you have to listen for the DialogFragment Lifecycle
using the materialDatePicker.getLifecycle()
by adding a DefaultLifecycleObserver
and use the override method void onStart(@NonNull LifecycleOwner owner)
to access the MaterialDatePicker
root View from there.
Change your code to be like the below:
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
materialDatePicker.getLifecycle().addObserver(new DefaultLifecycleObserver()
{
@Override
public void onCreate(@NonNull LifecycleOwner owner) {}
@Override
public void onStart(@NonNull LifecycleOwner owner) {
//in onStart of DialogFragment the View has been created so you can access the materialDatePicker.requireView()
View root = materialDatePicker.requireView();
//from root find the View you are interested to add your custom button
}
@Override
public void onResume(@NonNull LifecycleOwner owner) {}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
//remove Lifecycle Observer
materialDatePicker.getLifecycle().removeObserver(this);
}
});
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
Upvotes: 2
Reputation: 3683
In this example I created a class MainActivity.java
and it's layout that open a custom Dialog from a Button
like this:
The MainActivity.java
:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Button openDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openDialog = findViewById(R.id.open_dialog);
openDialog.setOnClickListener(v -> {
Log.d(TAG, "onClick: opening dialog.");
MyCustomDialog dialog = new MyCustomDialog();
dialog.show(getSupportFragmentManager(), "MyCustomDialog");
});
}
}
Layout
with the Button
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="MainActivity">
<Button
android:id="@+id/open_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="20sp"
android:text="open dialog" />
</RelativeLayout>
And the MyCustomDialog.java
class extends the DialogFragment
to have a custom View to store the DatePicker
and also other Widgets
in it. (e.g. TextView
):
public class MyCustomDialog extends DialogFragment {
private static final String TAG = "MyCustomDialog";
private TextView mActionOk, mActionCancel;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
mActionCancel = view.findViewById(R.id.action_cancel);
mActionOk = view.findViewById(R.id.action_ok);
mActionCancel.setOnClickListener(v -> {
Log.d(TAG, "onClick: closing dialog");
getDialog().dismiss();
});
mActionOk.setOnClickListener(v -> {
Log.d(TAG, "onClick: capturing input");
getDialog().dismiss();
});
return view;
}
}
Last but not least the XML
file dialog_my_custom.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="550dp"
android:padding="10dp">
<TextView
android:id="@+id/heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="This is your custom View with DatePicker"
android:textAlignment="center"
android:textColor="#000"
android:textSize="18sp" />
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:layout_centerHorizontal="true" />
<RelativeLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/date_picker">
<TextView
android:id="@+id/action_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="OK"
android:textColor="#33bbff"
android:textSize="18sp" />
<TextView
android:id="@+id/action_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="CANCEL"
android:textColor="#33bbff"
android:textSize="18sp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
Don't forget to add the dependency
of the support library:
implementation "com.android.support:appcompat-v7:$supportLibVersion"
RESULT:
Upvotes: 0