如何将数据从DialogFragment发送到片段?

2022-08-31 20:42:49

我有一个片段,打开一个以获取用户输入(字符串和整数)。如何将这两个东西发送回片段?Dialogfragment

这是我的DialogFragment:

public class DatePickerFragment extends DialogFragment {
    String Month;
    int Year;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().setTitle(getString(R.string.Date_Picker));
        View v = inflater.inflate(R.layout.date_picker_dialog, container, false);

        Spinner months = (Spinner) v.findViewById(R.id.months_spinner);
        ArrayAdapter<CharSequence> monthadapter = ArrayAdapter.createFromResource(getActivity(),
                R.array.Months, R.layout.picker_row);
              months.setAdapter(monthadapter);
              months.setOnItemSelectedListener(new OnItemSelectedListener(){
                  @Override
                  public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int monthplace, long id) {
                      Month = Integer.toString(monthplace);
                  }
                  public void onNothingSelected(AdapterView<?> parent) {
                    }
              });

        Spinner years = (Spinner) v.findViewById(R.id.years_spinner);
        ArrayAdapter<CharSequence> yearadapter = ArrayAdapter.createFromResource(getActivity(),
             R.array.Years, R.layout.picker_row);
        years.setAdapter(yearadapter);
        years.setOnItemSelectedListener(new OnItemSelectedListener(){
          @Override
          public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int yearplace, long id) {
              if (yearplace == 0){
                  Year = 2012;
              }if (yearplace == 1){
                  Year = 2013;
              }if (yearplace == 2){
                  Year = 2014;
              }
          }
          public void onNothingSelected(AdapterView<?> parent) {}
        });

        Button button = (Button) v.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
           public void onClick(View v) {
               getDialog().dismiss();
            }
        });

        return v;
    }
}

我需要在按钮点击后和之前发送数据getDialog().dismiss()

以下是需要将数据发送到的片段:

public class CalendarFragment extends Fragment {
int Year;
String Month;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int position = getArguments().getInt("position");
    String[] categories = getResources().getStringArray(R.array.categories);
    getActivity().getActionBar().setTitle(categories[position]);
    View v = inflater.inflate(R.layout.calendar_fragment_layout, container, false);    

    final Calendar c = Calendar.getInstance();
    SimpleDateFormat month_date = new SimpleDateFormat("MMMMMMMMM");
    Month = month_date.format(c.getTime());
    Year = c.get(Calendar.YEAR);

    Button button = (Button) v.findViewById(R.id.button);
    button.setText(Month + " "+ Year);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
           new DatePickerFragment().show(getFragmentManager(), "MyProgressDialog");
        }
    });
   return v;
  }
}

因此,一旦用户在 中选择日期,它必须返回月份和年份。Dialogfragment

然后,按钮上的文本应更改为用户指定的月份和年份。


答案 1

注意:除了一个或两个特定于 Android Fragment 的调用之外,这是实现松散耦合组件之间数据交换的通用配方。您可以安全地使用此方法在任何东西之间交换数据,无论是片段,活动,对话框还是应用程序的任何其他元素。


这是食谱:

  1. 创建(即命名)包含用于传递数据的方法的签名,即.interfaceMyContractmethodToPassMyData(... data);
  2. 确保完整地执行该协定(这通常意味着实现接口):DialogFragmentclass MyFragment extends Fragment implements MyContract {....}
  3. 创建 时,通过调用 将调用 设置为其目标片段。这是您稍后将要与之交谈的对象。DialogFragmentFragmentmyDialogFragment.setTargetFragment(this, 0);
  4. 在 中,通过调用并将返回的对象强制转换为您在步骤 1 中创建的协定接口来获取调用片段,方法是执行以下操作:。强制转换让我们确保目标对象实现了所需的协定,我们可以期望在那里。如果没有,那么您将获得 常规 .这通常不应该发生,除非你做了太多的复制粘贴编码:)如果您的项目使用外部代码,库或插件等,在这种情况下,您应该捕获异常并告诉用户.plugin不兼容,而不是让应用程序崩溃。DialogFragmentgetTargetFragment();MyContract mHost = (MyContract)getTargetFragment();methodToPassData()ClassCastException
  5. 当发回数据的时间到来时,调用您之前获取的对象:。如果您已经将目标片段强制转换并分配给类变量(即 ),则此代码将只是 。methodToPassMyData()((MyContract)getTargetFragment()).methodToPassMyData(data);onAttach()mHostmHost.methodToPassMyData(data);
  6. 瞧。您刚刚成功地将数据从对话传递回调用片段。

答案 2

这是不使用任何接口的另一个配方。只是利用 和 在 DialogFragment 和 Fragment 之间传递数据。setTargetFragmentBundle

public static final int DATEPICKER_FRAGMENT = 1; // class variable

1. 调用如下图所示:DialogFragment

// create dialog fragment
DatePickerFragment dialog = new DatePickerFragment();

// optionally pass arguments to the dialog fragment
Bundle args = new Bundle();
args.putString("pickerStyle", "fancy");
dialog.setArguments(args);

// setup link back to use and display
dialog.setTargetFragment(this, DATEPICKER_FRAGMENT);
dialog.show(getFragmentManager().beginTransaction(), "MyProgressDialog")

2. 在 中使用 a 中的 extra 将任何信息传递回目标片段。如果传递字符串和整数,则为以下代码。BundleIntentDialogFragmentButton#onClick()DatePickerFragment

Intent i = new Intent()
        .putExtra("month", getMonthString())
        .putExtra("year", getYearInt());
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i);
dismiss();

3. 使用 的方法来读取值:CalendarFragmentonActivityResult()

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case DATEPICKER_FRAGMENT:
            if (resultCode == Activity.RESULT_OK) {
                Bundle bundle = data.getExtras();
                String mMonth = bundle.getString("month", Month);
                int mYear = bundle.getInt("year");
                Log.i("PICKER", "Got year=" + year + " and month=" + month + ", yay!");
            } else if (resultCode == Activity.RESULT_CANCELED) {
                ...
            }
            break;
    }
}

推荐