Activity和Fragment的幾種交互方式(Activity可以改變Fragment的UI,Fragment也可以改變ActivityUI)

在工作中我們經(jīng)常會遇到Activity和Fragment交互踱稍。具體為什么要用Fragment曲饱,相信大家都懂的,可以使UI更靈活珠月,還可以把不同模塊獨(dú)立化扩淀,降低耦合度。Activity和Fragment之間傳值還是比較常見啤挎,但是要互相改變彼此UI還是有一定技巧的驻谆。下面根據(jù)自己工作經(jīng)驗(yàn),詳細(xì)總結(jié)一下Activity和Fragment的幾種交互方式庆聘。

一胜臊、getActivity()、new Fragment()方式(**** 這種方法比較經(jīng)典伙判,簡單實(shí)用****)

下面是Activity代碼:

public class MainActivity extends FragmentActivity implements OnActivityChangeListener{
 
    private TextView show_change_text;
    private Button change_fragment_bt;
    public static OnFragmentChangeListener onFragmentChangeListener;
    public static void setOnFragmentChangeListener(
            OnFragmentChangeListener onFragmentChangeListener) {
        MainActivity.onFragmentChangeListener = onFragmentChangeListener;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_content, new HomeFragment()).commit();
        change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt);
        show_change_text = (TextView) findViewById(R.id.show_change_text);
        // new HomeFragment().setOnActivityChangeListener(this);
        // 這樣set是不行的象对,因?yàn)檫@樣又重新創(chuàng)造了一個(gè)HomeFragment,和原來初始化的那個(gè)不是一個(gè),回報(bào)空指針澳腹,因?yàn)镠omeFragment的listener沒有被set
        //所以應(yīng)該這樣  HomeFragment.setOnActivityChangeListener(this);
        change_fragment_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //在這里執(zhí)行接口方法
                onFragmentChangeListener.onFragmentChange();
            }
        });
    }
 
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        // 除了這種方式傳遞子類對象织盼,還可以在Fragment中
        // setOnFragmentChangeListener,可以去那里面看一下,我已經(jīng)注釋過
        onFragmentChangeListener = (OnFragmentChangeListener) fragment;
    }
 
    @Override
    public void onActivityChange() {
        // TODO Auto-generated method stub
        // 在子類中實(shí)現(xiàn)接口的方法
        show_change_text.setText("I am UI of activity,and I have changed");
    }
 
}

下面是Fragment代碼:

public class HomeFragment extends Fragment implements OnFragmentChangeListener {
    private TextView show_change_text;
    private Button change_activity_bt;
    public static OnActivityChangeListener onActivityChangeListener;
    public void setOnActivityChangeListener(OnActivityChangeListener onActivityChangeListener){
        HomeFragment.onActivityChangeListener=onActivityChangeListener;
    }
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
 
        View view = inflater.inflate(R.layout.home_fragment, null);
        change_activity_bt = (Button) view
                .findViewById(R.id.change_activity_bt);
        show_change_text = (TextView) view.findViewById(R.id.show_change_text);
        // new MainActivity().setOnFragmentChangeListener(this);
        // 這樣set是不行的酱塔,因?yàn)檫@樣又重新創(chuàng)造了一個(gè)MainActivity,和原來初始化的那個(gè)不是一個(gè)沥邻,回報(bào)空指針,因?yàn)閍ctivity的listener沒有被set
        //所以應(yīng)該這樣  MainActivity.setOnFragmentChangeListener(this);
        change_activity_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //在這里執(zhí)行接口方法
                onActivityChangeListener.onActivityChange();
            }
        });
 
        return view;
    }
 
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // 除了這種方式傳遞子類對象羊娃,還可以在Activity中
                // setOnActivityChangeListener,可以去那里面看一下唐全,我已經(jīng)注釋過
        onActivityChangeListener=(OnActivityChangeListener) activity;
    }
 
    @Override
    public void onFragmentChange() {
        // 在子類中實(shí)現(xiàn)接口的方法
        show_change_text.setText("I am UI of fragment,and I have changed");
    }
}

