去年年底的時候需要改一個項目,接觸到了fragment。也沒有對fragment進行系統的學習,就開始動手改了,邊改邊學,現在閒下來了,對fragment進行一些總結。
- 什麼是Fragment?
- Fragment與Activity的區別
- Fragment的生命週期
- Fragment的簡單使用
- Fragment的回退棧
- Fragment的通信
1.什麼是fragment?
Fragment是Android3.0提出來的,之前剛提出來的時候,是不兼容Android3.0以下的版本(話說現在已經沒有人使用3.0以下的手機了吧),爲了兼容低版本,就出現了v4包下的fragment,網絡上對fragment的使用一般都是v4包下fragment,對於app包下的fragment的使用不僅很少,而且都是教程不全,或者坑太多。此文對app包下的fragment做一個詳細的講解。對於fragment,我們可以簡單的理解爲,是在Activity中的Activity。它可以顯示在Activity中,顯示出自己的內容。但是fragment是依賴於Activity存在的,不能夠自己單獨存在,同樣的一個Activity中可以有多個fragment,而且一個fragment可以被多個Activity使用,擁有自己的生命週期,我們可以在Activity中動態的進行fragment的添加刪除。說到這裏,感覺有點像Android中include的使用了,但是include只是相當於告訴編譯器,這裏只是放入了一個佈局,去加載這個佈局,但是fragment是讓編譯器去實例化這個fragment。
2. Fragment與Activity的區別?
fragment與Activity都擁有自己的生命週期。
Activity的生命週期:
onCreate()-onStart()-onResume()-onPause()-onStop()-onDestroy()-onRestart()
fragment的生命週期:
onAttach()-onCreate()-onCreateView()-onActivityCreated()-onStart()-onResume()-onPause()- onStop()-onDestroyView()-onDestroy()-onDetach()
通過生命週期可以明顯的看出來fragment比activity的生命週期要多,同時一個activity就是一個activity,fragment的意思就是碎片,所謂碎片,就反應出來了fragment比activity靈活,好控制。
fragment的使用優勢有以下幾點:
- 模塊化:我們不需要把所有代碼全部都寫在Activity中,而是把代碼寫在各自的fragmen中,減少了代碼的複雜性,後期維護比較簡單。
- 可重性:多個Activity可以重用同一個fragment。
- 適配性:根據不同手機的尺寸,方向,可以實現不同的佈局,使客戶的體驗性更好。
3.Fragment的生命週期
生命週期前面我門已經看到了,這裏具體講一下各生命週期的區別:
先給張圖:
對於activity的生命週期想必大家都已經很熟悉了,這裏只介紹fragment的生命週期:
onAttach(Activity) 當Fragment與Activity發生關聯的時候調用,可以通過getArguments()獲取參數
onCreate():Fragment被創建時調用
onCreateView(LayoutInflater, ViewGroup, Bundle) 創建fragment佈局
onActivityCreated(Bundle) 加載佈局結束後調用
onStart():當Fragment可見調用。
onResume():當Fragment可見且可交互時調用。
onPause():當Fragment不可交互但可見時調用。
onStop():當Fragment不可見時調用。
onDestroyView() Fragment的佈局被移除時調用
onDestroy():銷燬Fragment時調用。
onDetach() Fragment和Activity解除關聯的時候調用
4.Fragment的簡單使用
fragment有兩種使用方法,一種是靜態使用,一種是動態使用。
靜態使用:
靜態使用就是在佈局的xml文件中添加name屬性去加載fragment,這種方式有一個缺點,就是在fragment運行的時候,不能夠進行刪除這個fragment,因此我們一般用動態加載就可以了。
(1):創建佈局文件fragment_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_one"
android:text="1111"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:id="@+id/btn_two"
android:text="2222"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:id="@+id/btn_three"
android:text="3333"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:id="@+id/btn_four"
android:text="4444"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
(2):創建一個類BaseFragment繼承Fragment,重寫onAttach方法:
public class BaseFragment extends Fragment {
public String TAG = getClass().getSimpleName();
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
}
(3):創建一個HomeFragment類,重寫onCreateView方法。進行fragment的具體操作,繼承上面創建的類BaseFragment(你們也可以直接創建HomeFragment類,重寫onAttach方法):
public class HomeFragment extends BaseFragment {
public HomeFragment(){
/*對於爲什麼要使用無參構造函數,是因爲當屏幕方向發生變化的時候,
會重新構造fragment,會優先調用fragment無參的構造方法,
如果參數是通過構造函數傳遞的,在重新構造fragment時,參數就會丟失。
如果要在fragment創建的時候就要傳入參數,不建議使用構造函數,
可以使用setArguments()方式進行添加,因爲如果fragment被系統殺掉再次恢復的時候,
能夠保留這些數據,後面將會介紹這種方法*/
}
/**
* 加載佈局時候調用
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// 1. 加載佈局,第三個參數必須爲`false`,否則會加載兩次佈局並且拋出異常!!
//原因:在fragment內部中,會將佈局添加到container中,如果設置爲true,就會重複兩個添加,報IllegalStateException異常
return inflater.inflate(R.layout.fragment_home,container,false);
}
}
(3):Acticity對應的佈局文件(注意name標籤,就是指定Activity加載哪一個fragment):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:name="com.example.dhd.fragmentdemo.fragment.HomeFragment"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</RelativeLayout>
(4):MainActivity對應代碼(網上很多人說使用app包下的fragment繼承Activity即可,我試了繼承Activity程序會直接崩潰,繼承AppCompatActivity或者FragmentActivity纔可以成功運行(AppCompatActivity是FragmentActivity的一個子類)。):
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initView();
}
}
運行效果:
動態使用:
對於動態加載的使用,我在使用的時候因爲不仔細,讓我自己煩惱了很長時間。
靜態加載的佈局文件中使用的標籤是fragment,而在動態加載中使用的標籤是FrameLayout。主要動態加載佈局文件不要使用fragment,否則你會和我一樣很苦惱爲什麼報錯而且找不到問題所在。
先看一下效果:
剛開始顯示的是fragment_home.xml,點擊跳轉後,顯示的是fragment_one.xml
(1):activity_main佈局文件:
注意是FrameLayout標籤
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_jump"
android:text="跳轉"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<FrameLayout
android:layout_below="@+id/btn_jump"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="200dp">
</FrameLayout>
</RelativeLayout>
(2):創建兩個fragment佈局文件:
fragment_home.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_home"
android:text="home"
android:layout_width="match_parent"
android:layout_height="40dp">
</Button>
</RelativeLayout>
fragment_one.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_one"
android:text="one"
android:layout_width="match_parent"
android:layout_height="40dp">
</Button>
</RelativeLayout>
(3):創建對應佈局文件的fragmentActivity:
BaseFragment
public class BaseFragment extends Fragment {
public String TAG = getClass().getSimpleName();
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
}
HomeFragment
public class HomeFragment extends BaseFragment{
public HomeFragment() {
}
/**
* 加載佈局時候調用
*
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// 1. 加載佈局,第三個參數必須爲`false`,否則會加載兩次佈局並且拋出異常!!
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
OneFragment
public class OneFragment extends BaseFragment {
public OneFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one,container,false);
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private HomeFragment homeFragment;
private Button btn_jump;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
showFragment();
btn_jump = (Button) findViewById(R.id.btn_jump);
btn_jump.setOnClickListener(this);
}
private void showFragment() {
//獲取FragmentManager管理對象,使用 getFragmentManager()方法已經過時,並且有錯誤。
fragmentManager = getSupportFragmentManager();
//獲取FragmentTransaction事物對象,並開啓事務
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//創建fragment對象
homeFragment = new HomeFragment();
//操作fragment,佈局ID,fragment對象,還有第三個參數(tag,可寫可不寫)tag作爲fragment的唯一標誌,可以通過Fragment1 frag = getSupportFragmentManager().findFragmentByTag("tag")從FragmentManager中查找Fragment對象。
fragmentTransaction.add(R.id.fragment, homeFragment);
//提交事務
fragmentTransaction.commit();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_jump:
OneFragment oneFragment = new OneFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//replace就是替換fragment中原有的fragment,將其替換爲oneFragment,最後不要忘記commit,否則會沒有效果
fragmentTransaction.replace(R.id.fragment,oneFragment).commit();
break;
}
}
}
靜態加載和動態加載的使用就是這樣了,在項目中一般都是用動態加載的方法,畢竟靜態加載的時候是不能刪除正在使用的fragment。
補充一下fragmentTransaction的幾種使用方法:
fragmentTransaction.add() 向Activity中添加一個Fragment
- transaction.remove()
從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧(回退棧後面會詳細說),這個Fragment實例將會被銷燬 - fragmentTransaction.replace() 使用另一個Fragment替換當前的,實際上就是remove()然後add()的合體
- fragmentTransaction.hide() 隱藏當前的Fragment,僅僅是設爲不可見,並不會銷燬
- fragmentTransaction.show() 顯示之前隱藏的Fragment
- detach() 會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護
- attach() 重建view視圖,附加到UI上並顯示
fragmentTransaction.commit() 提交事務
注意:在add/replace/hide/show以後都要提交事務其效果纔會在屏幕上顯示出來
提交事務有四種方式:
1.commit():
- 當你調用commit()的時候, FragmentManger會檢查是否已經存儲了它自己的狀態, 如果已經存在, 就拋出IllegalStateException,同樣說明每個事務只能存在一次,如果你再重新重新創建一個事務,再去提交,這個時候是沒有問題的。
- 一旦調用這個方法, 這個commit()並不是立即執行的, 它會被髮送到主線程的任務隊列當中去, 當主線程準備好執行它的時候執行
- Activity執行完onSaveInstanceState()方法後不能再執行commit()方法
2.commitAllowingStateLoss():
- 當你調用commitAllowingStateLoss()的時候, FragmentManger不會檢查是否已經存儲了它自己的狀態, 也就不會拋出IllegalStateException.有效的解決了commit()提交時出現的問題。
3.commitNow():
- 當你調用commitNow()時,將會立即執行並且只會執行你當前要提交的transaction。
- 從v24.0.0開始提供了 commitNow()方法,在之前開發者會在commit()調用之後加上 executePendingTransactions()來保證立即執行, 即變異步爲同步,但是這樣會將所有pending在隊列中還有你新提交的transactions都執行了,而commitNow()就避免那些你可能並不想執行的transactions。
4.commitNowAllowingStateLoss():
- 當你調用commitNowAllowingStateLoss()的時候, FragmentManger不會檢查是否已經存儲了它自己的狀態, 也就不會拋出IllegalStateException,並且會立即執行。
5.Fragment的回退棧
Fragment的回退棧是用來保存每一次Fragment事務發生的變化 如果你將Fragment任務添加到回退棧,當用戶點擊後退按鈕時,將看到上一次的保存的Fragment。一旦Fragment完全從後退棧中彈出,用戶再次點擊後退鍵,則退出當前Activity。官方的說法就是就是你在點擊後退鍵的時候,到底要不要顯示上一個fragment.
要把fragment添加到回退棧,需要學會一個方法:
FragmentTransaction.addToBackStack(String)
下面用案列進行演示:
先看一下效果圖:
我默認第一個Activity打開homeFragment,在輸入框內輸入111.點擊HOME,將HomeFragment覆蓋爲OneFragment,輸入222,點擊ONE,將OneFragment覆蓋爲TwoFragment,點擊返回鍵,返回到OneFragment,可以看到輸入框上面還有,再次點擊返回鍵,返回到HomeFragment,輸入框有222。這裏我們再次點擊到最後一個fragment,點擊two,跳轉到第二個Activity.
先來看一下文件目錄:
下面來看代碼:
fragment_home.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_home"
android:text="home"
android:layout_width="match_parent"
android:layout_height="40dp">
</Button>
<EditText
android:id="@+id/et_home"
android:layout_below="@+id/btn_home"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</RelativeLayout>
activity_main.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="200dp">
</FrameLayout>
</RelativeLayout>
fragment_one.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_one"
android:text="one"
android:layout_width="match_parent"
android:layout_height="40dp">
</Button>
<EditText
android:id="@+id/et_one"
android:layout_below="@+id/btn_one"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</RelativeLayout>
fragment_two.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_two"
android:text="two"
android:layout_width="match_parent"
android:layout_height="40dp">
</Button>
<EditText
android:id="@+id/et_two"
android:text="已經到最後一個fragment了"
android:layout_below="@+id/btn_two"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
</RelativeLayout>
activity_second.xml佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<TextView
android:text="第二個Activity"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private HomeFragment homeFragment;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
showFragment();
}
private void showFragment() {
//獲取FragmentManager管理對象
fragmentManager = getSupportFragmentManager();
//獲取FragmentTransaction事物對象,並開啓事務
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//創建fragment對象
homeFragment = new HomeFragment();
//操作fragment,佈局ID,fragment對象
fragmentTransaction.add(R.id.fragment, homeFragment);
//提交事務
fragmentTransaction.commit();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
}
}
}
BaseFragment:
public class BaseFragment extends Fragment {
public String TAG = getClass().getSimpleName();
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
}
HomeFragment:
public class HomeFragment extends BaseFragment implements View.OnClickListener {
private Button btn_home;
public HomeFragment() {
}
/**
* 加載佈局時候調用
*
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// 1. 加載佈局,第三個參數必須爲`false`,否則會加載兩次佈局並且拋出異常!!
View v = inflater.inflate(R.layout.fragment_home, container, false);
btn_home = v.findViewById(R.id.btn_home);
btn_home.setOnClickListener(this);
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_home:
Log.e(TAG,"點擊了home");
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
OneFragment oneFragment = new OneFragment();
fragmentTransaction.replace(R.id.fragment,oneFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
/**
* 加載佈局結束後調用
*
* @param savedInstanceState
*/
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
/**
* Fragment的佈局被移除時調用
*/
@Override
public void onDestroyView() {
super.onDestroyView();
}
/**
* Fragment和Activity解除關聯的時候調用
*/
@Override
public void onDetach() {
super.onDetach();
}
}
OneFragment:
public class OneFragment extends BaseFragment implements View.OnClickListener {
private Button btn_one;
public OneFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
btn_one = v.findViewById(R.id.btn_one);
btn_one.setOnClickListener(this);
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_one:
FragmentManager fragmentManager = getFragmentManager();
TwoFragment twoFragment = new TwoFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment,twoFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
}
TwoFragment:
public class TwoFragment extends BaseFragment implements View.OnClickListener {
private Button btn_two;
public TwoFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_two, container, false);
btn_two = v.findViewById(R.id.btn_two);
btn_two.setOnClickListener(this);
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_two:
//fragment跳轉到Activity與平常不同,注意一下
startActivity(new Intent(getActivity(), SecondActivity.class));
break;
}
}
}
SecondActivity:
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
6.Fragment的通信
fragment的通信有三種情況,這三種情況都可以用EventBus進行傳值。使用傳統的方式太麻煩。
EventBus的使用請參考我的另一邊博客
EventBus使用超鏈接
當我們使用EvensBus的時候,有時候收到消息的活動,可能還沒有加載,也就是沒有進行註冊EventBus,這個時候我們使用普通的發送消息是不行的,我們需要使用EventBus的粘性事件。
建議不會使用EventBus或者不會使用EventBus粘性事件的先去上面的鏈接學習一下。
- Fragment向Activity傳遞數據
- Activity向Fragment傳遞數據
- Fragment之間傳遞數據
補充一下,本來Event的名字FA代表fragment向Activity傳遞數據,後來發現AF和FA弄反了,大家湊合看吧。
將他們寫到了一起,先來看看效果。
首先剛啓動的時候我使用EventBus在Activity中發送了粘性事件,默認啓動HomeFragment,啓動的時候註冊EventBus,將1111傳遞到HomeFragment中(Activity向Fragment傳遞數據),在HomeFragment中我點擊home,發送粘性事件,將2222傳遞到OneFragment(Fragment之間傳遞數據)。當我點擊two的時候,將3333傳遞到SecondActivity(Fragment向Activity傳遞數據)。
下面來看代碼:
根據上面的回退棧的代碼做了一些修改,只發布修改的地方
目錄:
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private HomeFragment homeFragment;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
showFragment();
}
private void showFragment() {
//發佈粘性事件
EventBus.getDefault().postSticky(new FAEvetn("1111"));
//獲取FragmentManager管理對象
fragmentManager = getSupportFragmentManager();
//獲取FragmentTransaction事物對象,並開啓事務
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//創建fragment對象
homeFragment = new HomeFragment();
//操作fragment,佈局ID,fragment對象
fragmentTransaction.add(R.id.fragment, homeFragment);
//提交事務
fragmentTransaction.commit();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
HomeFragment:
public class HomeFragment extends BaseFragment implements View.OnClickListener {
private Button btn_home;
private EditText et_home;
public HomeFragment() {
}
/**
* 加載佈局時候調用
*
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// 1. 加載佈局,第三個參數必須爲`false`,否則會加載兩次佈局並且拋出異常!!
View v = inflater.inflate(R.layout.fragment_home, container, false);
btn_home = v.findViewById(R.id.btn_home);
et_home = v.findViewById(R.id.et_home);
btn_home.setOnClickListener(this);
if(!EventBus.getDefault().isRegistered(this)){
EventBus.getDefault().register(this);
}
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_home:
//發佈粘性事件
EventBus.getDefault().postSticky(new FFEvetn("2222"));
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
OneFragment oneFragment = new OneFragment();
fragmentTransaction.replace(R.id.fragment,oneFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
/**
* 接收來自MainActivity的粘性事件
* @param faEvetn
*/
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void faEvent(FAEvetn faEvetn) {
et_home.setText(faEvetn.fa);
}
@Override
public void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
/**
* 加載佈局結束後調用
*
* @param savedInstanceState
*/
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
/**
* Fragment的佈局被移除時調用
*/
@Override
public void onDestroyView() {
super.onDestroyView();
}
/**
* Fragment和Activity解除關聯的時候調用
*/
@Override
public void onDetach() {
super.onDetach();
}
}
OneFragment:
public class OneFragment extends BaseFragment implements View.OnClickListener {
private Button btn_one;
private EditText et_one;
public OneFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
btn_one = v.findViewById(R.id.btn_one);
et_one = v.findViewById(R.id.et_one);
btn_one.setOnClickListener(this);
EventBus.getDefault().register(this);
return v;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_one:
FragmentManager fragmentManager = getFragmentManager();
TwoFragment twoFragment = new TwoFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment, twoFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
/**
* 接收來自HomeFragment的粘性事件
* @param ffEvetn
*/
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void faEvent(FFEvetn ffEvetn) {
et_one.setText(ffEvetn.ff);
}
@Override
public void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}
SecondActivity:
public class SecondActivity extends AppCompatActivity {
private TextView tv_second_show;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initView();
EventBus.getDefault().register(this);
}
private void initView() {
tv_second_show = (TextView) findViewById(R.id.tv_second_show);
}
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void afEvent(AFEvrnt afEvrnt){
tv_second_show.setText(afEvrnt.af);
}
@Override
protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}
activity_second.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<TextView
android:id="@+id/tv"
android:text="第二個Activity"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</TextView>
<TextView
android:layout_below="@+id/tv"
android:id="@+id/tv_second_show"
android:textColor="@color/colorAccent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
FAEvent:
public class FAEvetn {
public String fa;
public FAEvetn(String fa) {
this.fa = fa;
}
}
FFEvent:
public class FFEvetn {
public String ff;
public FFEvetn(String ff) {
this.ff = ff;
}
}
AFEvrnt:
public class AFEvrnt {
public String af;
public AFEvrnt(String af) {
this.af = af;
}
}
fragment的使用暫時就先介紹到這裏有啥錯誤或者不對的地方歡迎提出。下面附上源代碼下載地址:
鏈接:https://pan.baidu.com/s/14OcE_ZZzNesi5tIevWw7Rw
提取碼:h4tz