多个DatePickers在同一个活动

我对Android平台绝对陌生,并且在了解开发过程的同时一直在构build应用程序。

目前,我正在开展一项活动,我需要部署2个dateselect器。 一个是“开始date”,另一个是“结束date”。 我一直在这里的Android开发者页面上遵循DatePicker教程: http : //developer.android.com/resources/tutorials/views/hello-datepicker.html

对于一个DatePicker,它工作得很好。

现在我的问题是,当我复制第二个dateselect器的整个过程,它显示在模拟器上,以及在手机上。 但是,无论按哪个button来selectdate,只有第一个TextView被更新,第二个TextView会一直显示当前的date。

这里是代码:

package com.datepicker; import java.util.Calendar; import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.TextView; public class datepicker extends Activity { private TextView mDateDisplay; private TextView endDateDisplay; private Button mPickDate; private Button endPickDate; private int mYear; private int mMonth; private int mDay; static final int START_DATE_DIALOG_ID = 0; static final int END_DATE_DIALOG_ID = 0; /** Called when the activity is first created. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /* capture our View elements for the start date function */ mDateDisplay = (TextView) findViewById(R.id.startdateDisplay); mPickDate = (Button) findViewById(R.id.startpickDate); /* add a click listener to the button */ mPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(START_DATE_DIALOG_ID); } }); /* get the current date */ final Calendar c = Calendar.getInstance(); mYear = c.get(Calendar.YEAR); mMonth = c.get(Calendar.MONTH); mDay = c.get(Calendar.DAY_OF_MONTH); /* display the current date (this method is below) */ updateStartDisplay(); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.enddateDisplay); endPickDate = (Button) findViewById(R.id.endpickDate); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(END_DATE_DIALOG_ID); } }); /* get the current date */ final Calendar c1 = Calendar.getInstance(); mYear = c1.get(Calendar.YEAR); mMonth = c1.get(Calendar.MONTH); mDay = c1.get(Calendar.DAY_OF_MONTH); /* display the current date (this method is below) */ updateEndDisplay(); } private void updateEndDisplay() { endDateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-") .append(mDay).append("-") .append(mYear).append(" ")); } private void updateStartDisplay() { mDateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-") .append(mDay).append("-") .append(mYear).append(" ")); } 

/ *当用户在开始datefunction对话框中设置date时收到的回叫* /

  private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mYear = year; mMonth = monthOfYear; mDay = dayOfMonth; updateStartDisplay(); } }; @Override protected Dialog onCreateDialog(int id) { switch (id) { case START_DATE_DIALOG_ID: return new DatePickerDialog(this, mDateSetListener, mYear, mMonth, mDay); } return null; } /* the callback received when the user "sets" the date in the dialog for the end date function */ private DatePickerDialog.OnDateSetListener endDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mYear = year; mMonth = monthOfYear; mDay = dayOfMonth; updateStartDisplay(); } }; protected Dialog onCreateDialog1(int id) { switch (id) { case END_DATE_DIALOG_ID: return new DatePickerDialog(this, endDateSetListener, mYear, mMonth, mDay); } return null; } 

}

请告知代码所需的更改。

您需要制作2个单独的DatePicker对话框

让2个听众

 int from_year, from_month, from_day,to_year, to_month, to_day; //initialize them to current date in onStart()/onCreate() DatePickerDialog.OnDateSetListener from_dateListener,to_dateListener; 

实施他们…

  from_dateListener = new OnDateSetListener(){ public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { ... } } }; to_dateListener = new OnDateSetListener(){ public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { ..... } }; 

为他们两个创build分开的对话框

 int DATE_PICKER_TO = 0; int DATE_PICKER_FROM = 1; @Override protected Dialog onCreateDialog(int id) { switch(id){ case DATE_PICKER_FROM: return new DatePickerDialog(this, from_dateListener, from_year, from_month, from_day); case DATE_PICKER_TO: return new DatePickerDialog(this, to_dateListener, to_year, to_month, to_day); } return null; } 