getActivity()、new Fragment()方式源碼下載地址.........................

二、Handler方式

傳遞數(shù)據(jù)是比較容易實(shí)現(xiàn)邮利,但是要用到Activity和Fragment之間互相改變彼此的UI弥雹,網(wǎng)上關(guān)于這個(gè)問題的解決方法還是很少的,我也沒遇到合適的解決方案延届,自己在前人的基礎(chǔ)上研究后創(chuàng)造了一種方法剪勿。使Activity和Fragment共享一個(gè)Handler,然后發(fā)送消息通知彼此更新方庭。別的也不多說了厕吉,例子代碼如下,

這是Activity的代碼:

public class MainActivity extends FragmentActivity implements OnClickListener {
private Handler mHandler;
private long lastPressBack;
private boolean isFirstPressBack = true;
private Button change_fragment_bt;
private TextView show_change_text;
private HomeFragment homeFragment;
 
Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            show_change_text.setText("I am UI of activity,and I have changed");
            break;
        }
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        change_fragment_bt=(Button)findViewById(R.id.change_fragment_bt);
        show_change_text=(TextView)findViewById(R.id.show_change_text);
        change_fragment_bt.setOnClickListener(this);
        
        getSupportFragmentManager().beginTransaction()
        .replace(R.id.fragment_content, new HomeFragment())
        .commit();
    }
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        homeFragment=(HomeFragment) fragment;
        homeFragment.setHandler(handler) ;
    }
 
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);
        //點(diǎn)擊和Fragment交互械念,改變Fragment的UI
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            if(HomeFragment.changeText){
            Message msg = mHandler.obtainMessage();
                msg.what =0;
                mHandler.sendMessage(msg);
                HomeFragment.changeText=false;
                return false;
            }
            if (!isFirstPressBack) {
                if (System.currentTimeMillis() - lastPressBack > 2 * 1000) {
                    lastPressBack = System.currentTimeMillis();
                } else {
                    finish();
                }
            }
            lastPressBack = System.currentTimeMillis();
            Toast.makeText(this,getString(R.string.exit_app),Toast.LENGTH_SHORT).show();
            isFirstPressBack = false;
                return false;
            }
        return false;
        }
    public void setHandler(Handler handler) {
        mHandler = handler;
    }
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        //點(diǎn)擊和Fragment交互头朱,改變Fragment的UI
        Message msg = mHandler.obtainMessage();
        msg.what =0;
        mHandler.sendMessage(msg);
        HomeFragment.changeText=false;
    }
}

這是Fragment的代碼:

public class HomeFragment extends Fragment implements OnClickListener{
    private TextView show_change_text;
    private Button change_activity_bt;
    private MainActivity mActivity;
    public static boolean changeText=true;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0:
                show_change_text.setText("I am UI of fragment,and I have changed");
                break;
            }
        }
    };
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
 
        View view = inflater.inflate(R.layout.home_fragment, null);
        show_change_text=(TextView)view.findViewById(R.id.show_change_text);
        change_activity_bt=(Button)view.findViewById(R.id.change_activity_bt);
        change_activity_bt.setOnClickListener(this);
        return view;
    }
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mActivity = (MainActivity) activity;
        mActivity.setHandler(handler);
    }
    
     public void setHandler(Handler handler) {
            this.handler = handler;
        }
    
    public void onDestroy(){
        super.onDestroy();
        changeText=true;
    }
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        //點(diǎn)擊和Activity交互,改變ActivityUI
        Message msg = handler.obtainMessage();
        msg.what =0;
        handler.sendMessage(msg);
    }
}

Handler方式源碼下載地址....................

三龄减、接口回調(diào)方式(這個(gè)盡量不要用项钮,因?yàn)闀?chuàng)建static對象,而static對象不會被回收希停,很占內(nèi)存)

接口真是個(gè)好東西烁巫,條件是兩個(gè)類,一個(gè)接口脖苏,兩個(gè)類之間交互程拭。任何兩個(gè)類之間交互都可以用接口回調(diào),針對接口編程能降低兩個(gè)類之間的耦合度棍潘。

下面是Activity的代碼:

