如何在 Fragment 之间传递值

Posted

技术标签:

【中文标题】如何在 Fragment 之间传递值【英文标题】:How to pass values between Fragments 【发布时间】:2013-04-08 19:55:25 【问题描述】:

我只是想构建一个使用片段的简单示例应用程序。我的情况是,我有两个活动,每个活动中有一个片段。第一个片段有一个编辑文本和一个按钮。第二个片段有一个文本视图。当我在edittext中输入名称并单击按钮时,第二个片段中的textview应该显示在第一个片段的edittext中输入的名称。

我能够将值从第一个片段发送到其活动,然后从该活动发送到第二个活动。现在如何在第二个片段中使用这个值?

这是Java代码:

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Fragment_1 extends Fragment

    OnFragmentChangedListener mCallback;

    // Container Activity must implement this interface
    public interface OnFragmentChangedListener 
        public void onButtonClicked(String name);
    

    @Override
    public void onAttach(Activity activity) 
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try 
            mCallback = (OnFragmentChangedListener) activity;
         catch (ClassCastException e) 
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        
    


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
        // TODO Auto-generated method stub

        View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);

        final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
        Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);

        btnSayHi_Fragment.setOnClickListener(new OnClickListener() 

            @Override
            public void onClick(View v) 
                // TODO Auto-generated method stub

                String name = edtxtPersonName_Fragment.getText().toString();

                FragmentManager fm = getFragmentManager();
                Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);

                Activity activity = getActivity();

                if(activity != null)
                
                    Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
                


                if(f2 != null && f2.isInLayout())
                
                    f2.setName(name);
                
                else
                
                    mCallback.onButtonClicked(name);
                
            
        );

        return view;


    


文件 MainActivity.Java

package com.example.fragmentexample;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

import android.view.Choreographer.FrameCallback;
import android.view.Menu;

public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    

    @Override
    public void onButtonClicked(String name) 
        // TODO Auto-generated method stub

        Intent i = new Intent(this, SecondActivity.class);
        i.putExtra("", name);
        startActivity(i);
    


文件 SecondActivity.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Bundle b = getIntent().getExtras();

        Fragment_2 f2 = new Fragment_2();
        f2.setArguments(b);
    

Fragment_2.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment_2 extends Fragment

    View view;
    TextView txtName;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
        // TODO Auto-generated method stub

        view = inflater.inflate(R.layout.fragment_fragment_2, container, false);

            // Exception at this line
        String name = getArguments().getString("message");
        txtName = (TextView) view.findViewById(R.id.txtViewResult);
        txtName.setText(name);

        return view;
    

    @Override
    public void onAttach(Activity activity) 
        // TODO Auto-generated method stub
        super.onAttach(activity);
    

    public void setName(String name)
    
        txtName.setText("Hi " + name);
    


我得到以下异常:

04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.fragmentexample/com.example.fragmentexample.SecondActivity: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713):  at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 21 more

如何从 SecondActivity.java 中的包中获取值到 Fragment_2.Java 文件?

【问题讨论】:

请突出显示您遇到问题的部分 【参考方案1】:

第 1 步:将数据从片段发送到活动

Intent intent = new Intent(getActivity().getBaseContext(),
                           TargetActivity.class);
intent.putExtra("message", message);
getActivity().startActivity(intent);

第 2 步:在 Activity 中接收此数据:

Intent intent = getIntent();
String message = intent.getStringExtra("message");

第 3 步:要将数​​据从一个活动发送到另一个活动,请按照正常方法进行

Intent intent = new Intent(MainActivity.this,
                           TargetActivity.class);
intent.putExtra("message", message);
startActivity(intent);

第 4 步:在活动中接收此数据

  Intent intent = getIntent();
  String message = intent.getStringExtra("message");

第 5 步。:您可以从 Activity 将数据发送到 Fragment,其意图如下:

Bundle bundle = new Bundle();
bundle.putString("message", "From Activity");

// Set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

并在 Fragment 的 onCreateView 方法中接收一个片段:

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

    return inflater.inflate(R.layout.fragment, container, false);

【讨论】:

