安卓 - 如何从活动传递数据到片段?

9
我需要将数据从Activity传递到Fragment。我知道可以使用Bundle,但是一旦我传递了数据,除非重新调用和创建Fragment,否则无法发送数据。
在我的Activity中,某些内容可能会更改,我需要通知我的Fragment这些更改,而不必重新创建Fragment。

不确定,但可以检查EventBus是否能帮助您。 - Raghunandan
你的活动必须持有片段的引用,如果你有片段的引用,那么你可以调用片段的方法。 - Shubham
您可以使用接口在片段和活动之间传递数据,这可能会有所帮助。请参考以下链接:http://stackoverflow.com/questions/36861211/switching-between-2-fragments-in-the-same-activity-without-refreshing-the-data-s/36867893#36867893 - HourGlass
你正在尝试什么... - Arjun saini
8个回答

17
在你的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秒发送数据。


1
@navid abutorab,请检查一下它是否有帮助。 - pooja
@downvoters- 能否解释一下为什么要点踩?留下评论说明点踩的原因是一个好习惯。 - Aniruddha
@Aniruddha 我同意你的观点。我也尝试了这个答案,它是正确的。 - Nikhil
@Aniruddha 接口需要在 Activity 中吗?还是可以作为独立的类存在? - M A F
1
@MAF 根据您的实现,您可以将其添加到您的 Activity 中或作为独立类。 - pooja

3

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
  }

}

1

实际上,您的问题与以下内容无关:

我需要从活动传递数据到片段。我知道我可以使用bundle,但是一旦我传递了数据,我就不能再发送更多数据而不重新调用和创建fragment。

真正的问题是:

在我的活动中,某些事情可能会发生变化,我需要通知我的片段这些变化,而不必重新创建片段。

我该怎么做?

在这种情况下,我会将片段作为引用存储在活动中,并调用片段内的函数或接口实现。

像这样:

在 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
    }
}

这个界面仅用于测试。


1
主机活动可以通过使用findFragmentById()方法获取Fragment实例,并直接调用片段的公共方法来向片段传递消息。
在你的片段 - MyFragment中,创建一个公共方法。
public void myFragmentDataFromActivity(int passedDataFromActivity) {

// do your stuff

}

在您的活动中传递整数值,比如100:

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

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

myFragment.myFragmentDataFromActivity(100);

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

阅读更多关于此的内容


1

如果要在创建后通知带有一些数据的片段,可以使用某些通信器,或者您始终可以在创建时通过Bundle传递数据...例如:

public interface FragmentCommunicator {

void updateDataToFragment(List<Parcelable> data);

然后在你的片段中实现这个接口,并从活动中调用它,例如:

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

        }`

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


0

在Activity中尝试这个

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指出“不重新创建片段”。 - FlorianT

0

在片段中,您应该将方法声明为公共的以更新新数据。然后,您将通过片段实例调用该方法。例如,在获取新数据时,在您的活动中编写以下内容:

fragmentInstance.publicMethod(newData);

编程愉快!


0
我也遇到了同样的问题,我使用单例类将数据从活动传递到片段(而不进行片段事务或使用接口)。
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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接