当前位置: 首页 > 知识库问答 >
问题:

两个片段之间的基本通信

狄宇
2023-03-14

我有一个活动- MainActivity。在这个活动中,我有两个片段,这两个片段都是我在xml中以声明方式创建的。

我正在尝试将用户输入的文本的String传递到片段AFragment B

我知道一个片段可以使用getActive()获得对其活动的引用。所以我猜我会从那里开始?

共有3个答案

姬昀
2023-03-14

最好和推荐的方法是使用共享ViewModel。

https://developer . Android . com/topic/libraries/architecture/viewmodel #共享

来自谷歌文档:

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


public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
    itemSelector.setOnClickListener(item -> {
        model.select(item);
    });
}
}


public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
    model.getSelected().observe(this, { item ->
       // Update the UI.
    });
}
}

ps:两个片段从不直接交流

况浩邈
2023-03-14

其他一些示例(甚至是撰写本文时的文档)使用过时的 onAttach html" target="_blank">方法。下面是一个完整的更新示例。

    < li >您不希望片段彼此直接对话或与活动直接对话。这将它们与特定的活动联系在一起,使得重用变得困难。 < li >解决方案是创建一个回调侦听器接口,活动将实现该接口。当片段想要向另一个片段或其父活动发送消息时,它可以通过接口来完成。 < li >活动可以直接与其子片段公共方法通信。 < li >因此,活动充当控制器,将消息从一个片段传递到另一个片段。

主要活动.java

public class MainActivity extends AppCompatActivity implements GreenFragment.OnGreenFragmentListener {

    private static final String BLUE_TAG = "blue";
    private static final String GREEN_TAG = "green";
    BlueFragment mBlueFragment;
    GreenFragment mGreenFragment;

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

        // add fragments
        FragmentManager fragmentManager = getSupportFragmentManager();

        mBlueFragment = (BlueFragment) fragmentManager.findFragmentByTag(BLUE_TAG);
        if (mBlueFragment == null) {
            mBlueFragment = new BlueFragment();
            fragmentManager.beginTransaction().add(R.id.blue_fragment_container, mBlueFragment, BLUE_TAG).commit();
        }

        mGreenFragment = (GreenFragment) fragmentManager.findFragmentByTag(GREEN_TAG);
        if (mGreenFragment == null) {
            mGreenFragment = new GreenFragment();
            fragmentManager.beginTransaction().add(R.id.green_fragment_container, mGreenFragment, GREEN_TAG).commit();
        }
    }

    // The Activity handles receiving a message from one Fragment
    // and passing it on to the other Fragment
    @Override
    public void messageFromGreenFragment(String message) {
        mBlueFragment.youveGotMail(message);
    }
}

GreenFragment.java

public class GreenFragment extends Fragment {

    private OnGreenFragmentListener mCallback;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_green, container, false);

        Button button = v.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = "Hello, Blue! I'm Green.";
                mCallback.messageFromGreenFragment(message);
            }
        });

        return v;
    }

    // This is the interface that the Activity will implement
    // so that this Fragment can communicate with the Activity.
    public interface OnGreenFragmentListener {
        void messageFromGreenFragment(String text);
    }

    // This method insures that the Activity has actually implemented our
    // listener and that it isn't null.
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnGreenFragmentListener) {
            mCallback = (OnGreenFragmentListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnGreenFragmentListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallback = null;
    }
}

BlueFragment.java

public class BlueFragment extends Fragment {

    private TextView mTextView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_blue, container, false);
        mTextView = v.findViewById(R.id.textview);
        return v;
    }

    // This is a public method that the Activity can use to communicate
    // directly with this Fragment
    public void youveGotMail(String message) {
        mTextView.setText(message);
    }
}

activity_main.xml(活动_主.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <!-- Green Fragment container -->
    <FrameLayout
        android:id="@+id/green_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginBottom="16dp" />

    <!-- Blue Fragment container -->
    <FrameLayout
        android:id="@+id/blue_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

fragment_green.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:background="#98e8ba"
              android:padding="8dp"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:text="send message to blue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

碎片_蓝色.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:background="#30c9fb"
              android:padding="16dp"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:text="TextView"
        android:textSize="24sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>
公孙宇
2023-03-14

看看Android开发者页面:http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface

基本上,您在片段A中定义了一个接口,并让您的活动实现该接口。现在,您可以调用片段中的接口方法,并且您的活动将接收该事件。现在,在您的活动中,您可以调用第二个片段来用接收到的值更新textview

您的活动实现了您的接口(参见下面的片段a)

public class YourActivity implements FragmentA.TextClicked{
    @Override
    public void sendText(String text){
        // Get Fragment B
        FraB frag = (FragB)
            getSupportFragmentManager().findFragmentById(R.id.fragment_b);
        frag.updateText(text);
    }
}

片段A定义了一个接口,并在需要时调用该方法

public class FragA extends Fragment{

    TextClicked mCallback;

    public interface TextClicked{
        public void sendText(String text);
    }

    @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 = (TextClicked) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement TextClicked");
        }
    }

    public void someMethod(){
        mCallback.sendText("YOUR TEXT");
    }

    @Override
    public void onDetach() {
        mCallback = null; // => avoid leaking, thanks @Deepscorn
        super.onDetach();
    }
}

片段B有一个公共方法对文本做一些事情

public class FragB extends Fragment{

    public void updateText(String text){
        // Here you have it
    }
}
 类似资料:
  • 问题内容: 方法论问题: 我有一个“主” python脚本,该脚本在系统上无限循环地运行,并且我想偶尔与其他一些python脚本一起向其发送信息(例如,json数据字符串),这些脚本稍后将由本人或另一个程序启动并且将在发送字符串后立即结束。 我不能在这里使用子流程,因为我的主脚本不知道其他脚本何时运行以及它们将执行什么代码。 我正在考虑使主脚本在本地端口上侦听,并使其他脚本在该端口上向它发送字符串

  • 我正试图做到这一点:http://android-er.blogspot.com/2012/06/communication-between-fragments-in.html只不过我用的是一台碎纸机 我有一个有两个片段的活动 FragmentA有一个编辑文本和一个按钮,FragmentB有一个文本视图 现在我想要的是,每当我在编辑文本中输入一些内容并单击按钮时,我的文本视图中就会出现一些内容。

  • 我在viewpager中设置了三个片段,就像滑动选项卡布局一样。我需要将字符串值从一个片段传递到另一个片段。 首先,我试着建立一个接口,就像这里的答案建议如何在片段之间传递数据,这对我不起作用。想法是片段A告诉主活动,然后主活动告诉片段B。 所以我寻找不同的答案 http://android-er.blogspot.com/2012/06/communication-between-fragmen

  • 我的应用程序中有三个片段,其中需要传递和接收数据。我应该如何进行他们之间的沟通。我试图参考许多网站,但没有解决方案。 请给我推荐一些好的链接。 提前感谢。

  • 我有一个包含两个片段的FragmentActivity(support-v4)。并且都包含一个带有ActionBar的SearchView的菜单。 PlayListFragment: 附注。 我找到了原因,但没有解决方法: 呼叫 如何禁用ActionBar/SearchView/TextView的保存和还原?