我尝试了第 5 步,我正在从片段中调用 listactivity,并且在从该活动中选择项目后,我想返回带有所选文件名的片段。但它不起作用,它在 onCreateView 给了我 Nullpointer 异常。请问有什么解决办法吗?这是我的问题***.com/questions/18208771/… 如何在此处放置 POJO? bundle.putString("message", "From Activity"); 有没有人厌恶做这样的事情是多么令人费解 正是埃迪,这不是正确的方法。他们应该使用接口通过容器活动在片段之间进行通信。 关于使用接口进行Fragment之间的通信:developer.android.com/training/basics/fragments/…【参考方案2】:

// 在 Fragment_1.java 中

Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want

Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);

getFragmentManager()
      .beginTransaction()
      .replace(R.id.content, fragment2)
      .commit();

// 在 Fragment_2.java 中

Bundle bundle = this.getArguments();

if(bundle != null)
     // handle your code here.

希望对您有所帮助。

【讨论】:

干净的答案以显示要点。使用putString(或putInt)就是答案! 这会破坏我的第一个片段,导航按钮从第二个到第一个崩溃应用程序【参考方案3】:

如开发者网站所述

您通常希望一个 Fragment 与另一个 Fragment 进行通信,例如根据用户事件更改内容。所有 Fragment 到 Fragment 的通信都是通过关联的 Activity 完成的。两个 Fragment 永远不应该直接通信。

Fragment之间的通信应该通过关联的Activity来完成。

让我们有以下组件:

活动承载片段并允许片段通信

FragmentA第一个将发送数据的片段

FragmentB 第二个片段,它将接收来自 FragmentA

的数据

FragmentA 的实现是:

public class FragmentA extends Fragment 

    DataPassListener mCallback;
    
    public interface DataPassListener
        public void passData(String data);
    

    @Override
    public void onAttach(Context context) 
    
        super.onAttach(context);
        // This makes sure that the host activity has implemented the callback interface
        // If not, it throws an exception
        try 
        
            mCallback = (OnImageClickListener) context;
        
        catch (ClassCastException e) 
        
            throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
        
    
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    
        // Suppose that when a button clicked second FragmentB will be inflated
        // some data on FragmentA will pass FragmentB
        // Button passDataButton = (Button).........
        
        passDataButton.setOnClickListener(new OnClickListener() 
            @Override
            public void onClick(View v) 
                if (view.getId() == R.id.passDataButton) 
                    mCallback.passData("Text to pass FragmentB");
                
            
        );
    

MainActivity 的实现是:

public class MainActivity extends ActionBarActivity implements DataPassListener
    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (findViewById(R.id.container) != null) 
            if (savedInstanceState != null) 
                return;
            
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentA()).commit();
        
    
    
    @Override
    public void passData(String data) 
        FragmentB fragmentB = new FragmentB ();
        Bundle args = new Bundle();
        args.putString(FragmentB.DATA_RECEIVE, data);
        fragmentB .setArguments(args);
        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragmentB )
            .commit();
    

FragmentB 的实现是:

public class FragmentB extends Fragment
    final static String DATA_RECEIVE = "data_receive";
    TextView showReceivedData;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_B, container, false);
        showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
    
    
    @Override
    public void onStart() 
        super.onStart();
        Bundle args = getArguments();
        if (args != null) 
            showReceivedData.setText(args.getString(DATA_RECEIVE));
        
    

我希望这会有所帮助..

【讨论】:

这里的 OnImageClickListener 是什么?以及它如何转换为 DataPassListener 变量? 我发现它是“DataPassListener”。我让它工作,但只是因为每次单击按钮时都会发送数据。当它被发送时,它会替换片段。这意味着列表每次都会更新。因此,不要将项目列表保存在内存中。【参考方案4】:

来自Developers website:

通常您会希望一个 Fragment 与另一个 Fragment 进行通信,例如根据用户事件更改内容。所有 Fragment 到 Fragment 的通信都是通过关联的 Activity 完成的。两个 Fragment 永远不应该直接通信。

您可以借助其 Activity 在片段之间进行通信。你可以使用this approach在activity和fragment之间进行通信。

请同时查看this link。

【讨论】:

您提供的第二个链接显示了片段在同一活动中时如何在片段之间进行通信。当两者都在不同的活动中时,我如何沟通?【参考方案5】:

