Retrieving times from two TimePickers in DialogFragments - java

I have an input form in an activity where I'd like to retrieve the start time and end time of an event. I am using a timepicker displayed in a dialog fragment to get the start time and return it to the main activity, but how do re use the same logic to retrieve the end time of the event? My code:
Main Activity:
public class AddEventActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener{
private int pickerHour = 0;
private int pickerMin = 0;
//code ommitted for length
public void showTimePickerDialog(View v) {
TimePickerFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "timePicker");
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
String amOrPm = "am";
pickerHour = hourOfDay;
pickerMin = minute;
String minutesString = "";
if (hourOfDay > 12){ //translate to 12 hr clock. Little workaround to get both timepicker and am/pm label to show up correctly.
amOrPm = "pm";
pickerHour-=12;
}
if (pickerMin < 10) {
minutesString = "0"; //fix weird bug where only one zero is shown on times ending in :00
}
startTimeView.setText(pickerHour + " : " + minutesString + pickerMin + " " +amOrPm );
}
TimePickerFragment:
public class TimePickerFragment extends DialogFragment {
int hour,minute;
private Activity mActivity;
private TimePickerDialog.OnTimeSetListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
try {
mListener = (TimePickerDialog.OnTimeSetListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnTimeSetListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(mActivity, mListener, hour, minute,
DateFormat.is24HourFormat(mActivity));
}
}
I need to be able to differentiate between the start time and the end time, but I am not sure how to differentiate them without repeating myself. I am pretty new to Java and Android. Thank you so much for any help.

Possibly something as simple as a boolean?
public class AddEventActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener{
...
boolean isSettingStartTime = true;
//code ommitted for length
public void showTimePickerDialog(View v) {
TimePickerFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "timePicker");
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
...
if (isSettingStartTime) {
startTimeView.setText(pickerHour + " : " + minutesString + pickerMin + " " +amOrPm );
isSettingStartTime = false;
} else {
endTimeView.setText(pickerHour + " : " + minutesString + pickerMin + " " +amOrPm );
}
}
}

This would require you being able to retrieve the TimePicker from your TimePickerFragment
You either need to get the TimePicker instance when you create both TimePickerFragments and store them in two fields such as startTimePicker and finishTimePicker.
Then when the TimePicker is passed in through the onTimeSet you then check to see which TimePicker it is like so.
if ( timePicker == startTimePicker ) {
startTimeTextView.setText....
} else {
finishTimeTextView.setText...
}

Related

NullPoinerException in Fragment when handling dialog onclicklistener

