【问题标题】:Multiple DatePickers in same activity同一活动中的多个日期选择器
【发布时间】:2011-04-13 16:40:11
【问题描述】:

我是 Android 平台的新手,在学习开发过程的同时一直在构建应用程序。

目前,我正在进行一项需要部署 2 个日期选择器的活动。一个是“开始日期”,另一个是“结束日期”。我一直在关注 android 开发者页面上的 DatePicker 教程:http://developer.android.com/resources/tutorials/views/hello-datepicker.html

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

现在我的问题是,当我为第二个日期选择器复制整个过程时,它在模拟器和手机上都显示得很好。但是无论我按哪个按钮选择日期,只有第一个 TextView 被更新,第二个 TextView 一直显示当前日期。

代码如下:

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(" "));


}

/* 当用户在对话框中为开始日期函数“设置”日期时收到的回调 */

 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;
}

}

请告知代码所需的更改。

【问题讨论】:

  • 两个 ID 需要不同。
  • 您不需要制作两个单独的 DatePicker 对话框。看我的回答

标签: android date datepicker picker


【解决方案1】:

我有一个解决方案,它允许无限数量的日期字段而无需添加新的对话框类型。当用户单击其中一个按钮时,我会在启动 DatePickerDialog 之前注册当前正在修改的 TextView 和 Calendar。对话框的 OnDateSetListener 然后更新注册的 TextView 和 Calendar。

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;
        }
    }
}

这种灵活性在应用程序中非常有用,因为您直到运行时才知道需要多少个日期选择器。

【讨论】:

  • 我喜欢这种方法。我需要使用 4 个 DatePickers,而第一个方法似乎工作量太大。
  • 最好的解决方案,很优雅,我喜欢。
【解决方案2】:

您需要制作 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) {
                .....
            }
        };

为它们创建单独的对话框

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;
}

【讨论】:

  • 只有一个问题。是否可以将我的工作代码连同它的 XML 一起添加,这样任何有类似问题的人都可以立即获得解决方案?
  • 你可以在这里看看他们如何使用 setCallBack 方法来传递回调函数 - androidtrainningcenter.blogspot.com/2012/10/…
【解决方案3】:

将 Adam 的选项扩展为更轻量级的解释并可能更有用,我决定为实例化对话请求的元素 ID 维护一个 int 引用,然后在最终事件处理程序中引用它。如果您有多个日期输入但想要每个或每个组的特定格式,这具有很好地适应此方法中的 switch 语句的额外好处。下面所有的 sn-ps 都直接在我的 Activity 类中

实例变量

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);
    }
};

日期选择处理程序

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;
        }
    }
};