public class MainActivity extends FragmentActivity implements OnActivityChangeListener{
 
    private TextView show_change_text;
    private Button change_fragment_bt;
    public static OnFragmentChangeListener onFragmentChangeListener;
    public static void setOnFragmentChangeListener(
            OnFragmentChangeListener onFragmentChangeListener) {
        MainActivity.onFragmentChangeListener = onFragmentChangeListener;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_content, new HomeFragment()).commit();
        change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt);
        show_change_text = (TextView) findViewById(R.id.show_change_text);
        // new HomeFragment().setOnActivityChangeListener(this);
        // 這樣set是不行的恃鞋,因?yàn)檫@樣又重新創(chuàng)造了一個(gè)HomeFragment,和原來初始化的那個(gè)不是一個(gè),回報(bào)空指針亦歉,因?yàn)镠omeFragment的listener沒有被set
        //所以應(yīng)該這樣  HomeFragment.setOnActivityChangeListener(this);
        change_fragment_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //在這里執(zhí)行接口方法
                onFragmentChangeListener.onFragmentChange();
            }
        });
    }
 
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        // 除了這種方式傳遞子類對象恤浪,還可以在Fragment中
        // setOnFragmentChangeListener,可以去那里面看一下,我已經(jīng)注釋過
        onFragmentChangeListener = (OnFragmentChangeListener) fragment;
    }
 
    @Override
    public void onActivityChange() {
        // TODO Auto-generated method stub
        // 在子類中實(shí)現(xiàn)接口的方法
        show_change_text.setText("I am UI of activity,and I have changed");
    }
 
}

顯示Fragment的代碼:


<span style="font-size:14px;"><span style="font-size:14px;color:#333333;">public class HomeFragment extends Fragment implements OnFragmentChangeListener {
    private TextView show_change_text;
    private Button change_activity_bt;
    public static OnActivityChangeListener onActivityChangeListener;
    public void setOnActivityChangeListener(OnActivityChangeListener onActivityChangeListener){
        HomeFragment.onActivityChangeListener=onActivityChangeListener;
    }
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
 
        View view = inflater.inflate(R.layout.home_fragment, null);
        change_activity_bt = (Button) view
                .findViewById(R.id.change_activity_bt);
        show_change_text = (TextView) view.findViewById(R.id.show_change_text);
        // new MainActivity().setOnFragmentChangeListener(this);
        // 這樣set是不行的肴楷,因?yàn)檫@樣又重新創(chuàng)造了一個(gè)MainActivity,和原來初始化的那個(gè)不是一個(gè)水由,回報(bào)空指針,因?yàn)閍ctivity的listener沒有被set
        //所以應(yīng)該這樣  MainActivity.setOnFragmentChangeListener(this);
        change_activity_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //在這里執(zhí)行接口方法
                onActivityChangeListener.onActivityChange();
            }
        });
 
        return view;
    }
 
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // 除了這種方式傳遞子類對象赛蔫,還可以在Activity中
                // setOnActivityChangeListener,可以去那里面看一下砂客,我已經(jīng)注釋過
        onActivityChangeListener=(OnActivityChangeListener) activity;
    }
 
    @Override
    public void onFragmentChange() {
        // 在子類中實(shí)現(xiàn)接口的方法
        show_change_text.setText("I am UI of fragment,and I have changed");
    }
}
</span></span>

Interface方式代碼下載地址.....................

四、使用startActivityForResult(Fragment和Activity呵恢、兩個(gè)Activity之間交互都行)

下面是Fragment的代碼

public class HomeFragment extends Fragment {
    private TextView fragment_text;
    private Button change_activity_bt;
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
 
        View view = inflater.inflate(R.layout.home_fragment, null);
        change_activity_bt = (Button) view
                .findViewById(R.id.change_activity_bt);
        fragment_text = (TextView) view.findViewById(R.id.fragment_text);
 
