call DatePicker from helper class to an android activity - java

Iam using DatePickerDialog in one of my activity and its working fine but now I have to implement it in many activities so I thought to put it in a helper class and extend that function to all activities as good code practice.I have created an interface but couldn't able to use it properly.I have seen another link on stackoverflow but over there they are extending from one class to another class not activity.What I want is I have a helper class where I have put multiple function which Iam using repeatedly in my app and then extend them to any activity according to requirement.So I want to put this datepicker function in HelperClass then then get this function any where in app.Thanku
This is my datePicker function which is currently Iam using in an activity and its working fine
public void datePicker(int day,int month,int year) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
final Calendar myCalendar = Calendar.getInstance();
year = myCalendar.get(Calendar.YEAR);
month = myCalendar.get(Calendar.MONTH);
day = myCalendar.get(Calendar.DAY_OF_MONTH);
}
picker = new DatePickerDialog(RequestTraining.this, new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
}
}, year, month, day);
picker.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
picker.show();
}
This is the interface I made
public interface DatePickerListener {
public void onDate(DatePicker view, int year, int monthOfYear, int dayOfMonth);
}

I think, the best approach will be like this
class Utils {
public void datePicker(Context mContext, EditText et) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
final Calendar myCalendar = Calendar.getInstance();
year = myCalendar.get(Calendar.YEAR);
month = myCalendar.get(Calendar.MONTH);
day = myCalendar.get(Calendar.DAY_OF_MONTH);
}
picker = new DatePickerDialog(mContext, new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
et.setText(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year);
}
}, year, month, day);
picker.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
picker.show();
}
}
And now just call this method from any class like
Utils.datePicker(this, editText);

Just Need to make an interface callBack and implement it in all of your activities where you need callBack. Then you need to override the method onDateSelected(String date) in your activities which implements callBack interface. Just call the Utils.datePicker(this) where you want .
interface callBack{
onDateSelected(String date);
}
class Utils {
public static void datePicker(callBack call) {
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.N)
{
final Calendar myCalendar = Calendar.getInstance();
year = myCalendar.get(Calendar.YEAR);
month = myCalendar.get(Calendar.MONTH);
day = myCalendar.get(Calendar.DAY_OF_MONTH);
}
picker = new DatePickerDialog(RequestTraining.this, new
DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int
dayOfMonth) {
trainingDate = dayOfMonth + "/" + (monthOfYear + 1) + "/" + year;
call.onDateSelected(trainingDate);
}
}, year, month, day);
picker.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
picker.show();
}
}
Hope it will help you.

Related

DatePickerDialog outputs "DatePickerFragment must be a public static class to be properly recreated from instant state"

I am trying to implement this DatePickerDialog in my Android App:
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month, day);
}
public void onDateSet(DatePicker view, int year, int month, int day) {
int mon = month + 1;
date = day + "/" + mon + "/" + year;
textview1.setText(date);
}
}
unfortunatly the App crashes when I try to show the dialog showDatePickerDialog(imageview1); and I get the following Error:
"DatePickerFragment must be a public static class to be properly recreated from instant state"
May someone please help me fix this? I am grateful for every response :)

How can I add 40 weeks to the current date I get from the date picker