Fragment 之间传递数据的最新解决方案可以通过使用 ViewModel 和 LiveData 等 Android 架构组件来实现。使用此方案,您无需为通信定义接口,并且可以通过配置更改获得使用视图模型的优势,例如数据生存。

在此解决方案中,参与通信的片段共享同一个视图模型对象,该对象与其活动生命周期相关联。视图模型对象包含 livedata 对象。一个片段设置要在 livedata 对象上传递的数据,第二个片段观察者 livedata 更改并接收数据。

这里是完整的例子:Passing data between Android fragments using ViewModel

【讨论】:

【参考方案6】:

首先,所有答案都是正确的。您可以使用Intent传递除自定义对象以外的数据。

如果你想传递自定义对象,你必须实现SerialazableParcelable 到你的自定义对象类。我认为它太复杂了......

因此,如果您的项目很简单,请尝试使用DataCache。这为传递数据提供了一种超级简单的方法。 参考: GitHub project CachePot

1- 将此设置为将发送数据的 View 或 Activity 或 Fragment

DataCache.getInstance().push(obj);

2-在任何地方获取数据,如下所示

public class MainFragment extends Fragment

    private YourObject obj;

    @Override
    public void onCreate(Bundle savedInstanceState)
    
        super.onCreate(savedInstanceState);

        obj = DataCache.getInstance().pop(YourObject.class);

     //end onCreate()
 //end class MainFragment

【讨论】:

使用一个带有静态值的额外类不是更容易吗?然后两个片段都可以访问这些值,因此无需使用额外的库来缓存自定义对象。【参考方案7】:

Kotlin 方式

使用official ViewModel documentation建议的SharedViewModel

一个活动中的两个或多个片段需要 相互交流。想象一个常见的主从案例 片段,您有一个片段,用户在其中选择一个项目 从一个列表和另一个显示 选定的项目。这种情况绝非易事,因为两个片段都需要 定义一些接口描述,并且必须绑定所有者活动 两者在一起。此外,两个片段都必须处理场景 另一个片段尚未创建或可见。

这个常见的痛点可以通过使用 ViewModel 对象来解决。 这些片段可以使用它们的活动范围共享一个 ViewModel 处理此通信

首先实现fragment-ktx 以更轻松地实例化您的视图模型

dependencies 
    implementation "androidx.fragment:fragment-ktx:1.2.2"

然后,您只需将要与其他片段共享的数据放入视图模型中:

class SharedViewModel : ViewModel() 
    val selected = MutableLiveData<Item>()

    fun select(item: Item) 
        selected.value = item
    

然后,最后,只需在每个片段中实例化您的 viewModel,并从您要设置数据的片段中设置 selected 的值

片段 A

class MasterFragment : Fragment() 

    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener  item ->
        model.select(item)
      

    

然后,只需在 Fragment 目的地监听此值

片段 B

 class DetailFragment : Fragment() 

        private val model: SharedViewModel by activityViewModels()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item>  item ->
                // Update the UI
            )
        
    

你也可以反其道而行之

【讨论】:

它说 Unresolved reference: itemSelector 这是您单击以将数据传递给另一个视图的视图,您应该将其替换为当前代码【参考方案8】:

特别是现在 Android 团队正在更加努力地坚持单一的活动模型,片段之间的通信变得更加重要。 LiveData 和 Interfaces 是解决这个问题的完美方法。但现在谷歌终于解决了这个问题,并尝试使用 FragmentManager 带来更简单的解决方案。以下是在 Kotlin 中的实现方式。

在接收者片段中,添加一个监听器:

setFragmentResultListener(
    "data_request_key",
    lifecycleOwner,
    FragmentResultListener  requestKey: String, bundle: Bundle ->
        // Unpack the bundle and use data
        val frag1Str = bundle.getString("frag1_data_key")

    )

在发送方片段(frag1)中:

setFragmentResult(
    "data_request_key",
    bundleOf("frag1_data_key" to value)
)

请记住,此功能仅在 fragment-ktx 版本 1.3.0-alpha04 及更高版本中可用。

学分和进一步阅读:

A New Way to Pass Data Between Fragments

Android Fragments: Fragment Result

【讨论】:

【参考方案9】:

在片段之间传递参数。 回答这个问题已经相当晚了,但它可以帮助某人! Fragment_1.java

