i have a switch that opens up a custom dialog. in the method onCheckedChanged() i instanciate the class that represent the dialog and call the method show(). the problem is that the dialog opens up only after the onCheckedChanged() ends. i tried calling show() in the constructor of the dialog's class but the same thing happens.
the dialog is for the user to set time and date for a reminder. in the dialog there are also three buttons "OK" , "Cancel" and "Reset". the thing is that if the user clicks "Cancel" i want to change the switch to "Off", but the dialog opens only after the onCheckedChanged() ends and when i click "Cancel" the dialog is just dismissed and the switch stays "On".
dialog class:
public class DateTimePickerDialog extends Dialog implements OnDateChangedListener, OnTimeChangedListener, View.OnClickListener
{
private Calendar calendar;
private DatePicker datePicker;
private TimePicker timePicker;
private ViewSwitcher viewSwitcher;
private Button btnSwitchToTime;
private Button btnSwitchToDate;
private Button btnOk;
private Button btnReset;
private Button btnCancel;
private boolean reminderFlag;
/**
* Constructor
* @param context
*/
public DateTimePickerDialog(Context context)
{
super(context);
setContentView(R.layout.dialog_datetimepicker);
setTitle(R.string.title_dialog_datetimepicker);
// set the calendar with the current date
calendar = Calendar.getInstance();
calendar.getTime();
// set the reminder flag. this flag is for setting the ToggleButton in the parent activity
reminderFlag = true;
// initialize the date picker and the time picker with current time and date
datePicker = (DatePicker) findViewById(R.id.picker_DatePicker);
timePicker = (TimePicker) findViewById(R.id.picker_TimePicker);
resetDateTime();
// set listener for the time picker
timePicker.setOnTimeChangedListener(this);
// populate the view switcher
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher_DateTimePicker);
// populate and set listeners for all the buttons
btnSwitchToTime = (Button) findViewById(R.id.button_SwitchToTime);
btnSwitchToTime.setOnClickListener(this);
btnSwitchToDate = (Button) findViewById(R.id.button_SwitchToDate);
btnSwitchToDate.setOnClickListener(this);
btnOk = (Button) findViewById(R.id.button_Ok);
btnOk.setOnClickListener(this);
btnReset = (Button) findViewById(R.id.button_Reset);
btnReset.setOnClickListener(this);
btnCancel = (Button) findViewById(R.id.button_Cancel);
btnCancel.setOnClickListener(this);
this.show();
}
@Override
public void onClick(View view)
{
switch(view.getId())
{
case R.id.button_SwitchToTime:
btnSwitchToTime.setEnabled(false);
findViewById(R.id.button_SwitchToDate).setEnabled(true);
viewSwitcher.showNext();
break;
case R.id.button_SwitchToDate:
btnSwitchToDate.setEnabled(false);
findViewById(R.id.button_SwitchToTime).setEnabled(true);
viewSwitcher.showPrevious();
break;
case R.id.button_Cancel:
reminderFlag = false;
dismiss();
break;
case R.id.button_Ok:
dismiss();
break;
case R.id.button_Reset:
resetDateTime();
break;
}
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), hourOfDay, minute);
}
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
{
calendar.set(year, monthOfYear, dayOfMonth, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
}
/**
* Reset DatePicker, TimePicker and the member calendar
*/
public void resetDateTime()
{
calendar = Calendar.getInstance();
calendar.getTime();
datePicker.init(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), this);
//datePicker.updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
timePicker.setCurrentHour(calendar.get(Calendar.HOUR));
timePicker.setCurrentMinute(calendar.get(Calendar.MINUTE));
}
/**
* Get the reminder's time and date
* @return calendar
*/
public Calendar getReminderTimeAndDate()
{
return calendar;
}
public boolean isReminderFlag()
{
return reminderFlag;
}
public void setReminderFlag(boolean reminderFlag)
{
this.reminderFlag = reminderFlag;
}
}
xml of the dialog:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/DateTimePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:padding="5dip" >
<LinearLayout
android:id="@+id/ViewSwitchButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip" >
<Button
android:id="@+id/button_SwitchToDate"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="Set date" />
<Button
android:id="@+id/button_SwitchToTime"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Set time" />
</LinearLayout>
<ViewSwitcher
android:id="@+id/viewSwitcher_DateTimePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/ViewSwitchButtons" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true" >
<DatePicker
android:id="@+id/picker_DatePicker"
android:calendarViewShown="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true" >
<TimePicker
android:id="@+id/picker_TimePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip" />
</LinearLayout>
</ViewSwitcher>
<LinearLayout
android:id="@+id/OkResetCancelButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/viewSwitcher_DateTimePicker"
android:layout_marginBottom="5dip"
android:orientation="horizontal" >
<Button
android:id="@+id/button_Ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Ok" />
<Button
android:id="@+id/button_Reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Reset" />
<Button
android:id="@+id/button_Cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel" />
</LinearLayout>
the activity with the switch button:
public class CreateNewTaskActivity extends Activity
{
public final static String EXTRA_DESCRIPTION = "il.ac.shenkar.remindme.DESCRIPTION";
private Calendar calendar;
private Context context;
private Switch switchReminder;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_new_task);
//getActionBar().setDisplayHomeAsUpEnabled(true);
calendar = Calendar.getInstance();
context = this;
switchReminder = (Switch) findViewById(R.id.switch_reminder);
switchReminder.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
{
showDateTimePickerDialog(buttonView);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_description, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Calls when the user clicks the "Create" button.
* @param view
*/
public void createNewTask(View view)
{
// get the description from the EditText and check if it's valid
EditText editText = (EditText) findViewById(R.id.edit_description);
String description = editText.getText().toString();
if (description.length() == 0)
{
Toast.makeText(CreateNewTaskActivity.this, "You must fill in description!", Toast.LENGTH_LONG).show();
}
else
{
Task newTask = new Task(description, new GregorianCalendar().getTimeInMillis(), false);
TasksDAO tasksDao = TasksDAO.getInstance(this);
tasksDao.addNewTask(newTask);
finish();
}
}
public void backToMainActivity(View view)
{
finish();
}
/**
* Open's up the dialog in which the user sets the date end the time.
* In case the user cancelled the reminder via dialog, the switchReminder
* will be set to "OFF" again.
* @param view - which is the switchReminder
*/
public void showDateTimePickerDialog(CompoundButton view)
{
DateTimePickerDialog dialog = new DateTimePickerDialog(context);
if(dialog.isReminderFlag())
{
calendar = dialog.getReminderTimeAndDate();
view.setChecked(true);
}
else
{
view.setChecked(false);
}
}
}
Make DateTimePickerDialog dialog a class member of the class CreateNewTaskActivity and when you decide to show the dialog, instantiate it. So essentially when the dialog is cancelled, according to the lifecycle of any activity onResume() would be called. in onResume() method of the class CreateNewTaskActivity, first up check if dialog.isReminderFlag() is true or false and check n unchek it accordingly! So your CreateNewTaskActivity class code would be something like below:
public class CreateNewTaskActivity extends Activity
{
public final static String EXTRA_DESCRIPTION = "il.ac.shenkar.remindme.DESCRIPTION";
private Calendar calendar;
private Context context;
private Switch switchReminder;
private DateTimePickerDialog dialog;
@Override
public void onResume(){
if(dialog != null){
if(dialog.isReminderFlag())
{
calendar = dialog.getReminderTimeAndDate();
view.setChecked(true);
}
else
{
view.setChecked(false);
}
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_new_task);
//getActionBar().setDisplayHomeAsUpEnabled(true);
calendar = Calendar.getInstance();
context = this;
switchReminder = (Switch) findViewById(R.id.switch_reminder);
switchReminder.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
{
showDateTimePickerDialog(buttonView);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_description, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Calls when the user clicks the "Create" button.
* @param view
*/
public void createNewTask(View view)
{
// get the description from the EditText and check if it's valid
EditText editText = (EditText) findViewById(R.id.edit_description);
String description = editText.getText().toString();
if (description.length() == 0)
{
Toast.makeText(CreateNewTaskActivity.this, "You must fill in description!", Toast.LENGTH_LONG).show();
}
else
{
Task newTask = new Task(description, new GregorianCalendar().getTimeInMillis(), false);
TasksDAO tasksDao = TasksDAO.getInstance(this);
tasksDao.addNewTask(newTask);
finish();
}
}
public void backToMainActivity(View view)
{
finish();
}
/**
* Open's up the dialog in which the user sets the date end the time.
* In case the user cancelled the reminder via dialog, the switchReminder
* will be set to "OFF" again.
* @param view - which is the switchReminder
*/
public void showDateTimePickerDialog(CompoundButton view)
{
dialog = new DateTimePickerDialog(context);
if(dialog.isReminderFlag())
{
calendar = dialog.getReminderTimeAndDate();
view.setChecked(true);
}
else
{
view.setChecked(false);
}
}
Interface listener:
public interface IDialogListener {
public void changeSwitchState(boolean state);
}
class YourMainActivity implements IDialogListener{
//implement the interface method
public void changeSwitchState(boolean state){
//surround the UI change responsible codes like the one below inside UI thread runnable , activity.runOnUiThread();
switch.setChecked(state);
// if required invaliadate();//
}
}