Android 使用对话框片段从日期选择器获取日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11527051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:55:19  来源:igfitidea点击:

Get date from datepicker using dialogfragment

androiddatepickerandroid-dialogandroid-datepicker

提问by Gonzalo Cao

I'm using the google example to insert a datepicker inside my app using a dialogfragment
http://developer.android.com/guide/topics/ui/controls/pickers.html

我正在使用谷歌示例使用对话框片段在我的应用程序中插入日期选择器
http://developer.android.com/guide/topics/ui/controls/pickers.html

But I'm not sure how to get date after set it (not java expert). Dialog and datepicker runs ok and I can log that date is correctely set but, how can i do to get a callback executed on parent activity?

但我不确定如何在设置后获取日期(不是 Java 专家)。对话框和日期选择器运行正常,我可以记录正确设置的日期,但是,我该怎么做才能在父活动上执行回调?

This is my Dialog fragment

这是我的对话框片段

public 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 year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        **Log.w("DatePicker","Date = " + year);**
    }
}

...and I call dialog from my activity with...

...我从我的活动中调用对话...

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getSupportFragmentManager(), "datePicker");
}

What is the correct way to call a method in my parent activity instead Log.w? I suppose that is something related with passing a callback as parameter or something but most of references I found on internet are about previous versions without dialogfragments

在我的父活动而不是 Log.w 中调用方法的正确方法是什么?我想这与将回调作为参数或其他东西传递有关,但我在互联网上找到的大多数参考资料都是关于没有对话框片段的以前的版本

EDIT: not sure if it's important but parent activity is declared as:

编辑:不确定它是否重要,但父活动被声明为:

public class EditSessionActivity extends FragmentActivity {

SOLUTION: thanks to Lecho user this is the way to do it

解决方案:感谢 Lecho 用户,这是解决问题的方法

DatePickerFragmennt.class

DatePickerFragmennt.class

public class DatePickerFragment extends DialogFragment{

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);
    }

}

...and parent activity EditSessionActivity.class...

...和父活动 EditSessionActivity.class ...

public class EditSessionActivity extends FragmentActivity implements OnDateSetListener {
...
    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        //do some stuff for example write on log and update TextField on activity
        Log.w("DatePicker","Date = " + year);
        ((EditText) findViewById(R.id.tf_date)).setText("Date = " + year);
    }

回答by Leszek

Constructor fo DatePickerDialogtakes DatePickerDialog.OnDateSetListeneras second parameter, so maybe you should implement that interface in your parent activity EditSessionActivity(not in DatePickerFragment) and change this line:

构造函数FODatePickerDialog需要DatePickerDialog.OnDateSetListener作为第二个参数,那么也许你应该实现这个接口在父活动EditSessionActivity(不DatePickerFragment),并改变这一行:

return new DatePickerDialog(getActivity(), this, year, month, day);

into this:

进入这个:

return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);

And then your activity should looks like this:

然后你的活动应该是这样的:

public class EditSessionActivity extends FragmentActivity implements
        DatePickerDialog.OnDateSetListener{

    public void onDateSet(DatePicker view, int year, int month, int day) {
        //use date in your activity
    }
    ...
}

回答by Vinicius Paldês

I simple override onDateSet in date picker creation in my class that shows a date picker. See code below:

我在显示日期选择器的类中的日期选择器创建中简单地覆盖了 onDateSet。见下面的代码:

  private OnClickListener onDateClicked() {
    return new OnClickListener() {
          @Override
          public void onClick(View v) {
             DialogFragment newFragment = new DatePickerFragment() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int day) {
                  salePaymentCustomView.setBtDateText("" + day + "/" + month+1 + "/" + year);
                }
             };
             newFragment.show(getActivity().getSupportFragmentManager(), "datePicker");
    }
  };
 } 

回答by steps

The problem can also be solved without moving the onDateSetmethod to the parent activity. You just have to tell the DatePickerFragmentwhere to search for the view:

也可以在不将onDateSet方法移动到父活动的情况下解决该问题。你只需要告诉在DatePickerFragment哪里搜索视图:

public 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 year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // do some stuff for example write on log and update TextField on activity
        Log.w("DatePicker","Date = " + year);
        ((TextView) getActivity().findViewById(R.id.tf_date)).setText("Date = " + year);
    }
}

I also changed the target of the cast from EditTextto TextView. This way, you can reuse your implementation for different kinds of views, not only for an EditText.

我还将演员的目标从 更改EditTextTextView。这样,您可以对不同类型的视图重复使用您的实现,而不仅仅是EditText.

