javaandroidandroid-studiodatepickerdialog

setTitle for DatePickerDialog is not working


I've been trying to make a DatePickerDialog and TimePickerDialog to show a title on top but nothing worked so far. I tried using setTitle before showing the date/time pickers and also tried setCustomTitle. Here is my Dialog class that I use to show date picker and time picker which is based on this answer.

DateTimePickerDialog.java

import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Calendar;


public class DateTimePicker extends DatePickerDialog {

    @NonNull
    private Calendar calendar = Calendar.getInstance();
    @Nullable
    private DatePickerDialog datePickerDialog;
    @Nullable
    private TimePickerDialog timePickerDialog;

    private String pickerTitle;
    private TextView customTitle;


    public DateTimePicker(Context context, OnDateSetListener dateListener, int year, int monthOfYear, int dayOfMonth) {
        super(context, dateListener, year, monthOfYear, dayOfMonth);
    }

    public setPickerTitle(String title, TextView view){
        this.pickerTitle = title;
        this.customTitle = view;
    }

    public void showDialog(@NonNull Context context, long time) {
        calendar.setTimeInMillis(time);

        closeDialogs();
        showDatePicker(context);
    }

    private void closeDialogs() {
        if (datePickerDialog != null) {
            datePickerDialog.dismiss();
            datePickerDialog = null;
        }
        if (timePickerDialog != null) {
            timePickerDialog.dismiss();
            timePickerDialog = null;
        }
    }

    private DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            timePicker(view.getContext());
            dateListener.onDateSet(view, year, month, dayOfMonth);

        }
    };

    private TimePickerDialog.OnTimeSetListener timeSetListener = new TimePickerDialog.OnTimeSetListener() {

        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
            calendar.set(Calendar.MINUTE, minute);
            timeListener.onTimeSet(view, hourOfDay, minute);
        }

    };

    private void showDatePicker(@NonNull Context context) {
        datePickerDialog = new DatePickerDialog(context,
                dateSetListener,
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH));
        
        datePickerDialog.setTitle(this.pickerTitle);        
        datePickerDialog.show();
    }

    private void timePicker(@NonNull Context context) {
        timePickerDialog = new TimePickerDialog(context,
                timeSetListener,
                calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE),
                true);

        timePickerDialog.setCustomTitle(this.customTitle);
        timePickerDialog.show();
    }

}

And this is how I'm using it in my Fragment:

    private void onDateTimeClick(){

    DateTimePicker dateTimePicker = new DateTimePicker(getContext(), onDateSetListener, Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH);

    TextView view = new TextView(getContext());
    view.setText("Custom title");
    dateTimePicker.setPickerTitle("My title", view);

    dateTimePicker.showDialog(Objects.requireNonNull(getContext()), Calendar.getInstance().getTimeInMillis());
}

I tried overriding setTitle method as mentioned here, used setTitle and setCustomTitle individually and combined, and I went through all I could find on SO but nothing worked so far. When I debugged my code, I noticed that when setTitle is called, the cursor jumps to setTitle on AlertDialog.java then to the below method of PhoneWindow.java where mViewTitle is null. I think this may be it but couldn't figure out how to fix it.

  public void setTitle(CharSequence title, boolean updateAccessibilityTitle) {
    if (mTitleView != null) {
        mTitleView.setText(title);
    } else if (mDecorContentParent != null) {
        mDecorContentParent.setWindowTitle(title);
    }
    mTitle = title;
    if (updateAccessibilityTitle) {
        WindowManager.LayoutParams params = getAttributes();
        if (!TextUtils.equals(title, params.accessibilityTitle)) {
            params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
            if (mDecor != null) {
                // ViewRootImpl will make sure the change propagates to WindowManagerService
                ViewRootImpl vr = mDecor.getViewRootImpl();
                if (vr != null) {
                    vr.onWindowTitleChanged();
                }
            }
            dispatchWindowAttributesChanged(getAttributes());
        }
    }
}

Thanks for any help


Solution

  • You need to set a theme when creating the DatePickerDialog and the title will show up.

    new DatePickerDialog(
            context,
            android.R.style.Theme_Material_Light_Dialog,
            ...
    ))