I want to call a custom Dialog in fragment, where user will add some data and I want to get it in that fragment.
For this I created a dialog class and a special layout for it (I think it's not neccessary to post it here):
public class IntervalsDialog extends DialogFragment {
private TextView interval1, interval2, interval3, interval4;
private EditText weight1, weight2, weight3, weight4;
private IntervalDialogListener listener;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
try {
listener = (IntervalDialogListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "you must implement IntervalsDialogListener");
}
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_layout, null);
builder.setView(view).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).setPositiveButton("Go further", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (weight1.getText().toString().trim().matches("") || weight2.getText().toString().trim().matches("") ||
weight3.getText().toString().trim().matches("") || weight4.getText().toString().trim().matches("")){
Toast.makeText(getContext(), "You must fill in all the blanks to continue", Toast.LENGTH_SHORT).show();
}
else{
int w1 = Integer.valueOf(weight1.getText().toString().trim());
int w2 = Integer.valueOf(weight2.getText().toString().trim());
int w3 = Integer.valueOf(weight3.getText().toString().trim());
int w4 = Integer.valueOf(weight4.getText().toString().trim());
listener.onPositiveButtonClicked(w1, w2, w3, w4);
}
}
});
interval1 = view.findViewById(R.id.interval1);
interval2 = view.findViewById(R.id.interval2);
interval3 = view.findViewById(R.id.interval3);
interval4 = view.findViewById(R.id.interval4);
weight1 = view.findViewById(R.id.weight1);
weight2 = view.findViewById(R.id.weight2);
weight3 = view.findViewById(R.id.weight3);
weight4 = view.findViewById(R.id.weight4);
setIntervals();
return builder.create();
}
public interface IntervalDialogListener{
void onPositiveButtonClicked(int weigh1, int weight2, int weight3, int weight4);
}
private void setIntervals(){
int dayStart = 360;
int dayEnd = 1320;
ArrayList<Interval> idealInt = new ArrayList<>();
int dayInterval = (dayEnd - dayStart)/4;
for (int i = dayStart; i < dayEnd; i+= dayInterval) {
idealInt.add(new Interval(i, i + dayInterval));
}
interval1.setText(idealInt.get(0).toString());
interval2.setText(idealInt.get(1).toString());
interval3.setText(idealInt.get(2).toString());
interval4.setText(idealInt.get(3).toString());
}
}
class Interval{
private int start, end;
Interval(int start, int end){
this.start = start;
this.end = end;
}
public String toString() {
return (toTime(start) + " - " + toTime(end));
}
private static String toTime (int a) {
String s = "";
int b = a/60;
int c = a%60;
if (c < 10) {
s = b + " : " + 0 + c;
}
else {
s = b + " : " + c;
}
return s;
}
}
I faced a problem that my MainActivity could not be casted to a listener. I followed this answer and sended data first to my MainActivity:
#Override
public void onPositiveButtonClicked(int weigh1, int weight2, int weight3, int weight4) {
AddDataFragment fragment = new AddDataFragment();
fragment.getDataFromMainActivity(weigh1, weight2, weight3, weight4);
}
Then wrote a method for getting this data in my fragment (I hope, I did everything right up to this moment):
public void getDataFromMainActivity(int weigh1, int weight2, int weight3, int weight4){
Toast.makeText(getContext(), weigh1 + " -- " + weight2 + " -- " + weight3 + " -- " + weight4, Toast.LENGTH_LONG).show();
AddDataFragmentDirections.ActionSort action = AddDataFragmentDirections.actionSort();
action.setCurrentDate(currentDateGot);
action.setWeight1(weigh1);
action.setWeight2(weight2);
action.setWeight3(weight3);
action.setWeight4(weight4);
Navigation.findNavController(getView()).navigate(action);
}
Then I simply want to check if the data is saved correctly via Toast message. And then I get this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.widget.Toast.<init>(Toast.java:114)
at android.widget.Toast.makeText(Toast.java:277)
at android.widget.Toast.makeText(Toast.java:267)
at com.example.chronosaur.ui.AddDataFragment.getDataFromMainActivity(AddDataFragment.java:232)
at com.example.chronosaur.ui.MainActivity.onPositiveButtonClicked(MainActivity.java:44)
at com.example.chronosaur.ui.IntervalsDialog$1.onClick(IntervalsDialog.java:64)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
...
Why does this error occur? What did I miss? Please, help me. Thanks for any help.
Your DialogFragment was never attached to your activity. After instantiating your AddDataFragment use following way to attach it with your activity.
FragmentManager fm = getSupportFragmentManager();
fragment.show(fm, "tag");
Ignore the following part if your minSdk is not below 23.
getContext() is an API 23+ method which may produce exceptions on lower API devices.
Create a Context variable in your class to store the context.
...
private Context context; //add this
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
this.context = context; //add this
...
}
And replace getContext() with context e.g. Toast by using:
Toast.makeText(context, weigh1 + " -- " + weight2 + " -- " + weight3 + " -- " + weight4, Toast.LENGTH_LONG).show();

How to add timePicker using fragment?

