国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android應用開發中Fragment間通信的實現教程

2020-04-11 10:44:28
字體:
來源:轉載
供稿:網友

為了重用Fragment UI 組件,在設計中你應該通過定義每一個fragemnt自己的layout和行為,讓fragment的自包含和模塊化。一旦你定義了這些可重用的Fragment,你可以通過Activity將它們關聯起來并通過程序的邏輯代碼將他們連接起來以實現整體組合的UI。

你會經常想要一個fragment與另一個fragment通信,例如基于用戶事件改變fragment中的內容。所有fragment質檢單額通信都是通過Activity關聯起來的。兩個fragment之間不應該直接進行通信。

定義接口

為了允許fragment和它的Activity通信,你應該fragment類中定義一個接口并在Activity中實現它。Fragment在onAttach()回調函數中獲取接口的具體實現的對象。后面,fragment就可以調用接口中的方法實現與Activity的通信。

下面是一個Fragment一Activity通信的例子:

// 用來存放fragment的Activtiy必須實現這個接口  public interface OnHeadlineSelectedListener {    public void onArticleSelected(int position);  } @Override  public void onAttach(Activity activity) {    super.onAttach(activity);    // 這是為了保證Activity容器實現了用以回調的接口。如果沒有,它會拋出一個異常。    try {      mCallback = (OnHeadlineSelectedListener) activity;    } catch (ClassCastException e) {      throw new ClassCastException(activity.toString()          + " must implement OnHeadlineSelectedListener");    }  }

現在fragment可以通過使用實現了OnHeadlineSelectedListener接口的mCallback實例調用onArticleSelected()方法(或其他在接口中的方法)將消息傳遞給Activity。

例如下面在fragment中的方法將會在用戶點擊一個List item的時候被調用。這個fragment使用回調接口將時間傳遞給父Activtity。

