【问题标题】:Android - How to pass data from activity to fragment? [duplicate]Android - 如何将数据从活动传递到片段? [复制]
【发布时间】:2017-01-01 09:33:15
【问题描述】:

我需要将数据从活动传递到片段。我知道我可以使用 bundle ,但是一旦我传递了数据,如果不再次调用和创建片段,我就无法发送数据。

在我的活动中,有些事情可能会发生变化,我需要通知我的片段进行这些更改,而无需重新创建片段。

【问题讨论】:

  • 不确定但检查 EventBus 可能对您有帮助
  • 你的activity必须持有fragment的引用,如果你有fragment的引用,那么你可以调用fragment的方法
  • 您可以使用接口在片段和活动之间传递数据,这可能会帮助您stackoverflow.com/questions/36861211/…
  • 你在尝试什么...

标签: android android-fragments android-activity


【解决方案1】:

在您的Activity 中创建一个interface,并通过interface 将您的数据传递给fragment。在 fragment 中实现 interface 以获取数据。

例如

MainActivity.class

public class MainActivity extends AppCompatActivity {

    DataFromActivityToFragment dataFromActivityToFragment;

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

        FragmentA fr = new FragmentA();
        FragmentManager fm = getFragmentManager();
        dataFromActivityToFragment = (DataFromActivityToFragment) fr;
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_place, fr);
        fragmentTransaction.commit();


        final Handler handler = new Handler();

        final Runnable r = new Runnable() {
            public void run() {
                dataFromActivityToFragment.sendData("Hi");
            }
        };

        handler.postDelayed(r, 5000);


    }

    public interface DataFromActivityToFragment {
        void sendData(String data);
    }
}

FragmentA.class

public class FragmentA extends Fragment implements MainActivity.DataFromActivityToFragment {

