【问题标题】:Fragment-Fragment communication in AndroidAndroid中的Fragment-Fragment通信
【发布时间】:2013-03-05 01:50:08
【问题描述】:

我在 Android 编程方面处于初级水平,因此我需要您真诚的帮助。请任何人帮助我。

我正在尝试使用片段构建一个滑动 UI

所以我真正的疑问是......我有一个Fragment(比如Fragment A),里面有一个TextViewButton,还有一个Fragment(比如Fragment B)。它有一个TextView。当我在片段A中按下Button时,我需要在Fragment B的TextView中显示Fragment ATextView的内容。 我尝试了很多方法,不幸的是我没有得到正确的输出。 我相信你们都知道。请帮帮我。

谢谢

【问题讨论】:

  • 您应该将文本存储在父 Activity 中,并在加载时将其传递给 FRAGMENT B。
  • @dmaxi 但我不知道如何在父 Activity 中存储文本
  • 创建一个String类型的成员变量,不要忘记在onSaveInstanceState()回调中保存到Bundle中。您还应该阅读 Activity 和 Fragment 的 JavaDoc。
  • @dmaxi 你能举个例子吗...这对我会更有帮助

标签: android android-fragments fragment


【解决方案1】:

应该考虑监听器,所以片段仍然不相互依赖,可以在一个或两个窗格模式下使用。 Activity 应该处理两个片段的侦听器。

这是一个包含两个片段的活动示例:

package com.example;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

import com.example.fragment.FragmentA;
import com.example.fragment.FragmentA.TextChangeListener;
import com.example.fragment.FragmentB;

public class ActivityAB extends FragmentActivity {

    FragmentA fragmentA;
    FragmentB fragmentB;

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

        FragmentManager manager = getSupportFragmentManager();
        fragmentA = (FragmentA) manager.findFragmentById(R.id.fragmentA);
        fragmentB = (FragmentB) manager.findFragmentById(R.id.fragmentB);

        fragmentA.setTextChangeListener(new TextChangeListener() {

            @Override
            public void onTextChange(CharSequence newText) {
                fragmentB.updateTextValue(newText);
            }
        });
    }

}

这是片段 A,它具有自定义文本更改事件的侦听器。

package com.example.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.example.R;

public class FragmentA extends Fragment {

    TextChangeListener listener;

    public interface TextChangeListener {
        public void onTextChange(CharSequence newText);
    }

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

        Button btn = (Button) view.findViewById(R.id.button1);
        final TextView textView = (TextView) view.findViewById(R.id.textView1);

        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (null != listener) {
                    listener.onTextChange(textView.getText());
                }

            }
        });
        return view;
    }

    public void setTextChangeListener(TextChangeListener listener) {
        this.listener = listener;
    }
}

这是具有更新文本字段的公共方法的片段 B:

package com.example.fragment;

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

import com.example.R;

public class FragmentB extends Fragment {

    TextView textView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        textView = (TextView) view.findViewById(R.id.textView1);
        return view;
    }

    public void updateTextValue(CharSequence newText) {
        textView.setText(newText);
    }
}

ActivityAB 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:baselineAligned="false"
    android:orientation="horizontal" >

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.example.fragment.FragmentA"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.example.fragment.FragmentB"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

片段A 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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show" />

</LinearLayout>

片段 B 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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="(here will be text)"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

【讨论】:

  • 嗨,谢谢您的回复..但这对我不起作用..还有一件事我在活动 ab 中没有两个单独的片段布局(当然我有两个片段类和对应的布局 xml 文件)...相反,我只有一个片段布局,并且 iam 动态更改内容..你能再试一次吗..
  • 方法onTextChange会在按钮点击时被调用。因此,使用此回调将片段 A 替换为片段 B 并设置您收到的文本,例如fragmentB.updateTextValue(newText); this.showFragmentB();
  • 此建议不适用于一般情况。如果您使用子片段怎么办?父片段和子片段可能需要相互通信,而不必一直到包含 Activity 来这样做。在某些情况下,根 Activity 可能包含整个应用程序(即:基于选项卡的应用程序)。不可能每个子组件之间的每一次通信都应该通过一个地方进行路由(严重违反单一职责反模式)