I have 4 timePicker in my app. The timePicker dialog will pop out when the user double click on the editText. But sometimes when I accidentally click more than two times, the app crashed and said that the fragment already added. How can I fix this? Insted of clicking the editText twice, I want the timePicker dialog shown by just one click on the editText.
public void onClick(View v) {
int id = v.getId();
if (id == R.id.editTextTI1) {
tp.setFlag(TimePick.FLAG_START_DATE);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTO1) {
tp.setFlag(TimePick.FLAG_END_DATE);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTI2) {
tp.setFlag(TimePick.FLAG_START_DATE1);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTO2) {
tp.setFlag(TimePick.FLAG_END_DATE1);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTI3) {
tp.setFlag(TimePick.FLAG_START_DATE2);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTO3) {
tp.setFlag(TimePick.FLAG_END_DATE2);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTI4) {
tp.setFlag(TimePick.FLAG_START_DATE3);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
if (id == R.id.editTextTO4) {
tp.setFlag(TimePick.FLAG_END_DATE3);
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp.show(ft, "TimePicker");
}
}
public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener {
public static final int FLAG_START_DATE = 00;
public static final int FLAG_END_DATE = 01;
public static final int FLAG_START_DATE1 = 10;
public static final int FLAG_END_DATE1 = 11;
public static final int FLAG_START_DATE2 = 20;
public static final int FLAG_END_DATE2 = 21;
public static final int FLAG_START_DATE3 = 30;
public static final int FLAG_END_DATE3 = 31;
private int flag = 00;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
public void setFlag(int i) {
flag = i;
}
#Override
public void onTimeSet(TimePicker view, int hourofDay, int minute) {
if (flag == FLAG_START_DATE) {
start.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
b = start.getText().toString();
}
if (flag == FLAG_END_DATE) {
end.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
c = end.getText().toString();
}
if (flag == FLAG_START_DATE1) {
start1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
d = start1.getText().toString();
}
if (flag == FLAG_END_DATE1) {
end1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
e1 = end1.getText().toString();
}
if (flag == FLAG_START_DATE2) {
start2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
f = start2.getText().toString();
}
if (flag == FLAG_END_DATE2) {
end2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
g = end2.getText().toString();
}
if (flag == FLAG_START_DATE3) {
start3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
h = start3.getText().toString();
}
if (flag == FLAG_END_DATE3) {
end3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
i = end3.getText().toString();
}
LogCat Error
10-15 12:53:17.113 7943-7943/com.example.project.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.project.project, PID: 7943
java.lang.IllegalStateException: Fragment already added: TimePick{7c7eb96 #0 TimePicker}
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1219)
at android.app.BackStackRecord.run(BackStackRecord.java:715)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
Your code is so hardcoded and not easy to extend, which could lead to many bugs in future.
You should encapsulate general logic as max as you can, so in current case:
public void onClick(View v) {
EditText editText = (EditText) v;
if (tp==null || !tp.isAdded()){
FragmentTransaction ft = getFragmentManager().beginTransaction();
tp = new TimePick(editText);
tp.show(ft, "TimePicker");
}
}
#Override
public void onStop() {
super.onStop();
if (tp.isAdded()) tp.dismiss();
}
public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener {
private EditText editText;
public TimePick(EditText editText) {
this.editText = editText;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
#Override
public void onTimeSet(TimePicker view, int hourofDay, int minute) {
editText.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
}
}
this code won't try to create new time picker if any is on screen. You could pass target edittext to timePicker fragment. When you need values from these edittexts(your a,b,c,d... variables) you could read it when needed, not in onTimeSetMethod.
onStop method was provided to handle activity recreation cases. Here i just hide active timepicker.
You are adding the same DialogFragment instance twice, to fix this, check whether TimePicker is added with getFragmentManager.findFragmentByTag("TimePicker").

SimpleDateFormat and wrong dates

I had already tried the first two suggestions below, but I tried again and sincerely thanks for the help! The result is the same though. I´ll just edit the post to add more code info.
Hello there! I´m experimenting with a simple ToDo application and managed to change almost everything I wanted besides the date formatted that´s displayed once the user saves the task.
The task itself is added via the AddToDoActivity class which has the following resumed code:
public class AddToDoActivity extends Activity {
// 7 days in milliseconds - 7 * 24 * 60 * 60 * 1000
private static final int SEVEN_DAYS = 604800000;
private static final String TAG = "Lab-UserInterface";
private static String timeString;
private static String dateString;
private static TextView dateView;
private static TextView timeView;
private Date mDate;
private RadioGroup mPriorityRadioGroup;
private RadioGroup mStatusRadioGroup;
private EditText mTitleText;
private RadioButton mDefaultStatusButton;
private RadioButton mDefaultPriorityButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_todo);
mTitleText = (EditText) findViewById(R.id.title);
mDefaultStatusButton = (RadioButton) findViewById(R.id.statusNotDone);
mDefaultPriorityButton = (RadioButton) findViewById(R.id.medPriority);
mPriorityRadioGroup = (RadioGroup) findViewById(R.id.priorityGroup);
mStatusRadioGroup = (RadioGroup) findViewById(R.id.statusGroup);
dateView = (TextView) findViewById(R.id.date);
timeView = (TextView) findViewById(R.id.time);
// Set the default date and time
setDefaultDateTime();
// OnClickListener for the Date button, calls showDatePickerDialog() to show
// the Date dialog
final Button datePickerButton = (Button) findViewById(R.id.date_picker_button);
datePickerButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showDatePickerDialog();
}
});
// OnClickListener for the Time button, calls showTimePickerDialog() to show
// the Time Dialog
final Button timePickerButton = (Button) findViewById(R.id.time_picker_button);
timePickerButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showTimePickerDialog();
}
});
// OnClickListener for the Cancel Button,
final Button cancelButton = (Button) findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
log("Entered cancelButton.OnClickListener.onClick()");
finish();
}
});
//OnClickListener for the Reset Button
final Button resetButton = (Button) findViewById(R.id.resetButton);
resetButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
log("Entered resetButton.OnClickListener.onClick()");
setDefaultDateTime();
mTitleText.setText("");
mDefaultStatusButton.setChecked(true);
mDefaultPriorityButton.setChecked(true);
}
});
// OnClickListener for the Submit Button
// Implement onClick().
final Button submitButton = (Button) findViewById(R.id.submitButton);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
log("Entered submitButton.OnClickListener.onClick()");
// Gather ToDoItem data
Priority priority = getPriority();
Status status = getStatus();
String titleString = mTitleText.getText().toString();
// Date
String fullDate = dateString + " " + timeString;
// Package ToDoItem data into an Intent
Intent data = new Intent();
ToDoItem.packageIntent(data, titleString, priority, status, fullDate);
setResult(Activity.RESULT_OK, data);
finish();
}
});
}
// Do not modify below here
// Use this method to set the default date and time
private void setDefaultDateTime() {
// Default is current time + 7 days
mDate = new Date();
mDate = new Date(mDate.getTime() + SEVEN_DAYS);
Calendar c = Calendar.getInstance();
c.setTime(mDate);
setDateString(c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.MONTH),
c.get(Calendar.YEAR));
dateView.setText(dateString);
setTimeString(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
c.get(Calendar.MILLISECOND));
timeView.setText(timeString);
}
private static void setDateString(int dayOfMonth, int monthOfYear, int year) {
// Increment monthOfYear for Calendar/Date -> Time Format setting
monthOfYear++;
String mon = "" + monthOfYear;
String day = "" + dayOfMonth;
if (monthOfYear < 10)
mon = "0" + monthOfYear;
if (dayOfMonth < 10)
day = "0" + dayOfMonth;
dateString = year + "-" + mon + "-" + day;
}
private static void setTimeString(int hourOfDay, int minute, int mili) {
String hour = "" + hourOfDay;
String min = "" + minute;
if (hourOfDay < 10)
hour = "0" + hourOfDay;
if (minute < 10)
min = "0" + minute;
timeString = hour + ":" + min + ":00";
}
private Priority getPriority() {
switch (mPriorityRadioGroup.getCheckedRadioButtonId()) {
case R.id.lowPriority: {
return Priority.LOW;
}
case R.id.highPriority: {
return Priority.HIGH;
}
default: {
return Priority.MED;
}
}
}
private Status getStatus() {
switch (mStatusRadioGroup.getCheckedRadioButtonId()) {
case R.id.statusDone: {
return Status.DONE;
}
default: {
return Status.NOTDONE;
}
}
}
// DialogFragment used to pick a ToDoItem deadline date
public static class DatePickerFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int day = c.get(Calendar.DAY_OF_MONTH);
int month = c.get(Calendar.MONTH);
int year = c.get(Calendar.YEAR);
// Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
}
#Override
public void onDateSet(DatePicker view, int dayOfMonth, int monthOfYear,
int year) {
setDateString(dayOfMonth, monthOfYear, year);
dateView.setText(dateString);
}
}
// DialogFragment used to pick a ToDoItem deadline time
public static class TimePickerFragment extends DialogFragment implements
TimePickerDialog.OnTimeSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
// Create a new instance of TimePickerDialog and return
return new TimePickerDialog(getActivity(), this, hour, minute,
true);
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
setTimeString(hourOfDay, minute, 0);
timeView.setText(timeString);
}
}
private void showDatePickerDialog() {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
private void showTimePickerDialog() {
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "timePicker");
}
private void log(String msg) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, msg);
}
}
Here´s the ToDoItem, that actually reads the info from AddToDoActivity:
public class ToDoItem {
public static final String ITEM_SEP = System.getProperty("line.separator");
public enum Priority {
LOW, MED, HIGH
};
public enum Status {
NOTDONE, DONE
};
public final static String TITLE = "title";
public final static String PRIORITY = "priority";
public final static String STATUS = "status";
public final static String DATE = "date";
public final static String FILENAME = "filename";
public final static SimpleDateFormat FORMAT = new SimpleDateFormat(
"dd/MM/yyyy HH:mm:ss", Locale.US);
private String mTitle = new String();
private Priority mPriority = Priority.LOW;
private Status mStatus = Status.NOTDONE;
private Date mDate = new Date();
ToDoItem(String title, Priority priority, Status status, Date date) {
this.mTitle = title;
this.mPriority = priority;
this.mStatus = status;
this.mDate = date;
}
// Create a new ToDoItem from data packaged in an Intent
ToDoItem(Intent intent) {
mTitle = intent.getStringExtra(ToDoItem.TITLE);
mPriority = Priority.valueOf(intent.getStringExtra(ToDoItem.PRIORITY));
mStatus = Status.valueOf(intent.getStringExtra(ToDoItem.STATUS));
try {
mDate = ToDoItem.FORMAT.parse(intent.getStringExtra(ToDoItem.DATE));
} catch (ParseException e) {
mDate = new Date();
}
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public Priority getPriority() {
return mPriority;
}
public void setPriority(Priority priority) {
mPriority = priority;
}
public Status getStatus() {
return mStatus;
}
public void setStatus(Status status) {
mStatus = status;
}
public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
// Take a set of String data values and
// package them for transport in an Intent
public static void packageIntent(Intent intent, String title,
Priority priority, Status status, String date) {
intent.putExtra(ToDoItem.TITLE, title);
intent.putExtra(ToDoItem.PRIORITY, priority.toString());
intent.putExtra(ToDoItem.STATUS, status.toString());
intent.putExtra(ToDoItem.DATE, date);
}
public String toString() {
return mTitle + ITEM_SEP + mPriority + ITEM_SEP + mStatus + ITEM_SEP
+ FORMAT.format(mDate);
}
public String toLog() {
return "Title:" + mTitle + ITEM_SEP + "Priority:" + mPriority
+ ITEM_SEP + "Status:" + mStatus + ITEM_SEP + "Date:"
+ FORMAT.format(mDate);
}
}
Oh well, after hours tweaking the
public final static SimpleDateFormat FORMAT = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.US);
method from ToDoItem, I still cannot successfully convert yyyy-MM-dd to dd/MM/yyyy.
First, I´ve tried the obvious, and changed the expression yyyy-MM-dd to dd/MM/yyyy.
After that, all I got after saving the task was today´s date, even though the date inputted on AddToDoActivity is months or years ahead. If I revert back to yyyy-MM-dd, the date shown on the Task List is the same inputted on AddToDoActivity.
Then I tried to change all mentions of dates on every class to match the exact format that I wanted.
That made everything look good on AddToDoActivity, but again, when I transported the date back to ToDoItem, the app just ignored the previously inputted date and showed today´s date again.
Can anyone help me with this one??
Thanks!!
You are calling setDateString with arguments in the order of year, month, day:
setDateString(c.get(Calendar.YEAR), c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
But your method has parameters in the order of day, month, year:
private static void setDateString(int dayOfMonth, int monthOfYear, int year) {
...
}
I also think you made some errors while copying your code into the question, since the setDateString method is duplicated and there is no setTimeString method.
Change:
setDateString(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
to:
setDateString(c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.MONTH), c.get(Calendar.YEAR));
Modify the code as follows in the ToDoListAdapter file getView method
// TODO - Display Time and Date.
// Hint - use ToDoItem.FORMAT.format(toDoItem.getDate()) to get date and time String
final TextView dateView = (TextView) itemLayout.findViewById(R.id.dateView);
dateView.setText(ToDoItem.FORMAT.format(toDoItem.getDate()));
The output will be something similar the the following
Reference:
Completing UI Activity assignment

Multithreading using a Handler doesn't run past first pass

I am trying to run a simple clock in my activity, the purpose of the project is to create a secondary thread to run our clock on and update our main UI thread using a handler. I thought I had it working but I guess I was looking at something wrong. Either way, here is my code
public class MainActivity extends Activity implements Runnable{
/** VARIABLES **/
private LinearLayout currView;
private TextView clock;
private Typeface icelandFace;
private Calendar cal;
// clock time values
private int clockMins;
private int clockHour;
private int timeOfDay; // am/pm
private String currTimeString;
// for alarm clock
boolean startAlarm = false;
private long alarmStartTime = -1;
private final int DESIRED_ALARM_DURATION = 5;
// clock thread handler, to communicate between our main ui and our secondary ui
// - note to self - rather unclear on the explanation for the suppression for the handler
private Handler handler = new Handler();
// runnable variable for the secondary thread to actually run on
private final Runnable clockRunnable = new Runnable(){
public void run(){
updateUI();
}
};
/** OVERRIDDEN CLASS METHODS **/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currView = (LinearLayout) findViewById(R.id.main_activity);
clock = (TextView) findViewById(R.id.clock_view);
clock.setTextSize(clock.getTextSize() * 2);
icelandFace = Typeface.createFromAsset(getAssets(), "font/Iceland-Regular.ttf");
clock.setTypeface(icelandFace);
cal = Calendar.getInstance();
// Create New Thread (to run our clock on)
Thread clockThread = new Thread(){
public void run() {
keepTime();
clockMins = cal.get(Calendar.MINUTE);
clockHour = cal.get(Calendar.HOUR);
timeOfDay = cal.get(Calendar.AM_PM);
// Implement the handler for the thread
// NOTE: recall, Message contains data and is passed to our handler
//Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
// start with hours
String timeString = clockHour + ":";
// add minutes
if(clockMins < 10){
timeString = timeString + "0" + clockMins + " ";
}
else{
timeString = timeString + clockMins + " ";
}
// set time of day
if(timeOfDay == 0){
timeString = timeString + "am";
}
else{
timeString = timeString + "pm";
}
// Optional bundle stuff
//bundle.putString("time_string", timeString);
//message.setData(bundle);
Log.d("Runnable", "Tracking time # " + timeString);
currTimeString = timeString;
handler.post(clockRunnable);
}
private void keepTime(){
clockMins = cal.get(Calendar.MINUTE);
clockHour = cal.get(Calendar.HOUR);
timeOfDay = cal.get(Calendar.AM_PM);
checkAlarm(clockHour, clockMins, timeOfDay);
}
private void checkAlarm(int hour, int min, int timeOfDay){
SharedPreferences alarmPref = getSharedPreferences("alarm_preferences", MODE_PRIVATE);
int alarmHour = alarmPref.getInt("alarm_hour", -1);
int alarmMin = alarmPref.getInt("alarm_min", -1);
int alarmTimeOfDay = alarmPref.getInt("alarm_time_of_day", 0);
boolean alarmOn = alarmPref.getBoolean("alarm_on", true);
if(hour == alarmHour && min == alarmMin && timeOfDay == alarmTimeOfDay && alarmOn == true
&& alarmStartTime != -1){
startAlarm = true;
}
return;
}
};
clockThread.start();
}
//TODO: Setup the alarm via the menu that inflates here
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.alarm, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case R.id.alarm_settings:
startActivity(new Intent(this, AlarmPopup.class));
Toast.makeText(this, "Open Up Alarm Dialog", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void run()
{
while (clockRunnable != null)
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e) { };
handler.post(clockRunnable);
}
}
/** PRIVATE METHODS FOR SIMPLIFICATION **/
private void updateUI(){
if(startAlarm == true){
//AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmStartTime = cal.get(Calendar.SECOND);
currView.setBackgroundColor(Color.RED);
}
else if((cal.get(Calendar.SECOND) - alarmStartTime) > DESIRED_ALARM_DURATION){
alarmStartTime = -1;
startAlarm = false;
currView.setBackgroundColor(Color.WHITE);
}
clock.setText(currTimeString);
}
Obviously I am missing something as far as grasping what is going on, but I can't tell what. Create a background thread, run your processes, pass it through the handler to control the variables, and send those variables through your UI update. I used http://developer.android.com/guide/faq/commontasks.html to gain that understanding.
Instead of making the activity implement Runnable, try this:
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(clockRunnable);
}
};
Timer timer = new Timer();
timer.schedule(task, 0, 1000);
Even though I would use a different approach registering a BroadcastReceiver to receive tick actions from the system (every second).
Regards.