    TextView text;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.content_main, null);
        text = (TextView) rootView.findViewById(R.id.fragment_text);

        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void sendData(String data) {
        if(data != null)
        text.setText(data);
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/fragment_place"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    </LinearLayout>

</LinearLayout>

content_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fragment_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

在上面的示例中,我使用Runnable 只是在创建fragment 后延迟5 秒发送数据。

【讨论】:

  • @navid abutorab 请检查是否有帮助
  • @downvoters- 介意解释拒绝投票的原因吗?发表评论说明为什么投反对票是一个好习惯。
  • @Aniruddha 我同意你的看法。即使我已经尝试过这个答案,而且它是正确的
  • @Aniruddha 接口需要在Activity中吗?或者它可以是一个独立的类?
  • @MAF 根据您的实现,您可以将其添加到您的活动中或作为独立类。
【解决方案2】:

Fragment 对象和其他对象一样。像 String 一样,您可以调用字符串对象的方法 str.charAt(0) ,str.toUpperCase() 等。只需在片段中创建一个函数,将代码放在那里并调用功能与价值观

Inside Activity {
  fragDemoObject.doWhatYouWant("this is passed as string object to fragment");
}

Inside FragmentDemo{
  void doWhatYouWant(String input){
     System.out.println(input);
    // do what else you want to do with code
  }

}

【讨论】:

    【解决方案3】:

    其实你的问题与:

    我需要将数据从活动传递到 Fragmenet。我知道我可以使用 捆绑,但是我已经传递了数据,没有数据我不能再发送数据了 再次调用和创建片段。

    真正的是这样的:

    在我的活动中,有些事情可能会发生变化,我需要通知我的 从这些更改中提取片段,而无需重新创建片段。

    我该怎么做?

    在这种情况下,我会将片段作为引用存储在 Activity 中,然后我会调用一个函数,即片段内的接口实现。

    类似这样的:

    活动中:

    SomeEventListener myFragment  ;
    
    yourFragmentCreationMethod(){
     if(myFragment == null){
        myFragment  = new MyFragment(maybeParamsHere);
      }
    }
    
    yourNotificationMethod(){
       myFragment .onEventHappent(param);
    }
    
    // declare an interface: - separate file
    public interface SomeEventListener
    {
        void onEventHappent(param);
    }
    
    // implement the interface in Fragment - separate file
    public class MyFragment extends Fragment implements SomeEventListener{
        // add a constructor what you like
    
        public void onEventHappent(param){
               /// ... your update
        }
    }
    

    它只会帮助您进行测试的界面。

    【讨论】:

      【解决方案4】:

      宿主 Activity 可以通过捕获 Fragment实例用findFragmentById(),然后直接调用 片段的公共方法。

      在您的片段 - MyFragment 中,创建一个公共方法

      public void myFragmentDataFromActivity(int passedDataFromActivity) {
      
      // do your stuff
      
      }
      

      在你的活动中传递一个整数值,比如 100:

      通过提供 id/tag/position 使用 getSupportFragmentManager 或 getFragmentManager 获取 MyFragment 实例。然后调用 MyFragment 实例中的公共方法。

      MyFragment myFragment = (MyFragment) getSupportFragmentManager.getFragmentById(id);
      
      myFragment.myFragmentDataFromActivity(100);
      

      您也可以使用getFragmentByTag(tag)getFragments().get(position) 代替getFragmentById(id) 来获取片段实例。

      read more about this

      【讨论】:

        【解决方案5】:

        对于创建后带有一些数据的通知片段,可以使用一些 Communicator 来完成,或者您始终可以在创建时使用捆绑包传递数据... 例如:

        public interface FragmentCommunicator {
        
        void updateDataToFragment(List<Parcelable> data);
        

        } 然后在您的片段中实现此接口并从活动中调用它,例如:`

        Fragment fragment = mSectionsPagerAdapter.getRegisteredFragment(i);
                    if (fragment instanceof FragmentCommunicator) {
                        FragmentCommunicator fragmentCommunicator = (FragmentCommunicator) fragment;
                        fragmentCommunicator.updateDataToFragment(data);
        
                }`
        

        这应该适用于您的情况...

        【讨论】:

          【解决方案6】:

          在活动中试试这个

          fragment=new PdfFragment();
          if (fragment != null) {
              FragmentManager fragmentManager = getFragmentManager();
          
                  Bundle bundle = new Bundle();
                  bundle.putString("pdf", Pdf);
              bundle.putString("flag", "0");
              fragment.setArguments(bundle);
          
              fragmentManager.beginTransaction().replace(R.id.container, fragment).addToBackStack(null).commit();
          }
          

          在片段中

               Pdf = getArguments().getString("pdf");
          

          【讨论】:

          • 您正在重新创建片段。 OP 表示“不重新创建片段”。
          【解决方案7】:

          您应该在片段中将您的方法声明为公开的以更新新数据。然后您将通过片段实例调用该方法。例如,在获取新数据时在 Activity 中写入:

          fragmentInstance.publicMethod(newData);
          

          编码愉快!

          【讨论】:

            【解决方案8】:

            我也遇到过同样的问题,我用单例类 将数据从活动传输到片段(不制作片段 交易或使用接口)

            class DataPersistance {
            
            
                public String getName() {
                    return name;
                }
            
                public void setName(String name) {
                    this.name = name;
                }
            
                public String getPlace() {
                    return place;
                }
            
                public void setPlace(String place) {
                    this.place = place;
                }
            
                public String getType() {
                    return type;
                }
            
                public void setType(String type) {
                    this.type = type;
                }
            
                private String name;
                private String place;
                private String type;
            
                private static final DataPersistance ourInstance = new DataPersistance();
            
                static DataPersistance getInstance() {
                    return ourInstance;
                }
            
                private DataPersistance() {
                }
            }
            

            设置和获取数据

                    DataPersistance.getInstance().setName(mEditText.getText().toString());
                  String name =  DataPersistance.getInstance().getName();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-09-24
              • 2017-06-03
              • 2018-04-23
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多