【解决方案2】:

听起来您的设置可能类似于 - MainActivity w/ FragmentA [添加] 和 FragmentB [添加]。对于这种情况,我将通过 MainActivity 在两个片段之间委派消息/操作。允许 MainActivity 处理消息/动作还有助于在片段之间更复杂的情况下可能需要的“特殊”编排。例如:

public interface FragmentCommunicator
{
    public void sendMessage ( String broadcastMessage );
    public void takeAction ( String name, int action, Fragment frag );
}

public class MainActivity extends Activity implements FragmentCommunicator
{
    Fragment fragA;
    Fragment fragB;
    ...
    @Override
    public void sendMessage ( String msg )
    {
        if ( msg.Contains("Send To fragA") )
            fragA.receiveMsg(msg);
        ...
    }
    @Override
    public void takeAction ( String name, int action, Fragment frag )
    {
    if ( action == CLOSE )
            removeFragment( name, frag );
        ...
    }
}

public class FragmentA extends Fragment
{
    ...
@Override
public void onClick(View v)
{   
     FragmentCommunicator inter = (FragmentCommunicator) getActivity();
     inter.sendMessage("the txt/information/etc you want to send to fragB");    
}
}

public class FragmentB extends Fragment
{
    ...
    public void receiveMsg ( String msg )
    {
        textView.setText(msg);
    }
}

我忘记发布 FragmentA 的发送部分。 希望这会有所帮助。

【讨论】:

    【解决方案3】:

    两个片段之间的通信应该始终通过它们的片段活动来保持片段之间的松散耦合,因此,如果您想将一些数据从一个片段 A 发送到另一个片段 B,您可以创建侦听器并在您的片段活动和从片段A内部您可以使用该侦听器触发事件​​并将数据发送到片段活动,所以现在片段活动也将具有片段B的对象,因此片段活动可以直接调用片段B的方法并发送数据分片B...

    【讨论】:

      【解决方案4】:

      developer.android.com

      要允许 Fragment 与其 Activity 进行通信,您可以定义 Fragment 类中的一个接口并在 活动。 Fragment 捕获期间的接口实现 它的 onAttach() 生命周期方法,然后可以调用接口 方法以便与 Activity 进行通信。

      示例:- http://wiki.workassis.com/android-fragment-communication/

      参考:-https://developer.android.com/training/basics/fragments/communicating.html

      【讨论】:

        【解决方案5】:

        我喜欢让活动成为片段与片段之间通信的中间人。但我喜欢的另一件事是使用event bus 架构,它也提供解耦。

        【讨论】:

          【解决方案6】:

          其实很简单,只需按照以下步骤操作:

          1. 所以您创建了两个片段 A 和 B,现在创建它们的大脑,即 Java 类文件。我们称它们为 JClass A(用于 Fragment A)和 JClass B(用于 Fragment B)

          2.Frag A 中有按钮,所以转到 JClass A,然后获取用户键入的字符串文本和按钮按下事件,如下所示: // 只需重写 onCreate 方法。

          @Nullable
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
              View view = inflater.inflate(R.layout.<name of your fragment A.xml file>,container,false);
          
              userInput = (EditText)view.findViewById(R.id.<Id that you gave to EditText field in which user enters text>);
          
              Button myButton = (Button)view.findViewById(R.id.<id of your Button>);
              myButton.setOnClickListener(
                      new Button.OnClickListener(){
                          public void onClick(View v){
                              JClassB.setText(userInput.getText().toString());/*Replace JClassB with the java class of Fragment B*/
          
                          }
                      }
              );
          
              return view;
          }
          
          1. 最后在您的 JClass B(片段 B 的 java 文件)中:

            公共类BottomSectionFrag扩展片段{

            private static TextView userText;
            @Nullable
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                View view = inflater.inflate(R.layout.fragmentB, container, false);
                userText = (TextView)view.findViewById(R.id.userText);
                return view;
            }
            public static void setText(String text){
                userText .setText(text);
            
            }
            

            }

          瞧!!

          附:这是我第一次在 stackOverFlow 上发帖:D

          和平相处。

          【讨论】:

            猜你喜欢
            • 2023-03-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多