How to implement Android date picker in a fragment

I have implemented a date picker as following.
private void updateDisplay() {
String str_date = "";
if ((Month + 1) >= 10) {
if (Day < 10) {
str_date = Year + "-" + (Month + 1) + "-0" + Day;
} else {
str_date = Year + "-" + (Month + 1) + "-" + Day;
}
} else {
if (Day < 10) {
str_date = Year + "-0" + (Month + 1) + "-0" + Day;
} else {
str_date = Year + "-0" + (Month + 1) + "-" + Day;
}
}
date.setText("" + str_date);
}
protected void onPrepareDialog(int id, Dialog dialog) {
switch (id) {
case DATE_DIALOG_ID:
((DatePickerDialog) dialog).updateDate(Year, Month, Day);
break;
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(viewLoad.getContext(),
mDateSetListener, Year, Month, Day);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
Year = year;
Month = monthOfYear;
Day = dayOfMonth;
updateDisplay();
}
};
Here is my code segment for button.
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnDate:
showDialog(DATE_DIALOG_ID);
break;
This works fine. Now the problem is I need to implement a date picker in a fragment. Can anyone plz explain how to do it.
Edited Code
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
Year = year;
Month = monthOfYear;
Day = dayOfMonth;
updateDisplay();
}
};
Thanx in advance.
Use this CustomDialogFragment that contains use of
TimePicker Dialog fragment
DatePicker Dialog fragment
Simple Dialog Fragment
CustomeDialogFragment Class
public class CustomDialogFragment extends DialogFragment
{
public static final int DATE_PICKER = 1;
public static final int TIME_PICKER = 2;
public static final int DIALOG = 3;
Context mContext;
String mMessage;
boolean finishActivity;
// private Fragment mCurrentFragment;
Activity mActivity;
/**
* this constructor is used for datepicker & Timepicker
*/
public CustomDialogFragment (Fragment fragment ) {
// mCurrentFragment = fragment;
}
public CustomDialogFragment (Activity mActivity ) {
this.mActivity = mActivity;
}
/**
* this constructor is used for simple dialog fragment
*/
public CustomDialogFragment(Context context, String message, final boolean finishActivity) {
mContext = context;
mMessage = message;
this.finishActivity = finishActivity;
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle bundle = new Bundle();
bundle = getArguments();
int id = bundle.getInt("dialog_id");
switch (id) {
case DATE_PICKER:
return new DatePickerDialog(getActivity(),
(OnDateSetListener)mActivity, bundle.getInt("year"),
bundle.getInt("month"), bundle.getInt("day"));
case TIME_PICKER:
return new TimePickerDialog(getActivity(),
(OnTimeSetListener)mActivity,bundle.getInt("hour"),
bundle.getInt("minute"), true);
case DIALOG:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
alertDialogBuilder.setTitle(R.string.app_name);
alertDialogBuilder.setMessage(mMessage);
alertDialogBuilder.setIcon(R.drawable.ic_launcher);
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton(
getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss();
if (finishActivity == true) {
Activity act = (Activity) mContext;
act.finish();
}
}
});
alertDialogBuilder.setNegativeButton(getResources().getString(R.string.cancel_btn_title), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
CustomDialogFragment.this.dismiss();
}
});
return alertDialogBuilder.create();
}
//Define your custom dialog or alert dialog here and return it.
return new Dialog(getActivity());
}
}
& Use date Picker this Way
1) In your Activity Or fragment Implement OnDateSetListener ( after done it will get back result to onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) method)
2) Call DatePicker From Fragment Like this way
CustomDialogFragment dialog = new CustomDialogFragment(YourFragment.this);
Bundle bundle = new Bundle();
bundle.putInt("dialog_id", CustomDialogFragment.DATE_PICKER);
bundle.putInt("year", mYear);
bundle.putInt("month", mMonth);
bundle.putInt("day", mDay);
dialog.setArguments(bundle);
dialog.show(getFragmentManager(), "dialog");
& Call DatePicker From Activity(or FragmentActivity) Like this Way
CustomDialogFragment dialog = new CustomDialogFragment(this);
Bundle bundle = new Bundle();
bundle.putInt("dialog_id", CustomDialogFragment.DATE_PICKER);
bundle.putInt("year", mYear);
bundle.putInt("month", mMonth);
bundle.putInt("day", mDay);
dialog.setArguments(bundle);
dialog.setCancelable(false);
dialog.show(this.getSupportFragmentManager(), "dialog");
& as per Set "dialog_id" u can use TIME_PICKER (for time picker dialog) & DIALOG(for simple dialog)
as per send "dialog_id" according to send data through bundle to CustomDialogFragment.
As my knowledge, cannot use showDialog() in Fragment. It's also deprecated.
Use DialogFragment.
Learn from this tutorial as you need
http://www.kylebeal.com/2011/11/android-datepickerdialog-and-the-dialogfragment/

Categories

Resources