【问题标题】:Send Data from DialogFragment to Fragment将数据从 DialogFragment 发送到 Fragment
【发布时间】:2014-11-04 11:49:38
【问题描述】:

我有一个包含 EditText 的片段,当我单击该 EditText 时,会出现一个 DatePicker 对话框来选择日期。
片段文件

public class FirstFragment extends Fragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        EditText editText = (EditText) view.findViewById(R.id.visitDateFiled);

        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment picker = new DatePickerFragment();
                picker.show(getFragmentManager(), "Date Picker");
            }
        });
        return view;
    }

对话框片段

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

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, day);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());

    }
}

我不知道如何将数据(选定日期)从 DialogFragment 传递到 Fragment 的问题?
我阅读了一些主题,但没有帮助我感到困惑(抱歉再次问这个问题)。

Topic 1 Topic 2

【问题讨论】:

标签: android android-fragments


【解决方案1】:

更新代码


片段文件

public class FirstFragment extends Fragment implements DatePickerDialogFragmentEvents{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        EditText editText = (EditText) view.findViewById(R.id.visitDateFiled);

        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment picker = new DatePickerFragment();
                picker.setDatePickerDialogFragmentEvents(FirstFragment.this); //Changed
                picker.show(getFragmentManager(), "Date Picker");
            }
        });
        return view;
    }

    //This is where you will get selected date value
    @Override
    public void onDateSelected(String date) {
        String selectedDate = date;
    } 
 }

对话框片段

public class DatePickerFragment extends DialogFragment
        implements DatePickerDialog.OnDateSetListener {

    //Interface created for communicating this dialog fragment events to called fragment
    public interface DatePickerDialogFragmentEvents{
       void onDateSelected(String date);
    }

    DatePickerDialogFragmentEvents dpdfe

    public void setDatePickerDialogFragmentEvents(DatePickerDialogFragmentEvents dpdfe){
         this.dpdfe = dpdfe;
    }

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

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, day);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());
        dpdfe.onDateSelected(formattedDate); //Changed
    }
}

所以我在你的 dialogfragment 类中创建了一个名为 DatePickerDialogFragmentEvents 的接口,并在调用者片段中实现了它。在创建dialogfragment实例时从调用方fragment中,使用dialogfragment类的setDatePickerDialogFragmentEvents方法设置Fragment的DatePickerDialogFragmentEvents实例。

【讨论】:

  • 无法解析更改的行picker.setDatePickerDialogFragmentEvents(FirstFragment.this); //Changed。 ??
  • 帮我检查这种方式有效。在那里你必须传递片段“this”的实例......因为它在 setOnClickListener 内部,我作为 FirstFragment.this 传递,就好像我通过这个然后会采用那个 clicklisterner 及其错误。
  • 我已经解决了使用该主题的第二个响应的问题:stackoverflow.com/questions/18579590/…
  • 它正在工作,而不是在 FirstFragment 内的 onClickListner 内定义 DialogFragment picker = new DatePickerFragment();。将其定义为DatePickerFragment picker = new DatePickerFragment(); 然后setDatePickerDialogFragmentEvents 无法解决错误将消失。
【解决方案2】:

感谢this topic,主题的第二个回复,我已经解决了这个问题。
DatePickerFragment.java

@Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, day);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String formattedDate = sdf.format(c.getTime());
        // in this part I stored the selected date into the intent
        Intent i = new Intent();
        i.putExtra("selectedDate",formattedDate);
        getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i);
    }

片段文件

public static final int DATEPICKER_FRAGMENT=1; // adding this line
@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_feeding, container, false);
    EditText editText = (EditText) view.findViewById(R.id.foodDeliveryDateFiled);

    editText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            DialogFragment picker = new DatePickerFragment();
            picker.setTargetFragment(FeedingFragment.this, DATEPICKER_FRAGMENT);
            picker.show(getFragmentManager().beginTransaction(), "Date Picker");
        }
    });
    return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
        case DATEPICKER_FRAGMENT:
            if (resultCode == Activity.RESULT_OK) {
                // here the part where I get my selected date from the saved variable in the intent and the displaying it.
                Bundle bundle=data.getExtras();
                String resultDate = bundle.getString("selectedDate","error");
                EditText editText = (EditText) getView().findViewById(R.id.foodDeliveryDateFiled);
                editText.setText(resultDate);
            }
            break;
    }

【讨论】:

    【解决方案3】:

    每个 Java 程序员的第一反应都是创建一个 observable 或回调并将其发送出去。虽然这在大多数地方都是可以接受的做法,但在使用 Fragments 和 DialogFragments 时,由于重新创建、旋转、暂停时的状态丢失......你一定会收到你没想到的 IllegalStateExceptions。

    我的建议虽然有点激进,但会将您的通信模式从一系列接口回调转移到像 Otto 或 GreenRobot 那样的集中式事件总线。对于任何给定的状态,它在前台和后台都非常有效,并有助于解耦使用。

    【讨论】:

      【解决方案4】:

      使用 ViewModel 是最好的解决方案

      class ItemViewModel : ViewModel() {
              private val mutableSelectedItem = MutableLiveData<Item>()
              val selectedItem: LiveData<Item> get() = mutableSelectedItem
      
          fun selectItem(item: Item) {
              mutableSelectedItem.value = item
          }
      }
      
      class MainActivity : AppCompatActivity() {
          // Using the viewModels() Kotlin property delegate from the activity-ktx
          // artifact to retrieve the ViewModel in the activity scope
          private val viewModel: ItemViewModel by viewModels()
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              viewModel.selectedItem.observe(this, Observer { item ->
                  // Perform an action with the latest item data
              })
          }
      }
      
      class ListFragment : Fragment() {
          // Using the activityViewModels() Kotlin property delegate from the
          // fragment-ktx artifact to retrieve the ViewModel in the activity scope
          private val viewModel: ItemViewModel by activityViewModels()
      
          // Called when the item is clicked
          fun onItemClicked(item: Item) {
              // Set a new item
              viewModel.selectItem(item)
          }
      }
      

      According to Android Documentation

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多