Fragment 與Fragment之間的通信

1、背景


    如圖,在圖片中,要實現ListFragment中點擊的不同,就要實現對DetailFragment的更新,在DetailFragment中的內容出現變化時,ListFragment也要做相應的變化,那麼如何,實現DetailFragment與ListFragment之間的通信呢?

2、實現方式

爲了保持Fragment的獨立性,我們可以在Fragment中定義回調接口,委託託管的Activity來完成那些不應該由Fragment處理的任務,託管activity將實現回調接口,履行託管Fragment的任務

1、在ListFragment中定義了一個內部接口,

public class CrimeListFragment extends ListFragment {
    private Callbacks mCallbacks;
   
    
  public interface Callbacks{
	  void onCrimeSelected(Crime crime);
  }

@Override
public void onAttach(Activity activity) {
	super.onAttach(activity);
	mCallbacks=(Callbacks) activity;
}
@Override
public void onDetach() {
	// TODO Auto-generated method stub
	super.onDetach();
	mCallbacks=null;
}
  
2、同時在託管的Activty中實現這個接口,並重寫了接口中的onCrimeSelected(Crime crime)方法,該方法主要用於當點擊ListFragment中的item時,更新DetailFragment,
public class CrimeListActivity extends SingleFragmentActivity implements CrimeListFragment.Callbacks{

	@Override
	public void onCrimeSelected(Crime crime) {
			FragmentManager fm=getSupportFragmentManager();
			FragmentTransaction ft=fm.beginTransaction();
			
			Fragment oldDetail=fm.findFragmentById(R.id.detailFragmentContainer);
			Fragment newDetial=CrimeFragment.newInstance(crime.getId());
			if(oldDetail!=null){
				ft.remove(oldDetail);
			}
			ft.add(R.id.detailFragmentContainer, newDetial);
			ft.commit();
		}
	}
}
3、那麼如何在ListFragment中實現呢?首先在ListFragment被託管在Activity時,實例化mCallback對象,當Fragment被託管的Activity移除時,設置mCallback對象爲空,因爲ListFragment不被託管時,更新界面是不起作用的。同時當點擊ListFragment中的數據時,調用mCallback.onCrimeSelected()方法

<pre name="code" class="java">public class CrimeListFragment extends ListFragment {
 public void onListItemClick(ListView l, View v, int position, long id) {
        // get the Crime from the adapter
        Crime c = ((CrimeAdapter)getListAdapter()).getItem(position);
        // start an instance of CrimePagerActivity
       // Intent i = new Intent(getActivity(), CrimePagerActivity.class);
     //   i.putExtra(CrimeFragment.EXTRA_CRIME_ID, c.getId());
     //   startActivityForResult(i, 0);
        mCallbacks.onCrimeSelected(c);

  public interface Callbacks{
	  void onCrimeSelected(Crime crime);
  }

  public void UpdateUI(){
	  ((CrimeAdapter)getListAdapter()).notifyDataSetChanged();
  }
@Override
public void onAttach(Activity activity) {
	super.onAttach(activity);
	mCallbacks=(Callbacks) activity;
}

@Override
public void onDetach() {
	// TODO Auto-generated method stub
	super.onDetach();
	mCallbacks=null;
}

}

mCallback對象其實還是一個Activity對象,所以在此方法中調用的onCrimeSelected()方法就是activity中被重寫的onCrimeSelected()方法,那麼ListFragment更新Detail界面的流程就是這樣。同理,在DetailFragment中更新ListFragment中的數據,只需要在DetailFragment中聲明一個接口,同時在Activity中實現,在實現的過程中調用ListFragment中的
UpdateUI方法,就可以實現DetailFragment中的數據變化後ListFragment中的界面也會相應的進行改變,具體代碼如下:

public class CrimeFragment extends Fragment {

    /**
     * 
     * @author user
     * Required interface for hosting activites.
     */
    public interface CallBacks{
    	void onCrimeUpdated(Crime crime);
    }
    
    
    @Override
    public void onAttach(Activity activity) {
    	// TODO Auto-generated method stub
    	super.onAttach(activity);
    	mCallbacks=(CallBacks) activity;
    }

    @Override
    public void onDetach() {
    	// TODO Auto-generated method stub
    	super.onDetach();
    	mCallbacks=null;
    }
    
    
{

在Activity中重寫DetailFragment中的方法
public class CrimeListActivity extends SingleFragmentActivity implements CrimeListFragment.Callbacks,CrimeFragment.CallBacks {

@Override
	public void onCrimeUpdated(Crime crime) {
		// TODO Auto-generated method stub
		FragmentManager fm=getSupportFragmentManager();
		CrimeListFragment listFragment=(CrimeListFragment) fm.findFragmentById(R.id.fragmentContainer);
		listFragment.UpdateUI();
	}
    
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章