如何将数据从 DialogFragment 发送到 Fragment? [英] How to send data from DialogFragment to a Fragment?

查看:36
本文介绍了如何将数据从 DialogFragment 发送到 Fragment?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个片段,它打开一个 Dialogfragment 来获取用户输入(一个字符串和一个整数).我如何将这两件事发送回片段?

I have a fragment that opens a Dialogfragment to get user input (a string, and an integer). How do I send these two things back to the fragment?

这是我的 DialogFragment:

Here is my 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()

I need to send the data after the button click and before getDialog().dismiss()

这里是数据需要发送到的片段:

Here is the fragment that data needs to be sent to:

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 中选择了一个日期,它必须返回月份和年份.

so once the user selects a date in the Dialogfragment, it must return the month and year.

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

Then, the text on the button should change to the month and year specified by user.

推荐答案

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

这是食谱:

  1. 创建interface(即名为MyContract),包含传递数据的方法签名,即methodToPassMyData(... data);.
  2. 确保您的 DialogFragment 满足该契约(这通常意味着实现接口):class MyFragment extends Fragment implements MyContract {....}
  3. 在创建 DialogFragment 时,将您的调用 Fragment 设置为它的 目标片段 通过调用 myDialogFragment.setTargetFragment(this, 0);.这是您稍后将要与之交谈的对象.
  4. 在您的 DialogFragment 中,通过调用 getTargetFragment(); 获取该调用片段并将返回的对象转换为您在步骤 1 中创建的合约接口,执行以下操作:MyContract mHost = (MyContract)getTargetFragment();.转换让我们确保目标对象实现所需的契约,我们可以期待 methodToPassData() 在那里.如果没有,那么您将得到常规的 ClassCastException.这通常不应该发生,除非你做了太多的复制粘贴编码:) 如果你的项目使用外部代码、库或插件等,在这种情况下你应该捕捉异常并告诉用户即插件不兼容而不是让应用崩溃.
  5. 当回传数据的时候,对你之前获得的对象调用methodToPassMyData():((MyContract)getTargetFragment()).methodToPassMyData(data);.如果您的 onAttach() 已经将目标片段转换并分配给一个类变量(即 mHost),那么此代码将只是 mHost.methodToPassMyData(data);.
  6. 瞧.您刚刚成功地将对话框中的数据传递回调用片段.
  1. Create interface (i.e. named MyContract) containing a signature of method for passing the data, i.e. methodToPassMyData(... data);.
  2. Ensure your DialogFragment fullfils that contract (which usually means implementing the interface): class MyFragment extends Fragment implements MyContract {....}
  3. On creation of DialogFragment set your invoking Fragment as its target fragment by calling myDialogFragment.setTargetFragment(this, 0);. This is the object you will be talking to later.
  4. In your DialogFragment, get that invoking fragment by calling getTargetFragment(); and cast returned object to the contract interface you created in step 1, by doing: MyContract mHost = (MyContract)getTargetFragment();. Casting lets us ensure the target object implements the contract needed and we can expect methodToPassData() to be there. If not, then you will get regular ClassCastException. This usually should not happen, unless you are doing too much copy-paste coding :) If your project uses external code, libraries or plugins etc and in such case you should rather catch the exception and tell the user i.e. plugin is not compatible instead of letting the app crash.
  5. When time to send data back comes, call methodToPassMyData() on the object you obtained previously: ((MyContract)getTargetFragment()).methodToPassMyData(data);. If your onAttach() already casts and assigns target fragment to a class variable (i.e. mHost), then this code would be just mHost.methodToPassMyData(data);.
  6. Voilà. You just successfully passed your data from dialog back to invoking fragment.

这篇关于如何将数据从 DialogFragment 发送到 Fragment?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