@Override  public void onListItemClick(ListView l, View v, int position, long id) {    // 發送時間給Activity宿主    mCallback.onArticleSelected(position);  }


實現接口

為了接收從fragment傳遞過來的事件回調,宿主Activity必須實現定義在fragment類中的接口。

例如,下面的activity實現了上個例子中的接口。

public static class MainActivity extends Activity    implements HeadlinesFragment.OnHeadlineSelectedListener{  ...    public void onArticleSelected(int position) {    // 用戶選擇了HeadlinesFragment中的頭標題后    // 做一些業務操作  }}

將消息傳遞給fragment

宿主Activity可以通過調用findFragmentById()方法獲取Fragment實例,然后直接調用Fragment的公有方法,將消息傳遞給Fragment。

例如,想象一下,之前講過的Activity可能包含有其他的fragment,而這些fragment通過上面的回調函數返回的接口動態地顯示一些內容。這種情況下,Activity可以將回調函數中接收到信息傳遞給需要的fragment。

public static class MainActivity extends Activity    implements HeadlinesFragment.OnHeadlineSelectedListener{  ...  public void onArticleSelected(int position) {    // 用戶選中HeadlinesFragment中的頭標題后    // 做一些必要的業務操作    ArticleFragment articleFrag = (ArticleFragment)        getSupportFragmentManager().findFragmentById(R.id.article_fragment);    if (articleFrag != null) {      // 如果 article frag 不為空,那么我們在同時顯示兩個fragmnet的布局中...      // 調用ArticleFragment中的方法去更新它的內容      articleFrag.updateArticleView(position);    } else {      // 否則,我們就是在僅包含一個fragment的布局中并需要交換fragment...      // 創建fragment并給他一個跟選中的文章有關的參數      ArticleFragment newFragment = new ArticleFragment();      Bundle args = new Bundle();      args.putInt(ArticleFragment.ARG_POSITION, position);      newFragment.setArguments(args);          FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();      // 用這個fragment替換任何在fragment_container中的東西      // 并添加事務到back stack中以便用戶可以回退到之前的狀態      transaction.replace(R.id.fragment_container, newFragment);      transaction.addToBackStack(null);      // 提交事務      transaction.commit();    }  }}



動態加載的Fragment通信
fragment之間永遠不能通信都是通過他們所依附的Activity來通信的,通過接口回調的方式來通信
Activity--->Fragment:在activity中創建Bundle數據包,并調用fragment的setArguments(Bundle bundle)方法

fragment--->Activity:在fragment類中定義一個接口,并在他所屬的activity中實現該接口,fragment在他的onAttach()方法執行期間捕獲該接口的實現,然后就可以調用該接口方法,以便跟activity通信。

下面的代碼實現了在一個Activity下有兩個Fragment,在一個Fragment中輸入值在另一個Fragment顯示

public class MainActivity extends Activity implements MyListener {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    FragmentManager manager = getFragmentManager();    FragmentTransaction fragmentTransaction = manager.beginTransaction();    Fragment1 fragment1 = new Fragment1();    fragmentTransaction.add(R.id.layout1, fragment1);    fragmentTransaction.commit();  }    //在mainActivity中實現MyListener接口并實現它未實現的方法,在該方法中傳遞數據  @Override  public void send(String info) {    Toast.makeText(this, "Activity成功接收" + info, 0).show();        Fragment2 fragment2 = new Fragment2();    Bundle bundle = new Bundle();    bundle.putString("name", info);    fragment2.setArguments(bundle);    FragmentManager manager = getFragmentManager();    FragmentTransaction fragmentTransaction = manager.beginTransaction();    //替換該Fragment            fragmentTransaction.replace(R.id.layout2, fragment2, "fragment2");    fragmentTransaction.commit();  }}

上面的MainActivity布局就是添加兩個Linearlayout,下面是創建兩個Fragment,Fragment1的布局就是一個EditText一個Button,Fragment2的布局就是一個TextView。

 public class Fragment1 extends Fragment {  EditText et;  Button enter;  private String info;  @Override  public void onAttach(Activity activity) {    listener = (MyListener) activity;    super.onAttach(activity);  }  @Override  public View onCreateView(LayoutInflater inflater, ViewGroup container,      Bundle savedInstanceState) {    View view = inflater.inflate(R.layout.fragment1_lay,container, false);    et = (EditText) view.findViewById(R.id.et);    enter = (Button) view.findViewById(R.id.enter);    enter.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        info = et.getText().toString();        listener.send(info);      }    });    return view;  }  public MyListener listener;    //定義一個接口  public interface MyListener{     public void send(String info);  }}public class Fragment2 extends Fragment {  @Override  public View onCreateView(LayoutInflater inflater, ViewGroup container,      Bundle savedInstanceState) {    View view = inflater.inflate(R.layout.fragment2_lay,container, false);    TextView tv = (TextView) view.findViewById(R.id.tv);    tv.setText(getArguments().get("name")+"");//獲取傳遞的值    Toast.makeText(getActivity(), "fragment"+getArguments().get("name")+"", 0).show();    return view;  }}


靜態加載的fragment通信
fragment可以調用getActivity()方法獲取他所在的Activity
Activity可以調用FragmentManager的findFragmentById()或findFragmentByTag()方法獲取Fragment
如果是靜態加載的Fragmentn那么向Activity傳遞數據就很簡單了,在MainActivity的onCreate方法中:

FragmentManager fragmentManager = getFragmentManager();Fragment fragment = fragmentManager.findFragmentById(R.id.frag);//靜態加載在Activity布局中設置的Fragment的IDMyFragment frag = (MyFragment) fragment;frag.setText1("fragment靜態傳值");

在Fragment類中設置它的get、set方法,

private String text1;  public String getText1() {    return text1;  }  public void setText1(String text1) {    this.text1 = text1;  }

下面直接調用就可以了:

     String value = getText1();

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高雄市| 南康市| 西吉县| 西林县| 乌恰县| 尼勒克县| 甘南县| 河池市| 赣榆县| 甘洛县| 许昌市| 巴中市| 来安县| 和平县| 皮山县| 句容市| 沙河市| 常山县| 合江县| 融水| 壶关县| 云安县| 湘潭县| 深泽县| 晋城| 泰州市| 西藏| 平潭县| 阳春市| 定州市| 封开县| 岱山县| 雷波县| 巴南区| 遂川县| 崇信县| 雅江县| 裕民县| 盐池县| 阆中市| 壶关县|