ActivityとFragment通信方式まとめ

22233 ワード

概要
通常、FragmentとActivityの通信には、次の3つのケースがあります.
  • Activity操作内蔵Fragment
  • Fragment操作宿主Activity
  • Fragmentオペレーションは、Activityの他のFragmentと同じです.Androidでは、Activityとfragment間の通信を優雅に実現するには、次の方法があります.
  • Handler
  • 放送
  • EventBus
  • インタフェースコールバック
  • BundleおよびsetArguments(bundle)
  • Handler
    public class MainActivity extends FragmentActivity{ 
          //    Handler 
          public Handler mHandler = new Handler(){       
              @Override
               public void handleMessage(Message msg) { 
                    super.handleMessage(msg);
                     //         
               }
         }
         
       } 
        public class MainFragment extends Fragment{ 
              //  Activity   handler
               private Handler mHandler;
               @Override
               public void onAttach(Activity activity) { 
                    super.onAttach(activity);
                   
                    if(activity instance MainActivity){ 
                          mHandler =  ((MainActivity)activity).mHandler; 
                    }
               }
               
         }
    

    この方法の欠点:
  • Fragmentは特定のActivityに対して結合が存在し、Fragment多重化
  • に不利である.
  • はメンテナンスに不利であり、対応するActivityを削除するにはFragmentも
  • を変更しなければならない.
  • Activityの戻りデータを取得できないので、一般的にはこの方法は推奨されません.ブロードキャストActivityでブロードキャスト受信機を登録し、Fragmentでブロードキャストを送信:
    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (action.equals(ACTION_NAME)) {
                    String msg = intent.getStringExtra("msg");
                    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                }
            }
        };
        public void registerBoradcastReceiver() {
            IntentFilter myIntentFilter = new IntentFilter();
            myIntentFilter.addAction(ACTION_NAME);
            registerReceiver(mBroadcastReceiver, myIntentFilter);
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(mBroadcastReceiver);
        }
    
  • EventBus
  • MainActivity
    //     
    EventBus.getDefault().register(this);
    //         
    @Subscribe
        public void onEventMainThread(UserEvent event) {
            btn.setText(event.getUserName());
            service_tv.setText(event.getUserName());
        }
    
    
  • Fragment送信情報
    UserEvent event=new UserEvent();
    EventBus.getDefault().post(event);
    

  • インタフェースコールバック
  • Fragmentでインタフェース
  • を定義する.
  • 呼び出しインタフェースにおける抽象メソッド
  • Activityでインタフェースを実装し、インタフェース内の方法を具体的に実装し、通信を完了する.

  • Fragment
    public class MainFragment extends Fragment{
           public FragmentListener mListener; 
           
          //MainFragment      
          public static interface FragmentListener{ 
          
              //  h5  
             void toH5Page();
             
             //    
             void showMsg(String str);
           }
           @Override 
          public void onAttach(Activity activity) { 
                super.onAttach(activity); 
                //      Activity      
                 if(activity instance FragmentListener){
                 
                     mListener = ((FragmentListener)activity); 
                     
                }
           }
           ...         
           
           mButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  msgListener.showMsg("Hello      Activity  ");
              }
          });
    }
    

    Activity
    // MainActivity    MainFragment      
      public class MainActivity extends FragmentActivity implements FragmentListener{ 
            @override
             public void toH5Page(){... }
             
            @Override
             public void showMsg(String str) {
                Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
            }
             
           ...        
       }
    
    

    BundleとsetArguments(bundle)
    AndroidがFragmentにパラメータを優雅に渡す方法を参照
    Fragment&&Fragmentデータインタラクション
    FragmentとFragment間のデータインタラクションもよく使われるはずです.ホストActivityを伝達媒体として使用することができます.原理は、onActivity Resultコールバックを使用することによって、Fragment&&Fragmentのデータインタラクションを完了することでもあります.このうち、2つの重要な方法があります.Fragment.setTargetFragment、getTargetFragment().
    FirstFragmentでは、setTargetFragmentを使用してインタラクティブなFragmentを接続します.
    secondFragment.setTargetFragment(FirstFragment.this, REQUEST_CODE);
    
    

    次にonActivity Resultを実現し、伝達されたデータを処理する.
    @Override  
       public void onActivityResult(int requestCode, int resultCode, Intent data) {  
           super.onActivityResult(requestCode, resultCode, data);  
           if(resultCode != Activity.RESULT_OK){  
               return;  
           }else{  
               Integer str = data.getIntExtra("key",-1);  
               //    ...
           }  
       }
    

    SecondFragmentでsendResult()メソッドを呼び出し、FirstFragmentにデータを返信します.
    private void sendResult(int resultOk) {  
            if(getTargetFragment() == null){  
                return;  
            }else{  
                Intent intent = new Intent();  
                intent.putExtra("key", 520); 
                			   getTargetFragment().onActivityResult(FirstFragment.REQUEST_CODE,resultOk,intent);  
            }  
        }