我有一个解决scheme,允许无限数量的date字段,而无需添加新的对话框types。 当用户单击其中一个button时,我将在启动DatePickerDialog之前注册正在修改哪个TextView和Calendar。 对话框的OnDateSetListener然后更新注册的TextView和日历。

 import java.util.Calendar; import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; import android.app.DatePickerDialog.OnDateSetListener; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.TextView; public class MultiDatePickerActivity extends Activity { private TextView startDateDisplay; private TextView endDateDisplay; private Button startPickDate; private Button endPickDate; private Calendar startDate; private Calendar endDate; static final int DATE_DIALOG_ID = 0; private TextView activeDateDisplay; private Calendar activeDate; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.multidatepicker); /* capture our View elements for the start date function */ startDateDisplay = (TextView) findViewById(R.id.startDateDisplay); startPickDate = (Button) findViewById(R.id.startPickDate); /* get the current date */ startDate = Calendar.getInstance(); /* add a click listener to the button */ startPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(startDateDisplay, startDate); } }); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.endDateDisplay); endPickDate = (Button) findViewById(R.id.endPickDate); /* get the current date */ endDate = Calendar.getInstance(); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(endDateDisplay, endDate); } }); /* display the current date (this method is below) */ updateDisplay(startDateDisplay, startDate); updateDisplay(endDateDisplay, endDate); } private void updateDisplay(TextView dateDisplay, Calendar date) { dateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(date.get(Calendar.MONTH) + 1).append("-") .append(date.get(Calendar.DAY_OF_MONTH)).append("-") .append(date.get(Calendar.YEAR)).append(" ")); } public void showDateDialog(TextView dateDisplay, Calendar date) { activeDateDisplay = dateDisplay; activeDate = date; showDialog(DATE_DIALOG_ID); } private OnDateSetListener dateSetListener = new OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { activeDate.set(Calendar.YEAR, year); activeDate.set(Calendar.MONTH, monthOfYear); activeDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); updateDisplay(activeDateDisplay, activeDate); unregisterDateDisplay(); } }; private void unregisterDateDisplay() { activeDateDisplay = null; activeDate = null; } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, dateSetListener, activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); } return null; } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DATE_DIALOG_ID: ((DatePickerDialog) dialog).updateDate(activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); break; } } } 

这种灵活性在一个应用程序中很有用,在这个应用程序中,您不知道在运行时需要多lessdateselect器。

将Adam的选项扩展为稍轻一点的权重解释并且可能更有用,我决定维护一个实例化对话框请求的元素ID的int引用,然后在最终的事件处理函数中引用它。 如果您有多个dateinput但希望为每个或每个组select特定的格式,则此方法具有在此方法中很好地适用于switch语句的附加好处。 下面的所有代码片段都直接在我的Activity类中

实例variables

 private static final int DIALOG_DATE_PICKER = 100; private int datePickerInput; 

对话框处理程序

 @Override public Dialog onCreateDialog(int id) { switch(id) { case DIALOG_DATE_PICKER: final Calendar c = Calendar.getInstance(); DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); return dialog; } return null; } 

点击监听器

 private OnClickListener datePickerListener = new OnClickListener() { @Override public void onClick(View v) { datePickerInput = v.getId(); showDialog(DIALOG_DATE_PICKER); } }; 

dateselect处理程序

 private DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { switch( datePickerInput ) { case R.id.datePicker1: ((EditText) findViewById( datePickerInput )) .setText(...); ... break; case R.id.datePicker2: ... break; default: ... break; } } }; 

我想我find了一个更清洁的解决scheme。 这是Google的build议和我在这里阅读的评论之间的混合。 就我而言,它甚至可以在Viewpager的片段中调用。 基本上,当我从片段调用picker对话框时,我将一组parameter passing给对话框片段,如下所示: Android:将数据(extras)传递给片段然后,在DialogFragment类中获取包值,然后打开它的价值。

以下是我的Fragment代码中startDate和endDatebutton的两个监听器:

  mWylStartDate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putInt("DATE",1); DialogFragment newFragment = new DatePickerFragment(); newFragment.setArguments(bundle); newFragment.show(getFragmentManager(), "datePicker"); } }); mWylEndDate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putInt("DATE",2); DialogFragment newFragment = new DatePickerFragment(); newFragment.setArguments(bundle); newFragment.show(getFragmentManager(), "datePicker"); } }); 

