轉載請標明原地址:[http://blog.csdn.net/gaolei1201/article/details/44037831?](http://blog.csdn.net/gaolei1201/article/details/44037831)
在工作中我們經常會遇到Activity和Fragment交互。具體為什么要用Fragment,相信大家都懂的,這樣可以減少Activity之間來回切換,還可以把不同模塊獨立化,降低耦合度。下面根據自己工作經驗,詳細總結一下Activity和Fragment的幾種交互方式。
## 一、使用Bundle
這種方法只能用來傳遞數據,且只能是Activity向Fragmeng傳遞。
首先我們需要在Activity中動態添加Fragment時,用Bundle封裝我們需要傳遞的數據
~~~
HomeFragment arg = new HomeFragment();
Bundle bundle = new Bundle();
bundle.putString("arg", edit.getText().toString());
arg.setArguments(bundle);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.layout_fragment, arg);
ft.commit();
然后在Fragment的回調函數中通過Fragment提供的方法getArguments()取出Bundle對象。
text = (TextView) view.findViewById(R.id.text);
Bundle bundle = getArguments();
text.setText(bundle.getString("arg"));
~~~
這種方法比較簡單就不多說了
## 二、getActivity()、new Fragment()方式(?這種方法比較經典,簡單實用)
下面是Activity代碼:
~~~
public class MainActivity extends FragmentActivity {
private TextView show_change_text;
private Button change_fragment_bt;
private HomeFragment homeFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
homeFragment=new HomeFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_content,homeFragment ).commit();
change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt);
show_change_text = (TextView) findViewById(R.id.show_change_text);
change_fragment_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
homeFragment.changeText();
}
});
}
public void changeText(){
show_change_text.setText("I am UI of activity,and I have changed");
}
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
}
}
~~~
下面是Fragment代碼:
~~~
public class HomeFragment extends Fragment {
private TextView show_change_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);
show_change_text = (TextView) view.findViewById(R.id.show_change_text);
change_activity_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
((MainActivity) getActivity()).changeText();
}
});
return view;
}
public void changeText(){
show_change_text.setText("I am UI of fragment,and I have changed");
}
public void onAttach(Activity activity) {
super.onAttach(activity);
}
}
~~~
[? getActivity()、new Fragment()方式源碼下載地址.........................](http://download.csdn.net/detail/gaolei1201/8994197)
## 三、Handler方式
傳遞數據是比較容易實現,但是要用到Activity和Fragment之間互相改變彼此的UI,網上關于這個問題的解決方法還是很少的,我也沒遇到合適的解決方案,自己在前人的基礎上研究后創造了一種方法。使Activity和Fragment共享一個Handler,然后發送消息通知彼此更新。別的也不多說了,例子代碼如下,
這是Activity的代碼:
~~~
<span style="font-size:14px;color:#333333;">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);
//點擊和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
//點擊和Fragment交互,改變Fragment的UI
Message msg = mHandler.obtainMessage();
msg.what =0;
mHandler.sendMessage(msg);
HomeFragment.changeText=false;
}
}
</span>
~~~
這是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
//點擊和Activity交互,改變ActivityUI
Message msg = handler.obtainMessage();
msg.what =0;
handler.sendMessage(msg);
}
}
~~~
?[Handler方式源碼下載地址....................](http://download.csdn.net/detail/gaolei1201/8929807)
## 四、接口回調方式
接口真是個好東西,條件是兩個類,一個接口,兩個類之間交互。任何兩個類之間交互都可以用接口回調,針對接口編程能降低兩個類之間的耦合度。
下面是Activity的代碼:
~~~
<span style="font-size:14px;color:#333333;">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是不行的,因為這樣又重新創造了一個HomeFragment,和原來初始化的那個不是一個,回報空指針,因為HomeFragment的listener沒有被set
//所以應該這樣 HomeFragment.setOnActivityChangeListener(this);
change_fragment_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//在這里執行接口方法
onFragmentChangeListener.onFragmentChange();
}
});
}
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
// 除了這種方式傳遞子類對象,還可以在Fragment中
// setOnFragmentChangeListener,可以去那里面看一下,我已經注釋過
onFragmentChangeListener = (OnFragmentChangeListener) fragment;
}
@Override
public void onActivityChange() {
// TODO Auto-generated method stub
// 在子類中實現接口的方法
show_change_text.setText("I am UI of activity,and I have changed");
}
}</span>
~~~
顯示Fragment的代碼:
~~~
<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是不行的,因為這樣又重新創造了一個MainActivity,和原來初始化的那個不是一個,回報空指針,因為activity的listener沒有被set
//所以應該這樣 MainActivity.setOnFragmentChangeListener(this);
change_activity_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//在這里執行接口方法
onActivityChangeListener.onActivityChange();
}
});
return view;
}
public void onAttach(Activity activity) {
super.onAttach(activity);
// 除了這種方式傳遞子類對象,還可以在Activity中
// setOnActivityChangeListener,可以去那里面看一下,我已經注釋過
onActivityChangeListener=(OnActivityChangeListener) activity;
}
@Override
public void onFragmentChange() {
// 在子類中實現接口的方法
show_change_text.setText("I am UI of fragment,and I have changed");
}
}
</span>
~~~
[
Interface方式代碼下載地址.....................](http://download.csdn.net/detail/gaolei1201/8929815)