android-fragments 如何从DialogFragment获取数据到Fragment?

d6kp6zgx  于 2022-11-14  发布在  Android
关注(0)|答案(7)|浏览(205)

想象一下,我有一个 FragmentA,我从这个 * FragmentA * 开始启动DialogFragment *(盒子里有EditText)。我如何才能把EditText中的值恢复到 FragmentA?我试着做一些类似thisthis的东西,但是我没有成功。

zbq4xfa0

zbq4xfa01#

Fragment.onActivityResult()方法在这种情况下很有用。它接受getTargetRequestCode(),这是您在片段之间设置的代码,以便能够识别它们。此外,它还接受一个请求代码,如果代码运行良好,通常只接受0,然后是Intent,您也可以附加一个字符串,如下所示

Intent intent = new Intent();
intent.putExtra("STRING_RESULT", str);

此外,应该在发送结果的片段中使用setTargetFragment(Fragment, requestCode)来标识它。总的来说,在请求片段中的代码看起来如下:

FragmentManager fm = getActivity().getSupportFragmentManager();
DialogFragment dialogFragment = new DialogFragment();
dialogFragment.setTargetFragment(this, REQUEST_CODE);
dialogFragment.show();

发送数据的类(DialogFragment)将使用我们刚刚定义的Fragment来发送数据:

private void sendResult(int REQUEST_CODE) {
    Intent intent = new Intent();
    intent.putStringExtra(EDIT_TEXT_BUNDLE_KEY, editTextString);
    getTargetFragment().onActivityResult(
        getTargetRequestCode(), REQUEST_CODE, intent);
}

为了接收数据,我们在最初启动DialogFragment的Fragment中使用这种类型的类:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Make sure fragment codes match up 
    if (requestCode == DialogFragment.REQUEST_CODE) {
        String editTextString = data.getStringExtra(
            DialogFragment.EDIT_TEXT_BUNDLE_KEY);

此时,您已经从父片段中的DialogFragment得到了来自EditText的字符串,只需在TextChangeListener()匿名类中使用sendResult(int)方法,以便在需要时发送文本。

vbopmzt1

vbopmzt12#

假设你正在上传一些文件到服务器,点击上传按钮后会打开一个对话框,提示你输入标题和可选标签。对话框本身包含两个按钮,分别是取消和继续。
通过使用layout xml文件来制作您希望的UI。
然后创建一个类来扩展DialogFragment. inflate布局并初始化onCreateView()方法中的视图。
在该类中创建一个接口

public interface uploadDialogInterface

   {
       public void senddata(String title, String tag);
   }

    uploadDialogInterface interfaceObj;
    String title="";
    String tag=" ";

重要的是,您需要覆盖onAttach()方法

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    this.context=context;
    interfaceObj= (uploadDialogInterface) getTargetFragment();
}

并在对Button的单击中调用接口方法如

@Override
public void onClick(View v) {
    int id=v.getId();
    if(id== R.id.vB_fud_cancel)
    {
        dismiss();
    }
    else if(id== R.id.vB_fud_upload)
    {
        title=mVideotitle.getText().toString();
        tag=mOptionaltag.getText().toString();
        if(mVideotitle.getText().toString().isEmpty()) {
            Snackbar.make(mVideotitle,"Please enter the video title", Snackbar.LENGTH_SHORT).show();
       }else
        {
            interfaceObj.senddata(title,tag);
            dismiss();

        }
    }
}

并且在从中启动对话框的Fragment或Activity中应包含setTargetFragment属性。

private void callUploadDialog()
{
    UploadDialogFragment fragment = new UploadDialogFragment();
    fragment.setTargetFragment(this, 0);
    FragmentManager manager = getFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_in);
    fragment.show(ft, "UploadDialogFragment");
    fragment.setCancelable(false);
}

最后,您应该实现接口(在对话框片段中声明)并重写方法

@Override
public void senddata(String title,String optionaltag) {
    this.videoTitle=title;
    this.optionalTag=optionaltag;

}

我想这篇文章会对那些第一次使用对话框片段的人有所帮助。我一直在努力寻找解决方案。希望这篇文章能在未来解决一些人的问题。(抱歉语言)

zaqlnxep

zaqlnxep3#