这是我的DatePickerFragment类

 public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { static final int START_DATE = 1; static final int END_DATE = 2; private int mChosenDate; int cur = 0; @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); Bundle bundle = this.getArguments(); if(bundle != null){ mChosenDate = bundle.getInt("DATE",1); } switch (mChosenDate) { case START_DATE: cur = START_DATE; return new DatePickerDialog(getActivity(), this, year, month, day); case END_DATE: cur = END_DATE; return new DatePickerDialog(getActivity(), this, year, month, day); } return null; } @Override public void onDateSet(DatePicker datePicker, int year, int month, int day) { if(cur == START_DATE){ // set selected date into textview Log.v("Date Début","Date1 : " + new StringBuilder().append(month + 1) .append("-").append(day).append("-").append(year) .append(" ")); } else{ Log.v("Date fin","Date2 : " + new StringBuilder().append(month + 1) .append("-").append(day).append("-").append(year) .append(" ")); } } 

}

你可以简单地使用这种types

 public class MainActivity extends Activity { private TextView startDateDisplay; private TextView endDateDisplay; private Button startPickDate; private Button endPickDate; private Calendar startDate; private Calendar endDate; static final int DATE_DIALOG_ID = 0; private TextView activeDateDisplay; private Calendar activeDate; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* capture our View elements for the start date function */ startDateDisplay = (TextView) findViewById(R.id.startDateDisplay); startPickDate = (Button) findViewById(R.id.startPickDate); /* get the current date */ startDate = Calendar.getInstance(); /* add a click listener to the button */ startPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(startDateDisplay, startDate); } }); /* capture our View elements for the end date function */ endDateDisplay = (TextView) findViewById(R.id.endDateDisplay); endPickDate = (Button) findViewById(R.id.endPickDate); /* get the current date */ endDate = Calendar.getInstance(); /* add a click listener to the button */ endPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDateDialog(endDateDisplay, endDate); } }); /* display the current date (this method is below) */ updateDisplay(startDateDisplay, startDate); updateDisplay(endDateDisplay, endDate); } private void updateDisplay(TextView dateDisplay, Calendar date) { dateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(date.get(Calendar.MONTH) + 1).append("-") .append(date.get(Calendar.DAY_OF_MONTH)).append("-") .append(date.get(Calendar.YEAR)).append(" ")); } public void showDateDialog(TextView dateDisplay, Calendar date) { activeDateDisplay = dateDisplay; activeDate = date; showDialog(DATE_DIALOG_ID); } private OnDateSetListener dateSetListener = new OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { activeDate.set(Calendar.YEAR, year); activeDate.set(Calendar.MONTH, monthOfYear); activeDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); updateDisplay(activeDateDisplay, activeDate); unregisterDateDisplay(); } }; private void unregisterDateDisplay() { activeDateDisplay = null; activeDate = null; } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, dateSetListener, activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); } return null; } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); switch (id) { case DATE_DIALOG_ID: ((DatePickerDialog) dialog).updateDate(activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH)); break; } } } 

你可以使用下面的代码

 @Override protected Dialog onCreateDialog(int id) { /* * final Dialog d = new Dialog(this); d.set */ switch (id) { case DATE_DIALOG_ID: return new DatePickerDialog(this, android.R.style.Theme_Holo_Light_Dialog_MinWidth, mDateSetListener, cmYear, cmMonth, cmDay); } return null; } private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { cmYear = year; cmMonth = monthOfYear; cmDay = dayOfMonth; updateDisplay(); } }; private void updateDisplay() { String date_check = "" + new StringBuilder() // Month is 0 based so add 1 .append(cmYear).append("-").append(cmMonth + 1) .append("-").append(cmDay).append(" "); } 

你可以在任何一个onclick上调用Dialog

 showDialog(DATE_DIALOG_ID); 

DATE_DIALOG_ID被声明为

 static final int DATE_DIALOG_ID = 0; 

我希望这是有用的。

您可以简单地使用布尔标志variables来确定您正在进行调用的视图。