I have this code, I want to add 40 weeks to the date I get from the date Picker and get the new date after the 40 weeks (280 days) has been added to the date from the date picker.
Code:
public class MainActivity extends AppCompatActivity {
DatePickerDialog picker;
EditText eText;
Button btnGet;
TextView tvw;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvw=(TextView)findViewById(R.id.textView1);
eText=(EditText) findViewById(R.id.editText1);
eText.setInputType(InputType.TYPE_NULL);
eText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Calendar cldr = Calendar.getInstance();
int day = cldr.get(Calendar.DAY_OF_MONTH);
int month = cldr.get(Calendar.MONTH);
int year = cldr.get(Calendar.YEAR);
// date picker dialog
picker = new DatePickerDialog(MainActivity.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
eText.setText(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year);
}
}, year, month, day);
picker.show();
}
});
btnGet=(Button)findViewById(R.id.button1);
btnGet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tvw.setText("Selected Date: "+ eText.getText());
}
});
}
}
Joda time is a very convenient library for handling such cases. Add this to your project:
dependencies {
compile 'joda-time:joda-time:2.10.2'
}
And then you can manipulate the dates like this:
DateTime dt = DateTime.now();
DateTime laterDate = dt.withYear(2020)
.withMonthOfYear(3)
.withDayOfMonth(14)
.plusWeeks(40);
Remember that in JodaTime date objects are immutable (which is a very good idea), so each manipulation produces a new object.
First, convert the current format to milliseconds and then add specific days milliseconds and then again get it in the desired format. Like this way:
new DatePickerDialog(MainActivity.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar calendar = Calendar.getInstance();
calendar.set(year,monthOfYear + 1,dayOfMonth);
long timeInMilliseconds =
calendar.getTimeInMillis()+TimeUnit.DAYS.toMillis(280);
calendar.setTimeInMillis(timeInMilliseconds);
int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);
eText.setText(mDay + "/" + mMonth + "/" + mYear);
}
}, year, month, day);
picker.show();
}
});
Use add(Calendar.DAY_OF_MONTH, int) function in this way:
cldr.add(Calendar.DAY_OF_MONTH, 280);
Logically speaking, you don't have to add 40 weeks per say, a week has specific number of days, thus you can just add 40*7 = 280 days in your current day picked up from date picker.
[current date] + TimeUnit.DAYS.toMillis(280)

Android how to show years first in datepicker when onclick the button

datepickerLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
final Calendar calendar = Calendar.getInstance();
int yy = calendar.get(Calendar.YEAR);
int mm = calendar.get(Calendar.MONTH);
int dd = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(getContext(),new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
datePickerDialog.getTouchables().get(0).performClick();
String strdate=year+"-"+(monthOfYear+1)+"-"+dayOfMonth;
}
}, yy, mm, dd);
datePickerDialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
datePickerDialog.show();
}
});
I want to display years in datepicker when button is clicked after selecting the years i want to select date.
You can achieve this simply using below code
DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day);
dialog.getDatePicker().getTouchables().get( 0 ).performClick();
Use below class to open dialog
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
OnDateOfBirthSelection registrationIIFragment;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
// Create a new instance of DatePickerDialog and return it
DatePickerDialog abc = new DatePickerDialog(getActivity(), this, year, month, day);
//18 Years =568,025,136,000 Milliseconds
double diff = System.currentTimeMillis() - 568025136000.0;
abc.getDatePicker().setMaxDate((long) diff);
abc.getDatePicker().getTouchables().get( 0 ).performClick();
return abc;
}
public void onDateSet(DatePicker view, int year, int month, int day) {
// Do something with the date chosen by the user
// tv1.setText("Year: "+view.getYear()+" Month: "+view.getMonth()+" Day: "+view.getDayOfMonth());
registrationIIFragment.onDateOfBirthSelected(view.getDayOfMonth() + " - " + (view.getMonth() + 1) + " - " + view.getYear());
}
public void setCallbackListener(OnDateOfBirthSelection registrationIIFragment) {
this.registrationIIFragment = registrationIIFragment;
}
public interface OnDateOfBirthSelection {
public void onDateOfBirthSelected(String s);
} }
In button click create above class instance and call show method.
DatePickerFragment newFragment = new DatePickerFragment();
newFragment.setCallbackListener(this);
newFragment.show(getSupportFragmentManager(), "datePicker");
above code will display output as below image
Hope this will help thanks

Android DatePicker dialog, date should come from tomorrow