        change_activity_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent intent = new Intent(getActivity(), SecondActivity.class);
                startActivityForResult(intent, 0);
            }
        });
        return view;
    }
 
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (intent == null)
            return;
        String change01 = intent.getStringExtra("change01");
        // 根據(jù)上面發(fā)送過去的請求嗎來區(qū)別
        switch (requestCode) {
        case 0:
            fragment_text.setText(change01);
            break;
        default:
            break;
        }
    }
}

下面是SecondActivity代碼

<span style="font-size:14px;">public class SecondActivity extends FragmentActivity {
 
    private Button change_fragment_bt;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);
        change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt);
        change_fragment_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent mIntent = new Intent();
                mIntent.putExtra("change01", "Change HomeFragment By SecondActivity");
                mIntent.putExtra("change02", "Change MainActivity By SecondActivity");
                // 設(shè)置結(jié)果鞠值,并進(jìn)行傳送
                setResult(0, mIntent);
                finish();
            }
        });
    }
}</span>

stratActivityForResult方式源碼,點(diǎn)擊下載......

五渗钉、萬能的BroadCastReceiver(Fragment和Activity彤恶、兩個(gè)Activity之間交互都行)

雖然廣播比較萬能,但是它是由系統(tǒng)決定,且有優(yōu)先級声离,可能會造成延遲芒炼。

下面是MainActivity 代碼:

<span style="font-size:14px;">public class MainActivity extends Activity {  
  
    TextView textView;  
    Button sButton;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        textView = (TextView) findViewById(R.id.show);  
        sButton = (Button) findViewById(R.id.startAnother);  
        sButton.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                startActivity(new Intent(MainActivity.this,AnotherActivity.class));  
            }  
        });  
        IntentFilter filter = new IntentFilter(AnotherActivity.action);  
        registerReceiver(broadcastReceiver, filter);  
    }  
  
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {  
  
        @Override  
        public void onReceive(Context context, Intent intent) {  
            // TODO Auto-generated method stub  
            textView.setText(intent.getExtras().getString("data"));  
        }  
    };  
  
    protected void onDestroy() {  
        unregisterReceiver(broadcastReceiver);  
    };  
} </span>

下面是AnotherActivity代碼:

<span style="font-size:14px;">public class AnotherActivity extends Activity {  
  
    public static final String action = "jason.broadcast.action";  
  
    Button update;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.another);  
        update = (Button) findViewById(R.id.updateMain);  
        update.setOnClickListener(new OnClickListener() {  
  
            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                Intent intent = new Intent(action);  
                intent.putExtra("data", "yes i am data");  
                sendBroadcast(intent);  
                finish();  
            }  
        });  
    }  
}  </span>

六、可以使用第三方框架EventBus术徊,可參考:http://blog.csdn.net/lmj623565791/article/details/40794879

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末本刽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弧关,更是在濱河造成了極大的恐慌盅安,老刑警劉巖唤锉,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世囊,死亡現(xiàn)場離奇詭異,居然都是意外死亡窿祥,警方通過查閱死者的電腦和手機(jī)株憾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晒衩,“玉大人嗤瞎,你說我怎么就攤上這事√担” “怎么了贝奇?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長靠胜。 經(jīng)常有香客問我掉瞳,道長,這世上最難降的妖魔是什么浪漠? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任陕习,我火速辦了婚禮,結(jié)果婚禮上址愿,老公的妹妹穿的比我還像新娘该镣。我一直安慰自己,他們只是感情好响谓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布损合。 她就那樣靜靜地躺著,像睡著了一般娘纷。 火紅的嫁衣襯著肌膚如雪嫁审。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天失驶,我揣著相機(jī)與錄音土居,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛擦耀,可吹牛的內(nèi)容都是我干的棉圈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼眷蜓,長吁一口氣:“原來是場噩夢啊……” “哼分瘾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吁系,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤德召,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后汽纤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體上岗,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年蕴坪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肴掷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡背传,死狀恐怖呆瞻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情径玖,我是刑警寧澤痴脾,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站梳星,受9級特大地震影響赞赖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丰泊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一薯定、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞳购,春花似錦话侄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盏浇,卻和暖如春变丧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绢掰。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工痒蓬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留童擎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓攻晒,卻偏偏與公主長得像顾复,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子鲁捏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353