Fragment to Fragment通信使用LocalBroadcastManager失败

时间:2017-10-25 04:07:53

标签: android android-fragments localbroadcastmanager

我在使用LocalbroadcastManager将数据从一个片段传输到另一个片段时遇到问题。

FragmentA有editText,onclick就会启动FragmentB。 FragmentB有一个项目列表,并在我希望将数据传递给FragmentA的每个项目上单击。

这是我的实施。

public class FragmentA extends Fragment {
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String highSchoolName = intent.getStringExtra("HighSchoolName");
    }
};

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(mMessageReceiver, new IntentFilter("HighSchoolEvent"));
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mMessageReceiver);
}

下面是片段B,其中播放广播消息。

public class FragmentB extends Fragment {

    mHighSchoolListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            HighSchool highSchoolItem = mHighSchoolAdapter.getItem(position);
            sendHighSchoolItemToSignupForm(highSchoolItem);
        }
    });

    private void sendHighSchoolItemToSignupForm(HighSchool highSchoolItem) {
        Intent intent = new Intent("HighSchoolEvent");
        intent.putExtra("HighSchoolName", highSchoolItem.getName());
        LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
        getActivity().onBackPressed();
    }
}

调试/记录永远不会命中广播接收器的onReceive消息。有什么遗漏? 感谢任何建议。

3 个答案:

答案 0 :(得分:2)

如果&#34;启动&#34;表示您正在用Fragment A替换Fragment B,那么您就错了..

您应该将Fragment B添加到backstack

FragmentTransaction#addToBackStack(String fragmentName);

你应该做

FragmentTransaction#add()

而不是

FragmentTransaction#replace()

添加:会将另一个片段视图添加到容器

替换:将用另一个片段替换容器的所有内容

我确定您正在使用Fragment A替换Fragment B,在这种情况下,您的Fragment A将被销毁并且Fragment B将被加载,您将无法收听在Fragment A

中更新

答案 1 :(得分:0)

正如J Ramesh建议的那样,通过将片段事务类型从replace更改为add,修复了问题。

这是片段交易。

    FragmentManager fm = getFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.add(android.R.id.content, new FragmentA())
            .addToBackStack(null).commit();

答案 2 :(得分:0)

  1. 在片段B中定义InterFace

    要允许Fragment与其Activity进行通信,您可以在Fragment类中定义接口并在Activity中实现它。 Fragment在其onAttach() lifecycle方法期间捕获接口实现,然后可以调用Interface方法以与Activity通信。

  2.     UpdateFragmentA update;
        public interface  UpdateFragmentA {
           
            public void update_fragment(String data);
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            try {
                update= (UpdateFragmentA ) getActivity();
            }catch (Exception e)
            {
                e.printStackTrace();
            }
    
    
        }
    
    
    
    // set setOnItemClickListener for List View
    listview.setOnItemClickListener(new OnItemClickListener()
    {
        @Override 
        public void onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)
        { 
           update.update_fragment(items[position]);
        }
    });

    为了从片段接收​​事件回调,托管它的活动必须实现片段类中定义的接口。

     public static class MainActivity extends Activity
                implements FragmentB.UpdateFragmentA{
            ...
    
            public void update_fragment(String data) {
                // The user selected the Item 
    
                // send that data to fragment A
                a.recieve(data);  //a is FragmentA reference a=new FragmentA();
            }
        }

    主机活动可以通过捕获Fragment实例

    将消息传递给片段

    在FragmentA中定义方法接收(String s);

       public class FragmentA extends Fragment {
       ....
       ...
       
       public void recieve(String s)
        {
          //You get Selected Item From FragmentB through Activity
                // Do something here to display that
    
            if(!s.isEmpty())
            {
              textview.setText(s);
            }
    
        }
        
     }

    enter image description here