Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnDateChanged is not called in Date picker Android lollipop

Tags:

android

I have custom datepicker and time picker.it was working fine befor api level 21 but after it is not working. i debugged the code and came to know that ondatechanged and ontimechanged is not called when i change the date.

So how to resolv ethis issue.

custom class of DatePicker is -

public class DatePickerDialog extends Dialog implements OnDateChangedListener,OnClickListener{

    private static DatePickerDialog dialog;
    private String date;
    private String title;
    private DatePickerCallback callback;
    private DatePicker datePicker;
    private TextView tvHeading;
    private Button btnDone;
    private String lastModifiedDate;
    private String initialDate;
    private boolean isStartDateToday;
    private long currentDateInMS = 0;
    private Context context;
    private int noOfDaysBefore = 0;

    public DatePickerDialog(Context context, DatePickerCallback callback, String date, String title, boolean isStartDateToday,int noOfDaysBefore) {
        super(context);
        this.context = context;
        this.callback = callback;
        this.date = date;
        this.lastModifiedDate = date;
        this.initialDate = date;
        this.title = title;
        this.isStartDateToday = isStartDateToday;
        this.noOfDaysBefore = noOfDaysBefore;
    }

    public interface DatePickerCallback {
        public void setDate(String date);
    }

    public static void showDatePickerDialog(Context context,DatePickerCallback callback,String date,String title,int numOfDaysBefore){
        dialog = new DatePickerDialog(context, callback, date,title,false,numOfDaysBefore);
        dialog.show();
    }

    public static void showDatePickerDialogStartDateToday(Context context,DatePickerCallback callback,String date,String title){
        dialog = new DatePickerDialog(context, callback, date,title,true,0);
        dialog.show();
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.layout_datepicker);
         getWindow().getAttributes().windowAnimations = R.style.animationdialog;
        findAllIds();

        setListener();
        init(date);
    }

    private void findAllIds(){
        tvHeading = (TextView)findViewById(R.id.tv_heading);
        datePicker = (DatePicker)findViewById(R.id.datePicker);
        btnDone = (Button)findViewById(R.id.btn_done);
        tvHeading.setText(title);
    }

    private void setListener(){
        btnDone.setOnClickListener(this);
    }

    private long getMilisecondsFromCalendar(int noOfDays){
        SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy HH:mm:ss");
        String previousDate = CommonFunction.getDateBeforeOrAfterNoOfDays(
                CommonFunction.getCurrentDate("ddMMyyyy HH:mm:ss"), noOfDaysBefore, "ddMMyyyy HH:mm:ss");
        Date date;
        Calendar calendar = Calendar.getInstance();
        try {
            date = sdf.parse(previousDate);
            calendar.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return calendar.getTimeInMillis();
    }

    private void init(String date){
        String date_str = CommonFunction.formatDate("yyyyMMdd", "dd MM yyyy", date);
        String datearr[] = date_str.split(" ");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Integer.parseInt(datearr[2]), Integer.parseInt(datearr[1]), Integer.parseInt(datearr[0])); 
        int iDay=calendar.get(Calendar.DATE);
        int iMonth=calendar.get(Calendar.MONTH); 
        int iYear=calendar.get(Calendar.YEAR);
        if(isStartDateToday){
            datePicker.setMinDate(System.currentTimeMillis()-1000);
        }else{
            if(currentDateInMS == 0){

                currentDateInMS = getMilisecondsFromCalendar(1);//Calendar.getInstance().getTimeInMillis();
            }
            datePicker.setMaxDate(currentDateInMS);
        }
        datePicker.init(iYear, iMonth-1, iDay, this);
        datePicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
    }

    @Override
    public void onDateChanged(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {
        StringBuilder date = new StringBuilder();
        date.append(year);
        monthOfYear = monthOfYear +1;
        if(monthOfYear < 10){
            date.append("0"+monthOfYear+dayOfMonth);
        }else{
            date.append(monthOfYear).append(dayOfMonth);
        }
        if(isStartDateToday){

        }else{
            if(!isDateValid(date.toString())){
                try{
                    init(lastModifiedDate);
                }catch(Exception e){
                    e.printStackTrace();
                }
                return;
            }
        }
        this.date = date.toString();
    }

    private boolean isDateValid(String date){
        boolean flag = false;
        String currentDate = CommonFunction.getCurrentDate("yyyyMMdd");
        long days = CommonFunction.getNoOfDaysBetweenDate(currentDate, date, "yyyyMMdd");
      //  long days = CommonFunction.getNoOfDaysBetweendate(CommonFunction.formatDate("dd-MMM-yyyy", "ddMMyyyy", ), CommonFunction.formatDate("yyyyMMdd", "ddMMyyyy", date));
        if(days <= 0){
           flag = true; 
           lastModifiedDate = date;
        }
        return flag;
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.btn_done:
            callback.setDate(this.date);
            dialog.dismiss();
            break;
        }
    }
}

and layout file is

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#88000000"
     >

    <TextView
        android:id="@+id/tv_heading"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="@drawable/topcornerblue"
        android:padding="@dimen/datePickerHeadingTextPadding"
        android:text="@string/selectDate"
        android:textColor="@color/white"
        android:textSize="@dimen/datePickerHeadingTextSize" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/whitebottomcorner"
        android:paddingBottom="@dimen/datePickerButtonMargin"
        android:layout_below="@+id/tv_heading" >

        <DatePicker
            android:id="@+id/datePicker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="@dimen/datePickerMarginTop" />


        <Button
            android:id="@+id/btn_done"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/datePicker"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="@dimen/datePickerMarginTop"
            android:background="#14768D"
            android:padding="@dimen/datePickerHeadingTextPadding"
            android:text="@string/done"
            android:textColor="@color/white"
            android:minWidth="@dimen/datePickerButtonMinWidth"
            android:minHeight="@dimen/datePickerButtonMinHeight"
            android:textSize="@dimen/datePickerButtonTextSize"
            android:visibility="visible" />
    </RelativeLayout>

</RelativeLayout>
like image 555
Ashish Agrawal Avatar asked Jul 24 '15 11:07

Ashish Agrawal


1 Answers

This is a bug in Android 5.0 and up that occurs when the datepicker is in its new material style calendar mode. You can work around this bug by forcing the datepicker to use the pre-5.0 spinner mode by setting android:datePickerMode="spinner" on the DatePicker.

Or you can use the DatePickerDialog instead. The onDateChanged method of the dialog's listener does get called, even if the dialog is in the new material calendar mode.

like image 141
Leon Lucardie Avatar answered Nov 08 '22 11:11

Leon Lucardie