其中一个更好、更简单的方法是使用Android ViewModel。
这有助于更容易地共享数据,而不需要在片段之间发送任何数据。您不仅可以为DialogFragments这样做,也可以为普通的Fragments这样做。
来源:https://developer.android.com/topic/libraries/architecture/viewmodel
这是我所做的

我的视图模型如下所示

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;

public class PlayerViewModel extends ViewModel {
    private final MutableLiveData<Player> selectedPlayer = new MutableLiveData<>();

    public LiveData<Player> getSelectedPlayer() {
        return selectedPlayer;
    }

    public void selectPlayer(Player player) {
        selectedPlayer.setValue(player);
    }
}

在我选择播放器的片段中,我在onCreate方法中使用以下代码绑定ViewModel

playerViewModel = ViewModelProviders.of(getActivity()).get(PlayerViewModel.class);

选择特定的播放器时,请使用以下代码 (您可以使用ArrayAdapter、DialogFragment的选择器或任何您希望显示播放器列表的代码)

playerViewModel = ViewModelProviders.of(getActivity()).get(PlayerViewModel.class);

最后,在需要显示播放器信息的片段中,在onCreate方法中执行以下操作

PlayerViewModel model = ViewModelProviders.of(getActivity()).get(PlayerViewModel.class);
model.getSelectedPlayer().observe(this, new Observer<Player>() {
    @Override
    public void onChanged(@Nullable Player selPlayer) {
        if (selPlayer != null)
            player = selPlayer;
            populateData();
        }
    });
ie3xauqp

ie3xauqp4#

您需要通过回调方法将对话框中的数据发送回Activity,然后让Activity将数据返回给您希望它转到的片段。

public void datFromDialog(String data){
    MyFragment mf = (MyFragment)getFragmentManager().findFragmentById(r.id.frag);

    mf.iWantNewData(data);
}
nr7wwzry

nr7wwzry5#

你想要什么,根据Android开发者...

cgfeq70w

cgfeq70w6#

此方法可确保呼叫片段实作对话方块的onChangeListener。

片段A(调用片段):

MyDialogFragment f = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("data", data);
f.setArguments(args);
// Set the calling fragment for this dialog.
f.setTargetFragment(FragmentA.this, 0);
f.show(getActivity().getSupportFragmentManager(), "MyDialogFragment");

我的对话框片段:

import android.support.v4.app.DialogFragment;

public class MyDialogFragment extends DialogFragment {
    public OnChangeListener onChangeListener;

    interface OnChangeListener{
        void onChange(Data data);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Get the calling fragment and ensure that it implements onChangeListener.
        try {
            onChangeListener = (OnChangeListener) getTargetFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException(
                "The calling Fragment must implement MyDialogFragment.onChangeListener");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        .....
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // Send the data to the calling fragment.
                onChangeListener.onChange(data);
            }
        });
        .....
    }
}
pdkcd3nj

pdkcd3nj7#

不建议使用dialogFragment.setTargetFragment,请参阅:doc
请求结果的片段应该使用FragmentManager.setFragmentResultListener,而不是使用目标片段来传递结果(String,LifecycleOwner,FragmentResultListener)以使用父片段管理器注册具有requestKey的FragmentResultListener。然后,传送结果的片段应调用FragmentManager。setFragmentResult(String,Bundle)。如果需要支持动态请求键,请考虑使用setArguments传递requestKey。
下面是一个简单的实现:

  • 从主机片段调用
val dialog = MockDialog.newInstance(
          "requestKey")

      dialog.show(
          childFragmentManager, MockDialog.TAG
      )
  • 在MockDialog中(它扩展了DialogFragment):
dialog.setPositiveButton(R.string.dialog_yes) { _, _ ->
      parentFragmentManager.setFragmentResult(
          arguments!!.getString(DIALOG_REQUEST_PARAM)!!,// which is "requestKey"
          //add data to bundle
          bundleOf("result" to "any data")
      )
  }
  • 在主机片段上获取结果:
override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          childFragmentManager.setFragmentResultListener(
              "requestKey", this
          ) { requestKey, result ->
              // you data here 
              val data = result.getString("result", null)
          }
      }

基线:您需要传递“requestKey”并将其传递回host-fragment
祝你好运。

相关问题