android-如何通過介面回調來解決Fragment之間的互動

來源:互聯網
上載者:User

標籤:

  由於在android的絲線機制綜fragment和acitivty會被分別執行個體化為兩個不相干的對象,他們之間的聯絡由activity的一個成員對象FragmntManager來維護,Fragment執行個體化後到activity中的fragmentManager去註冊一下,這個動作封裝在Fragment對象的OnAttach中,所以你可以在fragment中聲明一些回調介面,當fragment調用onAttach時,將這些回調介面執行個體化,這樣fragment就能調用各個acivity的成員函數了,當然activity必須implements這些介面,否則會報ClassCastExceptionfragment和activity的回調機制又是OOP的又一次完美演繹!

下面通過一個例子來說明

實現的目的:將一個activity用兩個fragment分割填充,左側的fragment中有3個Button,右側作為內容顯示,當點擊左側的按鈕,顯示對應的文字資訊。

首先是activity_main.xml的布局檔案

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"    tools:context=".MainActivity">    <FrameLayout        android:id="@+id/ui_container"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1">    </FrameLayout>    <FrameLayout        android:id="@+id/details_container"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1"        android:background="@android:color/holo_blue_light">    </FrameLayout></LinearLayout>

如下所示:

左側的fragment布局left_fragment.xml如下所示:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent"><Button    android:id="@+id/firstButton"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="@string/first_button"/><Button    android:id="@+id/secondButton"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="@string/second_button"/><Button    android:id="@+id/thenButton"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="@string/then_button"/></LinearLayout>

如下所示:

右側的fragment布局right_fragment.xml如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent"><TextView    android:id="@+id/content"    android:layout_width="match_parent"    android:layout_height="match_parent" /></LinearLayout>


上面的布局檔案都很簡單,沒有什麼好說的,下面 ,我將對java檔案的代碼進行相應的解釋:

先將LeftFragment.java

package learn.dreamcoder.com.learn;import android.app.Activity;import android.app.Fragment;import android.graphics.Color;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Button;/** * Description: * User: Dream_Coder([email protected]) * Date: 2015-07-29 * Time: 15:15 */public class LeftFragment extends Fragment{    public interface MyListener{        public void showMessage(int index);    }    private MyListener mListener;    private Button mButton1;    private Button mButton2;    private Button mButton3;    public Button lastButton;    @Override    public void onAttach(Activity activity) {/*判斷宿主activity是否實現了介面MyListener*/        super.onAttach(activity);        try {            mListener = (MyListener) activity;        }catch (ClassCastException e) {            throw new ClassCastException(getActivity().getClass().getName()                    +" must implements interface MyListener");        }    }    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.left_fragment,container,false);        return view;    }    @Override    public void onResume() {        super.onResume();        mButton1 = (Button) getActivity().findViewById(R.id.firstButton);        mButton2 = (Button) getActivity().findViewById(R.id.secondButton);        mButton3 = (Button) getActivity().findViewById(R.id.thenButton);        mButton1.setOnClickListener(new MyButtonClickListener());        mButton2.setOnClickListener(new MyButtonClickListener());        mButton3.setOnClickListener(new MyButtonClickListener());    }    class MyButtonClickListener implements View.OnClickListener{        @Override        public void onClick(View v) {            Button button = (Button) v;            if(lastButton != null) {                lastButton.setBackgroundColor(0);            }            button.setBackgroundColor(Color.parseColor("#00FF00"));            lastButton= button;            if(button == mButton1) {                mListener.showMessage(1);            }            if(button == mButton2) {                mListener.showMessage(2);            }            if(button == mButton3) {                mListener.showMessage(3);            }        }    }}

該檔案中的MyListener是這個互動過程的關鍵,將這個介面暴露出去,交於宿主activity來實現,而宿主activity實現該介面,根據傳入的參數,做出對於的操作,並發出適當的命令交付給第二個Fragment,從而可以改變第二個fragment中的組件狀態。


整個過程可以理解為:Fragement1  ----》    activity   -----》   Fragment2

Fragment之間一般是不會直接進行互動的,而是需要通過宿主activity作為橋樑來進行通話。

宿主activity負責Fragement之間的業務通話,而Fragment僅僅負責維護自己的組件狀態就可以了,需要業務操作的部分暴露出去,交給宿主來做,這個暴露過程就是通過介面的方式。


例如在上述代碼中,類MyButtonClickListener中需要執行mListener.showMessage()函數來在Fragment2中展示資訊,但是在該Fragment中並沒有任何語句來對該介面進行實現,而是直接使用,因為我們的目的就是不直接與Fragment2進行互動,但是我們可以把這個介面交付給宿主activity,讓它來實現,讓它來操作這一切,於是乎,對於LeftFragment來講就不用擔心這個問題,直接使用就好了,因為宿主已經解決了這一切。

下面講解MainActivity.java代碼:

package learn.dreamcoder.com.learn;import android.app.Activity;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.os.Bundle;import android.view.View;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity implements LeftFragment.MyListener{    private TextView showMessageView;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        FragmentManager manager = getFragmentManager();        FragmentTransaction transaction = manager.beginTransaction();        transaction.add(R.id.ui_container,new LeftFragment());        transaction.add(R.id.details_container,new RightFragment());        transaction.commit();    }    @Override    public void showMessage(int index) {        if(1 == index) {            showMessageView.setText(R.string.first_page);        }else if(2 == index) {            showMessageView.setText(R.string.second_page);        }else {            showMessageView.setText(R.string.then_page);        }    }    @Override    protected void onResume() {        super.onResume();        showMessageView = (TextView) findViewById(R.id.content);    }}


在宿主activity中首先要做的事情就是要實現剛才的介面,這個介面的目的就是要根據剛才暴露出來是時候傳入的參數來向RightFragment發出命令,改變它的內容。所以要得到RightFragment中顯示的TextView 的引用,然後設定文字即可了。這就很好理解了

下面是RightFragment.java

package learn.dreamcoder.com.learn;import android.app.Fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;/** * Description: * User: Dream_Coder([email protected]) * Date: 2015-07-29 * Time: 15:16 */public class RightFragment extends Fragment{    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.right_fragment,container,false);    }}

這個很簡單,沒有什麼好說的,相信你們都能看明白。就不講解了。

總結一下,對於兩個Fragment之間的互動過程,如果想向Fragment發出什麼請求,直接把這個請求封裝成一個介面,暴露出去,交由宿主來實現就好了。


本人只是為了學習和理解,感覺這個代碼還是很有意義的,但是沒有太多的講解,我根據自己的理解寫了一些註解。

在這裡對原作者表示感謝

該文的原地址:http://www.360doc.com/content/14/0519/10/17121610_378958268.shtml


android-如何通過介面回調來解決Fragment之間的互動

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.