在工作中我們經(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