回答by Benny Margalit

i have one correction to the above answer. instead of return the DatePickerDialog like this

我对上述答案有一个更正。而不是像这样返回 DatePickerDialog

return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);

return new DatePickerDialog(getActivity(), (EditSessionActivity)getActivity(), year, month, day);

you should return it in a more generic way

你应该以更通用的方式返回它

return new DatePickerDialog(getActivity(), (OnDateSetListener)getActivity(), year, month, day);

return new DatePickerDialog(getActivity(), (OnDateSetListener)getActivity(), year, month, day);

just make sure your activity implements OnDateSetListener interface and override the function onDateSet

只需确保您的活动实现 OnDateSetListener 接口并覆盖函数 onDateSet

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) 

回答by Harsh Parikh

public void onDate(View view) {

        DialogFragment fragment = new SelectDateFragment();
        fragment.show(getFragmentManager(), "Date Picker");
    }

//  @SuppressLint("NewApi")
    class SelectDateFragment extends DialogFragment implements
            DatePickerDialog.OnDateSetListener {

        public Dialog onCreateDialog(Bundle savedInstanceState) {


            System.out.println("entrering on create dialog");;

            return new DatePickerDialog(getActivity(), this, mYear, mMonth,
                    mDay);//it will return dialog setting date with mYera,MMonth and MDay

        }

        @Override
        public void onDateSet(android.widget.DatePicker view, int year,
                int monthOfYear, int dayOfMonth) {
            System.out.println("year=" + year + "day=" + dayOfMonth + "month="
                    + monthOfYear);
            mYear=year;
            mMonth=monthOfYear;
            mDay=dayOfMonth;

            onPopulateSet(year, monthOfYear + 1, dayOfMonth);

        }
// set the selected date in the edit text  
        private void onPopulateSet(int year, int i, int dayOfMonth) {
            EditText et_setDate;
            et_setDate = (EditText) findViewById(R.id.register_et_dob);//register_et_dob:-id name of the edit text 
            et_setDate.setText(dayOfMonth + "/" + i + "/" + year);
            System.out.println("enetring on populate Set");

        }

回答by wvdz

Leszek's answer works, but not if the Dialog is started from another Fragment. In that case you need to use setTargetFragment()in the code that creates the dialog and getTargetFragment()in the dialog code.

Leszek 的答案有效,但如果 Dialog 从另一个 Fragment 启动则无效。在这种情况下,您需要setTargetFragment()在创建getTargetFragment()对话框的代码和对话框代码中使用。

In the code that creates the dialog:

在创建对话框的代码中:

DialogFragment dialogFragment = new YourDialogFragment();
dialogFragment.setTargetFragment(YourParentFragment.this, 0);
dialogFragment.show(getFragmentManager(), "mydialog");

In the DialogFragment code:

在 DialogFragment 代码中:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener()
    {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
        {
            YourParentFragment parentFragment = (YourParentFragment) getTargetFragment();
            // Manipulate the parent fragment
            // ...
        }
    };
    // Get the initial date
    // ...
    return new DatePickerDialog(getActivity(), listener, year, month, day);
}

回答by Leo Droidcoder

In case you have to return a result to a Fragment, but not an Activity, here is a complete solution:

如果您必须将结果返回给 Fragment 而不是 Activity,这里有一个完整的解决方案:

public class DatePickerDialogFragment extends DialogFragment  {

    private static final String ARGUMENT_YEAR = "ARGUMENT_YEAR";
    private static final String ARGUMENT_MONTH = "ARGUMENT_MONTH";
    private static final String ARGUMENT_DAY = "ARGUMENT_DAY";
    private DatePickerDialog.OnDateSetListener listener;

    private int year;
    private int month;
    private int dayOfMonth;

    public static DatePickerDialogFragment newInstance(final int year, final int month, final int dayOfMonth) {
        final DatePickerDialogFragment df = new DatePickerDialogFragment();
        final Bundle args = new Bundle();
        args.putInt(ARGUMENT_YEAR, year);
        args.putInt(ARGUMENT_MONTH, month);
        args.putInt(ARGUMENT_DAY, dayOfMonth);
        df.setArguments(args);
        return df;
    }

    @Override
    public void onCreate(@Nullable final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        retrieveArguments();
    }