Bundle i = new Bundle(); 
            i.putString("name", "Emmanuel");

            Fragment_1 frag = new Fragment_1();
            frag.setArguments(i);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame
                            , new Fragment_2())
                    .commit();

然后在您的 Fragment_2.java 中,您可以在您的onActivityCreated 中正常获取参数 例如

 Intent intent = getActivity().getIntent();
    if (intent.getExtras() != null) 
        String name =intent.getStringExtra("name");
    

【讨论】:

【参考方案10】:

我认为解决这个问题的一个好方法是使用自定义界面。

假设您有两个片段(A 和 B),它们位于同一个 Activity 中,并且您希望将数据从 A 发送到 B。

界面:

public interface OnDataSentListener
    void onDataSent(Object data);

活动:

    public class MyActivity extends AppCompatActivity

            private OnDataSentListener onDataSentListener;

            @Override
            protected void onCreate(Bundle savedInstanceState) 
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_activity);

                FragmentTransaction trans = getFragmentManager().beginTransaction();

                FragmentA fa = new FragmentA();
                FragmentB fb = new FragmentB();

               fa.setOnDataSentListener(new Listeners.OnDataSentListener() 
                    @Override
                    public void onDataSent(Object data) 
                         if(onDataSentListener != null)  onDataSentListener.onDataSent(data);
                    
               );

                transaction.add(R.id.frame_a, fa);
                transaction.add(R.id.frame_b, fb);

                transaction.commit();
            

            public void setOnDataSentListener(OnDataSentListener listener)
                this.onDataSentListener = listener;
            
        

片段 A:

public class FragmentA extends Fragment

    private OnDataSentListener onDataSentListener;

    private void sendDataToFragmentB(Object data)
        if(onDataSentListener != null) onDataSentListener.onDataSent(data);
    

    public void setOnDataSentListener(OnDataSentListener listener)
        this.onDataSentListener = listener;
    

片段 B:

public class FragmentB extends Fragment

    private void initReceiver()
        ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() 
            @Override
            public void onDataSent(Object data) 
                // Here you receive the data from fragment A
            
        );
    

【讨论】:

【参考方案11】:

将数据从 Fragment 传递到另一个 Fragment

从第一个片段开始

// Set data to pass
MyFragment fragment = new MyFragment(); //Your Fragment
Bundle bundle = new Bundle();
bundle.putInt("year", 2017)  // Key, value
fragment.setArguments(bundle); 
// Pass data to other Fragment
getFragmentManager()
 .beginTransaction()
 .replace(R.id.content, fragment)
 .commit(); 

第二个片段

@Override
public void onCreate(@Nullable Bundle savedInstanceState) 
     super.onCreate(savedInstanceState);

     Bundle bundle = this.getArguments();
     if (bundle != null) 
         Int receivedYear = bundle.getInt("year", ""); // Key, default value
      

【讨论】:

【参考方案12】:

片段之间的通信相当复杂(我发现侦听器的概念很难实现)。

通常使用“事件总线”来抽象这些通信。这是一个第三方库,可以为您处理这种通信。

'Otto' 经常被用来做这件事,可能值得研究一下:http://square.github.io/otto/

【讨论】:

【参考方案13】:

这个简单的实现有助于以简单的方式在片段之间传递数据。 认为您想将数据从“Frgment1”传递到“Fragment2”

在 Fragment1 中(设置要发送的数据)

 Bundle bundle = new Bundle();
 bundle.putString("key","Jhon Doe"); // set your parameteres

 Fragment2 nextFragment = new Fragment2();
 nextFragment.setArguments(bundle);

 FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
 fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();

在 Fragment2 的 onCreateView 方法中(获取参数)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost

【讨论】:

在我的应用程序中,我试图让它工作,但不知何故,虽然值正在传递,但它没有显示在 fragment2 上,我认为我在设置 R.id.content_drawer 时犯了错误。有人可以用 .xml 示例指导我什么是 R.id.content_drawer 的正确标识符。【参考方案14】:

您可以通过 ViewModelLive Data 实现您的目标,这已被清除 by Arnav Rao。现在我举一个例子来更清楚地清除它。

首先,假定的ViewModel 被命名为SharedViewModel.java

