0

I have two Dialog Picker: Check In and Check Out. But I want that after clicking dates from the Check In, it will disable dates before that. So when I click March 6, 2019 on the Check In, on the Checkout, it should be March 7, 2019 and so on.

Check In and Check Out Image1

DatePickerFragment.Java:

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {


        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog dialog = new DatePickerDialog(getContext(), (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day);

        dialog.getDatePicker().setMinDate(System.currentTimeMillis()-1000);


        return dialog;
    }

Details.Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

     final DialogFragment datePicker = new DatePickerFragment();

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            datePicker.show(getSupportFragmentManager(),"Date Picker");
            startDateOrEndDate = true ;
        }
    });
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            datePicker.show(getSupportFragmentManager(),"Date Picker");
            startDateOrEndDate = false ;
        }
    });
      }

public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.YEAR, year );
    c.set(Calendar.MONTH, month);
    c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    String date = DateFormat.getDateInstance(DateFormat.FULL).format(c.getTime());



    TextView textView = (TextView) findViewById(R.id.checkInTV);
    TextView textView2 = (TextView) findViewById(R.id.checkOutTV);




    if (startDateOrEndDate) {
        textView.setText(date);
    } else {
        textView2.setText(date);
    }
}
  • 1
    Possible duplicate of [Disable specific dates of day in Android date picker](https://stackoverflow.com/questions/35599203/disable-specific-dates-of-day-in-android-date-picker) – Siamak Ferdos Mar 06 '19 at 15:18
  • But what I need is that user picked the first date and then in the second date, dates before the first date should be disable. For example. Right now is March 6, so on the first date picker I chose March 9, then on the second date picker, dates before March 9 should already be disabled, only from march 9 should be applicable. – Christian De Silva Mar 06 '19 at 15:26
  • Did you get your solution? – amitava Mar 11 '19 at 06:31
  • sadly no T_T. I updated my codes but I guess no one hasn't found a solution. please help. thank you :) – Christian De Silva Mar 11 '19 at 10:50
  • Please tag whoever you are commenting, otherwise they will never know you commented. Just type @name,(first few letter of name of recipient) it will auto fill. – amitava Mar 12 '19 at 18:37
  • I believe the code provided by me shows how to set the date as you wanted. In that case would you mark my answer as right. – amitava Mar 13 '19 at 12:14
  • @amitava I've been able to set the date. However, the first date chosen probably will display on both textviews which is not the one I'm looking for. I'm looking for something that when I open the first dialog fragment, it will display the date on the Check In TextView and then, on the second dialog fragment, it will disable all the dates before the date chosen on the first dialog fragment and I'll be able to choose second date to display on the Check Out TextView. – Christian De Silva Mar 13 '19 at 14:10

2 Answers2

0

I believe that what you are looking for is reworking your date picker code such that setMinDate() can be set when created, so that you can pass in the min date. Right now you are setting the min date right here:

dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);

This works fine for the first date picker, as the min date given is today, but for the second date picker you want to pass in the first date as the min date.

I don't know what your other code looks like in terms of creating the date picker fragment, but assuming you are using fragments you can put the min date in the arguments bundle when creating the fragment. Here's an example of how you would pass in the min date when creating the Fragment:

// This would be the start date the user had previously chosen
long startDate = 0L

Bundle bundle = new Bundle(); 

// We only want to put in the min date if this is the second date
if (!startDateOrEndDate) {
    bundle.putLong("minDate", startDate); 
}

// Create the Fragment, set the bundle as its arguments
DatePickerFragment fragment = new DatePickerFragment(); 
fragment.setArguments(bundle);

Then, in the DatePickerFragment, you would set the min date accordingly:

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    // Dialog Creation code here

    // Default the min date to today 
    long minDate = System.currentTimeMillis() - 1000;

    // Check if there are arguments
    Bundle args = getArguments(); 
    if (args != null) {
        // If there are args, grab the min date from it (default to today just in case)
        minDate = args.getLong("minDate", minDate); 
    }

    dialog.getDatePicker().setMinDate(minDate); 

    return dialog; 
}

There's a few things to take into account:

  • You have to make sure that the user chooses the start date before the end date.
  • You might want to set the end date as (startDate + 1 day) as opposed to just startDate, so you'll need to take that into account when passing the minDate.

Overall this should give you an idea of how to proceed.

Side note: I would recommend renaming your boolean to something clear, such as isStartDate. That way if it's true, you know it's the start date and vice versa. startDateOrEndDate doesn't tell us which one it is if it's true, it just tells us that it's either the start date or the end date.

Edit - March 11, 2019

Given your new code, this is how you could change it with what I have said above

Details.java

private long startDate = -1L; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            DialogFragment datePicker = new DatePickerFragment();
            datePicker.show(getSupportFragmentManager(),"Date Picker");
            startDateOrEndDate = true ;
        }
    });
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (startDate == -1L) {
                // Start date hasn't been chosen yet, tell user to do so
                Toast.makeText(Details.this, "Please choose start date", Toast.LENGTH_SHORT).show(); 
                return; 
            }

            // Add the start date to the bundle
            Bundle bundle = new Bundle(); 
            bundle.putLong("minDate", startDate); 

            // Create the Fragment, set the bundle as its arguments
            DatePickerFragment datePicker = new DatePickerFragment(); 
            datePicker.setArguments(bundle);
            datePicker.show(getSupportFragmentManager(),"Date Picker");
            startDateOrEndDate = false ;
        }
    });
}

