149

我目前正在制作一个 android 应用程序,我想在活动和片段之间传递一个日期。我的活动有一个按钮,可以打开片段:DatePickerFragment。

在我的活动中,我显示了一个日期,我想用片段对其进行修改。所以我想将日期传递给日期选择器,并将其发送回活动。

我尝试了很多解决方案,但没有一个有效。简单的方法是传递一个参数,但这不能用片段来完成。

4

9 回答 9

230

要将信息传递给片段,请在创建片段时设置参数,稍后您可以在片段的 onCreate 或 onCreateView 方法中检索此参数。

在片段的 newInstance 函数上,添加要发送给它的参数:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

然后在方法的片段内,onCreate或者onCreateView您可以像这样检索参数:

Bundle args = getArguments();
int index = args.getInt("index", 0);

如果您现在想从您的片段与您的活动(发送或不发送数据)进行通信,您需要使用接口。您可以执行此操作的方式在片段之间通信的文档教程中得到了很好的解释。因为所有片段都通过 Activity 相互通信,所以在本教程中,您可以了解如何将数据从实际片段发送到他的 Activity 容器,以在 Activity 上使用这些数据或将其发送到您的 Activity 包含的另一个片段。

文档教程:

http://developer.android.com/training/basics/fragments/communicating.html

于 2013-07-02T22:16:12.973 回答
96

将数据发送ActivityFragment

活动:

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();

分段:

读取片段中的值

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String myValue = this.getArguments().getString("message");
    ...
    ...
    ...
}

但是如果你想将值从 Fragment 发送到 Activity,请阅读 jpardogo 的答案,你必须需要接口,更多信息:与其他 Fragment 通信

于 2014-01-13T23:17:07.707 回答
11

感谢@ρяσѕρєя K 和 Terry ...它对我有很大帮助并且效果很好

从 Activity 你发送数据的意图是:

Bundle bundle = new Bundle(); 
bundle.putString("edttext", "From Activity"); 
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

并在片段 onCreateView 方法中:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

参考: 将数据从活动发送到android中的片段

于 2018-08-14T07:19:33.587 回答
7

对于所有的 Kotlin 开发人员:

这是 Android Studio 提出的将数据发送到 Fragment 的解决方案(= 当您使用 File -> New -> Fragment -> Fragment(Blank) 创建一个空白片段并选中“包含片段工厂方法”时)。

把它放在你的片段中:

class MyFragment: Fragment {

...

    companion object {

            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.apply是在创建对象时设置数据的好技巧,或者正如他们在此处所述:

调用指定的函数 [block] 并以thisvalue 作为接收者并返回thisvalue。

然后在您的 Activity 或 Fragment 中执行以下操作:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

并阅读片段中的参数,例如:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

要将数据“发送”回您的 Activity,只需在 Activity 中定义一个函数并在 Fragment 中执行以下操作:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

享受 Kotlin 的魔力!

于 2019-09-23T11:03:25.030 回答
6

使用库 EventBus 来回传递可能包含您的变量的事件。这是一个很好的解决方案,因为它使您的活动和片段保持松散耦合

https://github.com/greenrobot/EventBus

于 2013-07-02T21:52:38.460 回答
3

将数据从 Activity 发送到由 XML 链接的 Fragments

如果您在 Android Studio 中使用模板之一创建片段,例如 File > New > Fragment > Fragment (List),则片段通过 XML 链接。newInstance 方法在片段中创建,但从未被调用,因此不能用于传递参数。

而是在 Activity 中重写 onAttachFragment 方法

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

然后根据其他答案阅读片段 onCreate 方法中的参数

于 2019-07-25T21:06:50.777 回答
2

在 2021 年回答现在一天片段具有内置的静态方法,这些方法用于在创建片段时传递参数 尝试他们未来的编码器

当您创建一个片段时,它具有以下已定义的静态方法

 public static categoryfrag newInstance(String param1, String param2) {
        categoryfrag fragment = new categoryfrag();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

片段中的 onCreate 方法通过已经定义的代码接收参数

   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       if (getArguments() != null) {
           mParam1 = getArguments().getString(ARG_PARAM1);
           mParam2 = getArguments().getString(ARG_PARAM2);
         //  rr=getArguments().getInt("ky");
           sn1=mParam1;
           sn2=mParam2;
       }
   }

如果您希望其他数据类型修改此内置行或使用 bundle,则下面的代码用于 mostpop 是片段类的名称的活动

Fragment mp=mostpop.newInstance("parameter1","parameter2");
于 2021-11-27T06:14:42.553 回答
0

您可以简单地使用捆绑包实例化您的片段:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
于 2018-04-18T12:43:20.837 回答
-2

类中的公共变量声明是最简单的方法:

在目标类上:

public class MyFragment extends Fragment {
    public MyCallerFragment caller; // Declare the caller var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Do what you want with the vars
        caller.str = "I changed your value!";
        caller.i = 9999;
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

在调用者类上:

public class MyCallerFragment extends Fragment {
    public Integer i; // Declared public var
    public String str; // Declared public var
        ...
            FragmentManager fragmentManager = getParentFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();

            myFragment = new MyFragment();
            myFragment.caller = this;
            transaction.replace(R.id.nav_host_fragment, myFragment)
                    .addToBackStack(null).commit();
        ...
}

如果您想使用主要活动,也很容易:

在主要活动课上:

public class MainActivity extends AppCompatActivity {
    public String str; // Declare public var
    public EditText myEditText; // You can declare public elements too.
                                // Taking care that you have it assigned
                                // correctly.
...
}

在被调用的类上:

public class MyFragment extends Fragment {
    private MainActivity main; // Declare the activity var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Assign the main activity var
        main = (MainActivity) getActivity();

        // Do what you want with the vars
        main.str = "I changed your value!";
        main.myEditText.setText("Wow I can modify the EditText too!");
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

注意:使用事件(onClick、onChanged 等)时要小心,因为您可能处于“战斗”的情况下,其中不止一个分配一个变量。结果将是变量有时不会改变或会神奇地返回到最后一个值。

要获得更多组合,请使用您的创造力。:)

于 2020-10-25T17:59:50.177 回答