【讨论】:

    【解决方案4】:

    我想我找到了更清洁的解决方案。这是谷歌建议的内容和我在这里读到的 cmets 的混合体。 就我而言,它甚至可以在从 Viewpager 的片段中调用时工作。 基本上,当从我的片段调用选择器对话框时,我将一组参数传递给对话框片段,如下定义:Android: Pass data(extras) to a fragment 然后我在 DialogFragment 类中取回 bundle 值,并打开它的值。

    这是我的 startDate 和 endDate 按钮的两个侦听器,来自我的片段代码:

        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(" "));
            }
        }
    }
    

    【讨论】:

    • 这正是我正在寻找的。谢谢。
    【解决方案5】:

    只需像这样在 mainActivity 中创建布尔变量 ::

    private boolean startDateOrEndDAte = true;
    

    然后像这样为按钮创建侦听器,并为 evrey 按钮更改变量的值::

    DialogFragment datePicker = new DatePickerFragment();
    
    attendDate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    datePicker.show(getSupportFragmentManager(),"Date Picker");
                    startOrEnd = true ;
                }
            });
            leaveDate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    datePicker.show(getSupportFragmentManager(),"Date Picker");
                    startOrEnd = false ;
                }
            });
    

    然后在 onDateSet 方法中添加这样的 if 语句 ::

    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().format(c.getTime());
        attendDate = findViewById(R.id.attend_date);
        leaveDate = findViewById(R.id.leave_date);
    
        if (startOrEnd) {
            attendDate.setText(date);
        } else {
            leaveDate.setText(date);
        }
    }
    

    【讨论】:

      【解决方案6】:

      你可以简单地使用这种类型

      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;
                  }
              }
      
      
      }
      

      【讨论】:

        【解决方案7】:

        我使用 DialogFragment 标签来区分我的活动中的 DatePickerFragment 实例。它运作良好并且使事情变得简单。通过这种方式,您可以重用相同的 DatePickerFragment 类,并在您的活动中拥有大量实例,并由每个实例使用的唯一标签分开。

        根据 Android Dev 文档,DatePickerFragment 类是直接的,它带有一个 Activity 必须实现的附加接口。这允许 DatePickerFragment 回调活动,传递一个 Date 对象并返回标识标签。

        Android Pickers

        public class DatePickerFragment extends DialogFragment
          implements DatePickerDialog.OnDateSetListener {
        
          public interface DatePickerWithTagListener {
            public void onDateSet(String tag, Date date);
          }
        
          private static final String ARG_YEAR = "paramYear";
          private static final String ARG_MONTH = "paramMonth";
          private static final String ARG_DAY = "paramDay";
        
          private int mParamYear;
          private int mParamMonth;
          private int mParamDay;
        
          private Activity mActivity;
          private DatePickerFragment.DatePickerWithTagListener mListener;
        
          public DatePickerFragment() {
            // Required empty public constructor
          }
        
          /**
           * Use this factory method to create a new instance of
           * this fragment using the provided parameters.
           *
           * @param paramYear Year parameter.
           * @param paramMonth Month parameter.
           * @param paramDay Day parameter.
           * @return A new instance of fragment DatePickerFragment.
           */
          public static DatePickerFragment newInstance(int paramYear, int paramMonth, int paramDay) {
            DatePickerFragment fragment = new DatePickerFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_YEAR, paramYear);
            args.putInt(ARG_MONTH, paramMonth);
            args.putInt(ARG_DAY, paramDay);
            fragment.setArguments(args);
            return fragment;
          }
        
          @Override
          public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
              mParamYear = getArguments().getInt(ARG_YEAR);
              mParamMonth = getArguments().getInt(ARG_MONTH);
              mParamDay = getArguments().getInt(ARG_DAY);
            }
          }
        
          @Override
          public void onAttach(@NonNull Context context) {
            super.onAttach(context);
            mActivity = (Activity) context;
        
            try {
              mListener = (DatePickerFragment.DatePickerWithTagListener) mActivity;
            } catch (ClassCastException e) {
              throw new ClassCastException(mActivity.getClass().getName() + " must implement DatePickerWithTagListener");
            }
          }
        
          @NonNull
          @Override
          public DatePickerDialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            // Create a new instance of DatePickerDialog and return it
            return new DatePickerDialog(mActivity, R.style.MyAlertDialog, this, mParamYear, mParamMonth, mParamDay);
          }
        
          /**
           * @param view       the picker associated with the dialog
           * @param year       the selected year
           * @param month      the selected month (0-11 for compatibility with
           *                   {@link Calendar#MONTH})
           * @param dayOfMonth the selected day of the month (1-31, depending on
           */
          @Override
          public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
            Date date = null;
            Calendar cal = Calendar.getInstance();
        
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.MONTH, month);
            cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            date = cal.getTime();
        
            mListener.onDateSet(this.getTag(), date);
          }
        }
        

        您的活动需要实现 DatePickerFragment.DatePickerWithTagListener。

        public class SelectFilterActivity extends AppCompatActivity
         implements DatePickerFragment.DatePickerWithTagListener {
          private static final String START_DATE_PICKER = "startDatePicker";
          private static final String END_DATE_PICKER = "endDatePicker";
        
        ....
        
        private void setupStartDateClick() {
            binding.startDateTV.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                if (binding.useDateRange.isChecked()) {
                  Calendar cal = Calendar.getInstance();
                  cal.setTime(mFilter.getDateRangeStart());
                  int year = cal.get(Calendar.YEAR);
                  int month = cal.get(Calendar.MONTH);
                  int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
                  DialogFragment newFragment = DatePickerFragment.newInstance(year, month, dayOfMonth);
                  newFragment.show(getSupportFragmentManager(), START_DATE_PICKER);
                }
              }
            });
          }
        
          private void setupEndDateClick() {
            binding.endDateTV.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                if (binding.useDateRange.isChecked()) {
                  Calendar cal = Calendar.getInstance();
                  cal.setTime(mFilter.getDateRangeStart());
                  int year = cal.get(Calendar.YEAR);
                  int month = cal.get(Calendar.MONTH);
                  int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
                  DialogFragment newFragment = DatePickerFragment.newInstance(year, month, dayOfMonth);
                  newFragment.show(getSupportFragmentManager(), END_DATE_PICKER);
                }
              }
            });
          }
        
           
          @Override
          public void onDateSet(String tag, Date date) {
            if (tag.equals(START_DATE_PICKER)) {
              // do whatever you need to with the date returned for the start date picker
            }
            else if (tag.equals(END_DATE_PICKER)) {
              // do whatever you need to with the date returned for the end date picker
            }
          }
        

        【讨论】:

          【解决方案8】:

          我对上述任何解决方案都不满意,所以我自己做了如下:https://gist.github.com/JoachimR/f82b2b371b1ced4a09918c970e045d4f

          import android.app.DatePickerDialog
          import android.app.Dialog
          import android.os.Bundle
          import android.support.v4.app.DialogFragment
          import java.util.*
          
          
          class ChooseDayDialog : DialogFragment() {
          
              companion object {
          
                  private val KEY_INITIAL_TIMESTAMP = "KEY_INITIAL_TIMESTAMP"
                  private val KEY_REQUEST_CODE = "KEY_REQUEST_CODE"
          
                  private val DEFAULT_REQUEST_CODE = 20
          
                  fun createInstance(initialTimestamp: Long,
                                     requestCode: Int = DEFAULT_REQUEST_CODE) =
                          ChooseDayDialog().apply {
                              arguments = Bundle().apply {
                                  putLong(KEY_INITIAL_TIMESTAMP, initialTimestamp)
                                  putInt(KEY_REQUEST_CODE, requestCode)
                              }
                          }
          
              }
          
              interface OnDayChosenListener {
          
                  fun onDayChosen(requestCode: Int, year: Int, month: Int, dayOfMonth: Int)
          
              }
          
              private lateinit var listener: OnDayChosenListener
          
              override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  val activity = activity
                  if (activity is OnDayChosenListener) {
                      listener = activity
                  } else {
                      throw IllegalStateException("Activity must implement OnDayChosenListener")
                  }
              }
          
              override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
                  val timestamp = arguments?.getLong(KEY_INITIAL_TIMESTAMP, -1L) ?: -1L
                  if (timestamp == -1L) {
                      throw IllegalStateException("no initial time given")
                  }
                  val requestCode = arguments?.getInt(KEY_REQUEST_CODE, DEFAULT_REQUEST_CODE)
                          ?: DEFAULT_REQUEST_CODE
          
                  val calendar = Calendar.getInstance().apply {
                      timeInMillis = timestamp
                  }
                  return DatePickerDialog(activity,
                          DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth ->
                              listener.onDayChosen(requestCode, year, month, dayOfMonth)
                          },
                          calendar.get(Calendar.YEAR),
                          calendar.get(Calendar.MONTH),
                          calendar.get(Calendar.DAY_OF_MONTH))
              }
          
          }
          

          【讨论】:

            【解决方案9】:

            我必须为旅行的开始日期和结束日期实施 2 个日期选择器。我使用了一个布尔标志来知道哪个文本视图要填充从日期选择器对话框中选择的日期。下面是代码的可视化表示。

            public class AddTrip extends AppCompatActivity implements DatePickerDialog.OnDateSetListener {
            
                private boolean startOrEnd = true;
                private Button startDateBtn;
                private Button endDateBtn;
                private TextView startDateText;
                private TextView endDateText;
            
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_add_trip);
            
                    initAll();
            
                    startDateBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            showDatePickerDialog();
                            startOrEnd = true;
                        }
                    });
            
                    endDateBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            showDatePickerDialog();
                            startOrEnd = false;
                        }
                    });
                }
            
                public void initAll(){
                    startDateBtn = findViewById(R.id.idstartDateBtn);
                    endDateBtn = findViewById(R.id.idendDateBtn);
                    startDateText = findViewById(R.id.startDateText);
                    endDateText = findViewById(R.id.endDateText);
                }
            
            
                private void showDatePickerDialog() {
                    DatePickerDialog datePickerDialog = new DatePickerDialog(
                            this,
                            this,
                            Calendar.getInstance().get(Calendar.YEAR),
                            Calendar.getInstance().get(Calendar.MONTH),
                            Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
                    datePickerDialog.show();
                }
            
                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    String date = "month/day/year: " + month + "/" + dayOfMonth + "/" + year;
                    if (startOrEnd) {
                        startDateText.setText(date);
                    } else {
                        endDateText.setText(date);
                    }
                }
            }
            
            

            【讨论】:

              【解决方案10】:

              你可以使用下面的代码

              @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;
              

              我希望这是有用的。

              【讨论】:

                【解决方案11】:
                    issue.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Bundle bundle = new Bundle();
                            bundle.putInt("DATE", 1);
                
                            DialogFragment newFragment = new MyDatePickerFragment();
                            newFragment.setArguments(bundle);
                            newFragment.show(getSupportFragmentManager(), "datePicker");
                        }
                    });
                
                    expiry.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Bundle bundle = new Bundle();
                            bundle.putInt("DATE", 2);
                
                            DialogFragment newFragment = new MyDatePickerFragment();
                            newFragment.setArguments(bundle);
                            newFragment.show(getSupportFragmentManager(), "datePicker");
                
                        }
                    });
                
                }
                
                
                @Override
                public void sendInput(String input, int id) {
                    date = input;
                    switch (id) {
                        case 1:
                            issue.setText(date);
                            break;
                        case 2:
                            expiry.setText(date);
                            break;
                    }
                
                
                
                
                public class MyDatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
                
                    static final int ISSUE_DATE = 1;
                    static final int EXPIRY_DATE = 2;
                
                    private int mChosenDate;
                
                    int cur = 0;
                
                
                    @Override
                    public void onDateSet(DatePicker datePicker, int year, int month, int day) {
                
                        String date;
                        if (cur == ISSUE_DATE) {
                            // set selected date into textview
                
                            Log.v("Date Issue", "Date1 : " + new StringBuilder().append(month + 1)
                                    .append("-").append(day).append("-").append(year)
                                    .append(" "));
                            date = day + "/0" + (month + 1) + "/" + year;
                        } else {
                            Log.v("Date expiry", "Date2 : " + new StringBuilder().append(month + 1)
                                    .append("-").append(day).append("-").append(year)
                                    .append(" "));
                            date = day + "/0" + (month + 1) + "/" + year;
                
                        }
                        listenerforActivity.sendInput(date, cur);
                    }
                
                    public interface OnDateSetListenerInterface {
                        void sendInput(String input, int id);
                    }
                
                    public OnDateSetListenerInterface listenerforActivity;
                
                    @Override
                    public void onAttach(Context context) {
                        super.onAttach(context);
                        try {
                            listenerforActivity = (OnDateSetListenerInterface) getActivity();
                        } catch (ClassCastException e) {
                            Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
                        }
                    }
                
                    @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 ISSUE_DATE:
                                cur = ISSUE_DATE;
                                return new DatePickerDialog(getActivity(), this, year, month, day);
                
                            case EXPIRY_DATE:
                                cur = EXPIRY_DATE;
                                return new DatePickerDialog(getActivity(), this, year, month, day);
                
                        }
                        return null;
                    }
                
                
                }
                

                【讨论】:

                  【解决方案12】:

                  我的解决方案是简单地使用开关

                  public class RegisterActivity extends AppCompatActivity implements DatePickerDialog.OnDateSetListener {
                  private TextView mDisplayBirthDay;
                  private TextView mDisplayExpDate;
                  private TextView mDisplayIssueDate;
                  private int sw;
                  
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_register);
                      Toolbar toolbar = findViewById(R.id.toolbar);
                      setSupportActionBar(toolbar);
                      Objects.requireNonNull(getSupportActionBar()).setDisplayShowTitleEnabled(false); // to get rid of the title of the activity
                      Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
                  
                      mDisplayBirthDay = findViewById(R.id.birthDate);
                      findViewById(R.id.birthDate).setOnClickListener(new View.OnClickListener() {
                          @Override
                          public void onClick(View v) {
                              showDatePickerDialog();
                              sw = 0;
                          }
                      });
                      mDisplayExpDate = findViewById(R.id.editText_expire);
                      findViewById(R.id.editText_expire).setOnClickListener(new View.OnClickListener() {
                          @Override
                          public void onClick(View v) {
                              showDatePickerDialog();
                              sw = 1;
                          }
                      });
                      mDisplayIssueDate = findViewById(R.id.editText_issueDate);
                      findViewById(R.id.editText_issueDate).setOnClickListener(new View.OnClickListener() {
                          @Override
                          public void onClick(View v) {
                              showDatePickerDialog();
                              sw = 2;
                          }
                      });
                  }
                  private  void showDatePickerDialog(){
                      DatePickerDialog datePickerDialog = new DatePickerDialog(this,
                              this,
                              Calendar.getInstance().get(Calendar.YEAR),
                              Calendar.getInstance().get(Calendar.MONTH),
                              Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
                      datePickerDialog.show();
                  }
                  
                  @Override
                  public boolean onOptionsItemSelected(MenuItem item) {
                      switch (item.getItemId()) {
                          case R.id.show_registrations:
                              getSupportFragmentManager().beginTransaction().replace(R.id.event_description,
                                      //TODO: pass eventID as intend when clicked on event
                                      EventRegistration.newInstance(69)).commit();
                              break;
                          case R.id.visibility_event:
                  
                              break;
                          case android.R.id.home:
                              onBackPressed(); //handling the "back" button
                              break;
                          default:
                      }
                      return true;
                  }
                  
                  @Override
                  public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                      month = month + 1;  //because January is the month 0
                      String date = dayOfMonth + "/" + month + "/" + year;
                      switch (sw){
                          case 0:
                              mDisplayBirthDay.setText(date);
                              break;
                          case 1:
                              mDisplayExpDate.setText(date);
                              break;
                          case 2:
                              mDisplayIssueDate.setText(date);
                              break;
                          default:
                      }
                  
                  }
                  

                  }

                  【讨论】:

                    【解决方案13】:

                    我通过将标志 id 传递给 DialogFragment 解决了这个问题,然后 onDateSet 使用该标志来相应地设置 textview 数据

                    这是对话框片段的代码部分:

                    public class twodatepickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
                    private int first ;
                    
                    public twodatepickerFragment(int i) {
                        first=i;
                    }
                    
                    @NonNull
                    @Override
                    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
                        int date=c.get( Calendar.DAY_OF_MONTH);
                        int month= c.get( Calendar.MONTH);
                        int year=c.get ( Calendar.YEAR );
                        return new DatePickerDialog(getActivity(),(DatePickerDialog.OnDateSetListener) getActivity (), year, month, date);
                        return new DatePickerDialog(getActivity(),this, year, month, date);
                    }
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        calendar.set(Calendar.YEAR, year);
                        calendar.set(Calendar.MONTH, month);
                        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    
                        Date date = calendar.getTime();
                        TextView textView = findViewById(R.id.date_selected);
                        textView.setText(new SimpleDateFormat("dd-MMMM-yyyy").format(date));
                        if(first==0){
                            TextView tv= getActivity().findViewById(R.id.date_selected);
                            tv.setText(new SimpleDateFormat("dd-MMMM-yyyy").format(date));
                        }else{
                            TextView tv= getActivity().findViewById(R.id.date_selected_2);
                            tv.setText(new SimpleDateFormat("dd-MMMM-yyyy").format(date));
                        }
                    }
                    

                    }

                    这是 MainActivity 的代码,这里 select_date_1 和 select_date_2 是按钮。

                     select_date_2.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                DialogFragment datepicker = new twodatepickerFragment (1);
                                datepicker.show ( getSupportFragmentManager (),"date picker" );
                            }
                        });
                        select_date_1.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                DialogFragment datepicker = new twodatepickerFragment (0);
                                datepicker.show ( getSupportFragmentManager (),"date picker" );
                            }
                        });
                    

                    【讨论】:

                      【解决方案14】:

                      您可以简单地使用布尔标志变量来确定您从中进行调用的视图。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-01-17
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-06-02
                        • 1970-01-01
                        相关资源
                        最近更新 更多