public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.YEAR, year );
    c.set(Calendar.MONTH, month);
    c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    String date = DateFormat.getDateInstance(DateFormat.FULL).format(c.getTime());

    TextView textView = (TextView) findViewById(R.id.checkInTV);
    TextView textView2 = (TextView) findViewById(R.id.checkOutTV);

    if (startDateOrEndDate) {
        // If this is the start date, save it to the instance variable above
        startDate = c.getTimeinMillis(); 
        textView.setText(date);
    } else {
        textView2.setText(date);
    }
}

And in the onCreateDialog() of the DatePickerFragment use the code in my original answer above.

Let me know if this makes sense!

jguerinet
  • 1,429
  • 1
  • 14
  • 21
  • how will I setText the bundle.putLong("minDate", startDate); into textview? – Christian De Silva Mar 11 '19 at 04:18
  • I actually don't get anything. I'm newbie to android programming T_T – Christian De Silva Mar 11 '19 at 04:35
  • I'm getting an error of java.lang.NullPointerException: Attempt to invoke virtual method 'long android.os.Bundle.getLong(java.lang.String, long)' on a null object reference at com.example.batangasbeachhousesfinal.DatePickerFragment.onCreateDialog(DatePickerFragment.java:28) – Christian De Silva Mar 13 '19 at 04:02
  • Yes, that is because I'm not adding the arguments to the first DatePicker. This is untested code, my apologies. I'll edit right now. You just need to check if there is a bundle before proceeding. – jguerinet Mar 13 '19 at 14:37
  • actually no, it crashes when I did that. But thank you btw :) – Christian De Silva Mar 21 '19 at 11:49
0

You can copy paste the following code somewhere and then add your code.

The MainActivity

public class MainActivity extends AppCompatActivity implements
    DatePickerDialog.OnDateSetListener{
final long[]l = new long[1];
boolean startDateOrEndDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button en = findViewById(R.id.entry);
    Button ex = findViewById(R.id.exit);


    final myDatepickerFragment datePicker = new myDatepickerFragment();

    en.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            l[0]= System.currentTimeMillis();
            datePicker.show(getSupportFragmentManager(),l[0]+"");

            startDateOrEndDate = true ;
        }
    });
    ex.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            datePicker.show(getSupportFragmentManager(),l[0]+"");
            startDateOrEndDate = false ;
        }
    });

}
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.YEAR, year);
    c.set(Calendar.MONTH, month);
    c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    l[0]= c.getTimeInMillis()+24*60*60*1000;
    String date = DateFormat.getDateInstance(DateFormat.FULL).format(c.getTime());
    System.out.println(date);

TextView textView = (TextView) findViewById(R.id.checkInTV);
TextView textView2 = (TextView) findViewById(R.id.checkOutTV);


if (startDateOrEndDate) {
    textView.setText(date);
} else {
    textView2.setText(date);
}
}
}

The Fragment class

public class myDatepickerFragment extends DialogFragment {
private String tag;

@Override
public void show(FragmentManager manager, String tag) {
    super.show(manager, tag);
    this.tag = tag;
}

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {


    Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);
    long l = Long.parseLong(tag);
    DatePickerDialog dialog = new DatePickerDialog(getContext(), (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day);

    dialog.getDatePicker().setMinDate(l-1000);
    dialog.getDatePicker().setBackgroundColor(Color.rgb(50,100,100));


    return dialog;
} }

I started experimenting with "tag" attribute earlier; may not be in proper copybook style, but it serves my purpose.

By the way it seems that you implemented the listener in (main) activity but I did not see "@override" there. Would you please explain this.

amitava
  • 505
  • 1
  • 5
  • 10
  • how can I show the date picked from dialog to text view? both on checIn and checkOut textview – Christian De Silva Mar 13 '19 at 04:47
  • @ChristianDeSilva Use the "date" from inside onDateSet(). Is not that you were doing earlier? – amitava Mar 13 '19 at 05:18
  • here's the thing. If I use the "date" from inside onDateSet(), then I'll be probably display the same date both on Check In and Check Out textviews? – Christian De Silva Mar 13 '19 at 14:06
  • @ChristianDeSilva, No I guess it should not. You already have a code for that which I did not include as I asked you to include that, I modified my answer to include your code. – amitava Mar 13 '19 at 15:47
  • @ChristianDeSilva, did you get different date by different button click. I am confident that you should. – amitava Mar 14 '19 at 16:24
  • OMG! Worked like a charm! Thank You so much for this help. I badly needed this for my thesis. – Christian De Silva Mar 15 '19 at 08:46
  • @ChristianDeSilva, Glad that you got it. Would you also upvote it, what you did I guess you choose it to be best answer, so I see the green acceptance tic mark. You can also upvote it, by this you are confirming that the answer is useful to you. – amitava Mar 15 '19 at 10:18
  • I actually upvote it however, I'm below 15 reputations so it won't display as of now I guess? another questions, How can I save it to SQLite? Do I need to get it like checkInTV.getString or something? – Christian De Silva Mar 15 '19 at 11:45
  • Oh Thanks, absolutely okay. You should use textView.getText(); – amitava Mar 15 '19 at 12:08
  • I have a constructor like public Beach(String name, String image, String description, String price, String menuID, String checkIn, String checkOut) { this.name = name; this.image = image; this.description = description; this.price = price; this.menuID = menuID; this.checkIn = checkIn; this.checkOut = checkOut; } however, when currentBeach.setCheckIn(checkInTV.getText().toString()) is void? why? – Christian De Silva Mar 15 '19 at 12:28
  • Well, I'm just gonna put another topic about it. I'm having problem with construction as I got an error of java.string.lang,java.string.lang,java.string.lang,void,void – Christian De Silva Mar 15 '19 at 12:37
  • checkInTV is id what I see in your code. Please use textView instead of checkInTV. – amitava Mar 15 '19 at 16:19