public class SharedViewModel extends ViewModel 
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) 
        selected.setValue(item);
    
    public LiveData<Item> getSelected() 
        return selected;
    

那么源片段就是我们要发送数据的MasterFragment.java

public class MasterFragment extends Fragment 
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) 
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> 

            // Data is sent

            model.select(item);
        );
    

最后,目标片段是我们想要接收数据的DetailFragment.java

public class DetailFragment extends Fragment 

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) 
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(),  item ->

           // Data is received

        );
    

【讨论】:

【参考方案15】:

您可以使用几种方法来实现相同的目的:

    一种方法是在您的父 Activity 中实现一个接口,以便 Fragment1 可以通过调用这些接口方法将信息传递给它的父 Activity。类似地,您可以让 fragment2 实现一个接口,以便父 Activity 可以将数据发送到 Fragment2。

    另一种更简单的方法是在彼此之间直接调用方法。从 fragment1 中,您可以使用框架 API 获取其父 Activity,然后通过在父 Activity 中定义您的辅助方法,您可以直接从 Fragment1 调用该方法并将您的信息传递给父 Activity。同样,在父活动中,您可以使用框架 API 来获取对其任何子片段的引用,在您的情况下是片段 2。然后,您可以在 fragment2 中定义自己的辅助方法,以便您可以从父 Activity 调用相同的方法并将信息传递给 Fragment2。

【讨论】:

【参考方案16】:

在您的第一个片段中,输入这段代码:

editprofile.setOnClickListener(new View.OnClickListener() 
    @Override
    public void onClick(View v) 

        Fragment_editprofile Fragment = new Fragment_editprofile();
            .
            .
            .
        Fragment.getintentdetails(tv_name.getText().toString(),
            tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
            tv_gender.getText().toString(), photointent);

    
);

第二个片段中,创建如下方法:

public void getintentdetails(String name, String mobile, String email, String dob,
                             String gender, String photointent) 

    this.name_str = name;
    this.mob_str = mobile;
    this.email_str = email;
    this.dob_str = dob;
    this.gender_str = gender;
    this.photo_str = photointent;

然后在类级别定义一个变量:

String name_str, mob_str, dob_str, photo_str, email_str, gender_str;

然后在第二个片段中另做一个方法来设置一个值:

setexistingdetails();

private void setexistingdetails() 

    if(!name_str.equalsIgnoreCase(""))
        (et_name).setText(name_str);
    if(!mob_str.equalsIgnoreCase(""))
        et_mobile.setText(mob_str);
    if(!email_str.equalsIgnoreCase(""))
        email_et.setText(email_str);
    if(!dob_str.equalsIgnoreCase(""))
        dob_et.setText(dob_str);
    if(!gender_str.equalsIgnoreCase("")) 
        if (gender_str.equalsIgnoreCase("m"))
            male_radio.setChecked(true);
        
        else 
            female_radio.setChecked(true);
        
    
    if(!photo_str.equalsIgnoreCase("")) 
        try 
            Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
        
        catch (Exception e) 
        
    

【讨论】:

【参考方案17】:
Bundle bundle = new Bundle();
bundle.putString("mykey","abc"); 
bundle.putString("mykey2","abc"); // Put anything what you want

Fragment fragment = new Fragment();
fragment2.setArguments(bundle);

getFragmentManager()
  .beginTransaction()
  .replace(R.id.content, fragment2)
  .commit();

Bundle bundle = this.getArguments(); // in your fragment oncreate

if(bundle != null)
  String mykey = bundle.getString("mykey");
  String mykey2 = bundle.getString("mykey2");
  

【讨论】:

【参考方案18】:

我已经为像我这样的初学者做了一些非常简单的事情。我在我的 activity_main.xml 文件中创建了一个文本视图并放入:

id = index
visibility = invisible

然后我从第一个片段中得到这个文本视图:

index = (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")

然后在第二个片段中我得到了值:

index = (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();

【讨论】:

答案与提出的问题无关

以上是关于如何在 Fragment 之间传递值的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量从 Activity 传递到 Fragment,并将其传回?

Android:Fragment与Activity之间的通信方式简单介绍

如何在活动和片段之间传递对象

Fragment基础----信息传递

将 Fragment 之间的数据传递给 Activity

老式Android中碎片Fragment之间的跳转和数据传递