Android中的片段碎片通信

时间:2013-03-16 09:48:52

标签: android android-fragments fragment

我在Android编程的初级水平,所以我需要你真诚的帮助。任何人都可以帮助我。

我正在尝试使用片段构建SLIDING UI

所以我的实际怀疑是......我有一个Fragment(说Fragment A),其中有一个TextViewButton以及另一个Fragment Fragment (说TextView B)。它中有一个Fragment A。当我在片段A中按下TextView时,我需要在Fragment B TextView中显示Button的{​​{1}}内容。 我尝试了很多方法,遗憾的是我没有得到正确的输出。 我相信大家都知道。请帮帮我。

谢谢

6 个答案:

答案 0 :(得分:15)

它应该是思想监听器,因此碎片仍然不相互依赖,可以在一个或两个窗格模式下使用。 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>

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

答案 1 :(得分:2)

听起来好像你的设置可能是这样 - MainActivity w / FragmentA [添加]和FragmentB [添加]。对于这种情况,我将通过MainActivity委派两个片段之间的消息/操作。允许MainActivity处理消息/操作也有助于实现特殊的&#39;在碎片之间更复杂的情况下可能需要的编排。例如:

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的发送部分。 希望这会有所帮助。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

developer.android.com

  

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:-1)

实际上非常简单,只需按照以下步骤操作:

  1. 所以你创建了两个片段A和B,现在创建它们的大脑,即Java类文件。让我们称它们为JClass A(对于片段A)和JClass B(对于片段B)
  2. 2.你在Frag A中有了一个按钮,所以转到JClass A,然后获取用户输入的String文本和按下按钮事件,如下所示: //只是覆盖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扩展Fragment {

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

      }

    2. 瞧!! ​​

      P.S。这是我在stackOverFlow上发表的第一篇文章:D

      和平了。