Calendar calender = Calendar.getInstance();
final CustomDatePickerDialog pickerDialog = new CustomDatePickerDialog(LabCheckOutActivity.this,
myDateListener, calender.get(Calendar.YEAR), calender.get(Calendar.MONTH),
calender.get(Calendar.DAY_OF_MONTH)+1);
pickerDialog.getDatePicker().setMinDate(System.currentTimeMillis()-1000);
pickerDialog.show();
by Using this code, in dialog date is pointed to tomorrow but user can also select todays date.I want user can select date from tomorrow not today.
public class CustomDatePickerDialog extends DatePickerDialog {
int maxYear;
int maxMonth;
int maxDay;
public CustomDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
super(context, callBack, year, monthOfYear, dayOfMonth);
}
public void setMaxDate(long maxDate) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getDatePicker().setMaxDate(System.currentTimeMillis());
} else {
final Calendar c = Calendar.getInstance();
c.setTimeInMillis(maxDate);
maxYear = c.get(Calendar.YEAR);
maxMonth = c.get(Calendar.MONTH);
maxDay = c.get(Calendar.DAY_OF_MONTH);
}
}
#Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
super.onDateChanged(view, year, monthOfYear, dayOfMonth);
} else {
if (year > maxYear)
view.updateDate(maxYear, maxMonth, maxDay);
if (monthOfYear > maxMonth && year == maxYear)
view.updateDate(maxYear, maxMonth, maxDay);
if (dayOfMonth > maxDay && year == maxYear && monthOfYear == maxMonth)
view.updateDate(maxYear, maxMonth, maxDay);
}
}
}
Use
pickerDialog.getDatePicker().setMinDate(System.currentTimeMillis()+24*60*60*1000);//where 24*60*60*1000 represents the total timestamp for one day
instead of
pickerDialog.getDatePicker().setMinDate(System.currentTimeMillis()-1000);
Please see complete implementation below:
DialogFragment class
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener
{
public DatePickerFragment()
{
}
public void setiDateTimeListener(IDateTimeListener iDateTimeListener)
{
this.iDateTimeListener = iDateTimeListener;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Use the current date as the default date in the picker
final 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 datePickerDialog = new DatePickerDialog(getActivity(), this, year, month, day);
// Set minimum date as tommorw
datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() + 24*60*60*1000);
// If need to set max date then use this also
// datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());
// Create a new instance of DatePickerDialog and return it
return datePickerDialog;
}
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
{
try
{
String selectedDt = dayOfMonth+"-"+(monthOfYear + 1)+"-"+year;
iDateTimeListener.onDateSet(selectedDt);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Interface must be implemented in date picker calling class
public interface IDateTimeListener
{
public void onDateSet(String date);
}
Calling dialog fragment
public void showDatePickerDialog()
{
DatePickerFragment datePickerFragment = new DatePickerFragment();
datePickerFragment.setiDateTimeListener(this);
datePickerFragment.show(getActivity().getSupportFragmentManager(),"datePicker");
}
if (CustomVerticalCalendarView.isPreviousDateDisabled()) { // disable previous date disable flow
int daysOfYear = listCalender.get(Calendar.DAY_OF_YEAR);
int currentDate = today.get(Calendar.DAY_OF_YEAR);
int listYear = listCalender.get(Calendar.YEAR);
int currentYear = today.get(Calendar.YEAR);
if (daysOfYear < currentDate || listYear < currentYear) {
checkBox.setEnabled(false);
checkBox.setTextColor(ContextCompat.getColor(checkBox.getContext(), R.color.dark_gray));
}
}
Hope this code helps you.

I have two methods which are nearly the same, how to refactor them?

I am having two DatePickerFragments because I need to pick up a start and end time.
private void showDatePickerTimePeriodStart() {
final DatePickerFragment date = new DatePickerFragment();
// Sets up the current date in Dialog.
final Calendar calender = Calendar.getInstance();
final Bundle args = new Bundle();
args.putInt("year", calender.get(Calendar.YEAR));
args.putInt("month", calender.get(Calendar.MONTH));
args.putInt("day", calender.get(Calendar.DAY_OF_MONTH));
date.setArguments(args);
// Sets callback to the captured data.
date.setCallBack(ondate);
date.show(getFragmentManager(), "Date Picker");
}
OnDateSetListener ondate = new OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
final Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(year, monthOfYear, dayOfMonth);
millisSinceEpochStart = calendar.getTimeInMillis();
}
};
private void showDatePickerTimePeriodEnd() {
final DatePickerFragment date = new DatePickerFragment();
// Sets up the current date in Dialog.
final Calendar calender = Calendar.getInstance();
final Bundle args = new Bundle();
args.putInt("year", calender.get(Calendar.YEAR));
args.putInt("month", calender.get(Calendar.MONTH));
args.putInt("day", calender.get(Calendar.DAY_OF_MONTH));
date.setArguments(args);
/**
* Set Call back to capture selected date
*/
date.setCallBack(ondateSecond);
date.show(getFragmentManager(), "Date Picker");
}
OnDateSetListener ondateSecond = new OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
final Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(year, monthOfYear, dayOfMonth);
millisSinceEpochEnd = calendar.getTimeInMillis();
}
};
The Fragment(s):
public class DatePickerFragment extends DialogFragment {
OnDateSetListener ondateSet;
public DatePickerFragment() {}
public void setCallBack(OnDateSetListener ondate) {
ondateSet = ondate;
}
private int year;
private int month;
private int day;
#Override
public void setArguments(Bundle args) {
super.setArguments(args);
year = args.getInt("year");
month = args.getInt("month");
day = args.getInt("day");
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new DatePickerDialog(getActivity(), ondateSet, year, month, day);
}
}
And there is one more Fragment, which is the same.
So it appears to me, if I set up the first Date, I need to do setCallBack, but I have two separate buttons, so to my understanding, I need another method, which sets another callback. I want to avoid this repetition because it's not very DRY.
How do I fix this?
Technically, since it's setting different vars, it is different functionality and is not doing too much repetition. One way to condense the replicated code would be to move it to another method. Try this:
public long getMillis(int year, int monthOfYear, int dayOfMonth){
final Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(year, monthOfYear, dayOfMonth);
return calendar.getTimeInMillis();
}
Then you can simply have your callbacks call the above method.
OnDateSetListener ondate= new OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
millisSinceEpochStart = getMillis(year, monthOfYear, dayOfMonth);
}
};
...
OnDateSetListener ondateSecond = new OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
millisSinceEpochEnd = getMillis(year, monthOfYear, dayOfMonth);
}
};
If I understand this correctly (if not let me know and I will delete this), you could do something like this
public class DatePickerFragment extends DialogFragment{
// What you already have
...
// Show the date time picker on click
// (assuming the click listener is already setup)
public void showDateTimePicker(){
final DatePickerFragment date = new DatePickerFragment();
// Sets up the current date in Dialog.
final Calendar calender = Calendar.getInstance();
final Bundle args = new Bundle();
args.putInt("year", calender.get(Calendar.YEAR));
args.putInt("month", calender.get(Calendar.MONTH));
args.putInt("day", calender.get(Calendar.DAY_OF_MONTH));
date.setArguments(args);
/**
* Set Call back to capture selected date
*/
date.setCallBack(getCallback());
date.show(getFragmentManager(), "Date Picker");
}
public OnDateSetListener getCallback(){
return new OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
final Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(year, monthOfYear, dayOfMonth);
setTime(calendar.getTimeInMillis());
}
};
}
public void setTime(long timeInMillis){
// Override this method and do what you want with the millis
}
}
Then all you would have to do in your DatePickerFragment's is override setTime(long timeInMillis) and do what you want with the value.
For example
public class StartDatePickerFragment extends DatePickerFragment{
#Override
public void setTime(long timeInMillis){
millisSinceEpochStart = timeInMillis;
// Do whatever else you want in the override call
...
}
// Do whatever else you want outside of the method
...
}
You can also override the getCallback() function itself if you didn't want to utilize the default listener.

Categories