    private void retrieveArguments() {
        final Bundle args = getArguments();
        if (args != null) {
            year = args.getInt(ARGUMENT_YEAR);
            month = args.getInt(ARGUMENT_MONTH);
            dayOfMonth = args.getInt(ARGUMENT_DAY);
        }
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {
        return new DatePickerDialog(getContext(), this.listener, this.year, this.month, this.dayOfMonth);
    }

    public void setListener(final DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }
}

Then just use it in a Fragment or in an Activity:

然后只需在片段或活动中使用它:

final Calendar c = Calendar.getInstance();
DatePickerDialogFragment datePicker = DatePickerDialogFragment.newInstance(
        c.get(Calendar.YEAR),
        c.get(Calendar.MONTH),
        c.get(Calendar.DAY_OF_MONTH));
datePicker.setListener(this);
datePicker.show(getChildFragmentManager(), null);

回答by Water

Kotlin version.

科特林版。

DatePickerFragment class:

DatePickerFragment 类:

class DatePickerFragment : DialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val day = c.get(Calendar.DAY_OF_MONTH)

        return DatePickerDialog(context!!, context!! as MainActivity, year, month, day)
    }
}

DatePickerDialog.OnDateSetListeneris moved to MainActicity

DatePickerDialog.OnDateSetListener移至 MainActicity

class MainActivity : AppCompatActivity(), DatePickerDialog.OnDateSetListener {

    ..

    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        //use date in your activity
    }
}

回答by Matt

I had a similar problem to this, but my date picker was being launched from a dialog fragment inside another fragment. This made it very difficult to play around with the callbacks, because they want to return to the Main Activity and I wanted the data to go back to the previous dialog fragment.

我有一个类似的问题,但我的日期选择器是从另一个片段内的对话框片段启动的。这使得处理回调变得非常困难,因为它们想返回到主活动,而我希望数据返回到前一个对话框片段。

Initially, I passed the new date values to the Main Activity (using the OnDateSetListener) and was going to get them using the dialog that launched the date picker, but there are no lifecycle events triggered in that dialog when the datepicker closes.

最初,我将新日期值传递给主活动(使用 OnDateSetListener),并打算使用启动日期选择器的对话框获取它们,但是当日期选择器关闭时,该对话框中没有触发生命周期事件。

The result I came to was in onDismiss in the date picker, instantiate a new dialog fragment, call a set results method on it and then launch it. Of course for this you need to make sure that the previous fragment is dismissed when it launches the date picker.

我得到的结果是在日期选择器中的 onDismiss,实例化一个新的对话框片段,在其上调用 set results 方法然后启动它。当然,为此您需要确保在启动日期选择器时取消前一个片段。

This is the dialogFragment that called the date picker

这是调用日期选择器的 dialogFragment

public class NewTrialDialogFragment extends DialogFragment  {

public final String LOG_TAG = "NewTrialDialog Fragment";

Button startDateButton;
Integer newYear, newMonth, newDay;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.dialog_new_trial, container, false);
    getDialog().setTitle("Dialog New Trial");

    startDateButton = (Button) rootView.findViewById(R.id.button_start_date);
    startDateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showDatePickerDialog(v);
        }
    });

    //If you exit the datepicker without choosing anything, it returns zeros
    if (newYear != null && newMonth != null && newDay != null && newYear != 0) {
        startDateButton.setText(newYear + " " + newMonth + " " + newDay);
    }else{
        startDateButton.setText("Select Start Date");
    }

     return rootView;
}

public void showDatePickerDialog(View v) {
    TrialDatePickerDialog newDialog = new TrialDatePickerDialog();
    newDialog.show(getActivity().getSupportFragmentManager(), "datePicker");
    this.dismiss();
}

public void setDates(int year, int month, int day){
    newYear = year;
    newMonth = month;
    newDay = day;
}}

And the date picker

和日期选择器

public  class TrialDatePickerDialog extends DialogFragment implements DatePickerDialog.OnDateSetListener
     {

private final String LOG_TAG = "TrialDatePickerDialog";
int newYear, newMonth, newDay;


@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // Use the current date as the default date in the picker
    final Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);

    // Create a new instance of TrialDatePickerDialog and return it
    return new DatePickerDialog(getActivity(), this , year, month, day);
}

         @Override
         public void onDismiss(DialogInterface dialog) {
             super.onDismiss(dialog);
             FragmentManager fm = getActivity().getSupportFragmentManager();
             NewTrialDialogFragment newTrialDialogFragment = new NewTrialDialogFragment();
             newTrialDialogFragment.setDates(newYear, newMonth, newDay);
             newTrialDialogFragment.show(fm, "new_trial_dialog");

         }

         @Override
         public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
             newYear = year;
             newMonth = monthOfYear;
             newDay = dayOfMonth;
         }
     }