[Java][Android Studio] Navigation實作圖形化切換Fragment頁面(一)

快看看那個!我真的需要那酷東西!Fragment切換有圖形化了

使用Navigation套件需要你的Android Studio版本在3.3以上,並且要支援Java8官方說明文件

要先在 build.gradle(Module:app) 匯入依賴,好了之後點選右上角的Sync Now來匯入套件

(如果你是Java那就不用匯入Kotlin套件,反之亦然,都匯入也沒關西)

def nav_version = "2.3.5"

// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"

// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

// Feature module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

// Testing Navigation
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"

// Jetpack Compose Integration
implementation "androidx.navigation:navigation-compose:1.0.0-alpha10"

好了之後在右側res資料夾上面按滑鼠右鍵>New>Android Resource File

輸入檔名,這裡用nav_graph做示範

然後點選Resource type下拉選單選擇Navigation

之後點擊OK

就會發現他幫我們建立一個資料夾和檔案,並且自動開啟

我們先去建立兩個Fragment,這樣之後才能練習切換

對者左側的MainActivity按下滑鼠右鍵>New>Java Class

這裡就叫MainFragment好了,輸入完成後按下Enter

繼承Fragment,然後輸入程式碼
public MainFragment(){
super(R.layout.fragment_main);
}

這時候fragment_main會是紅線,有錯誤。

這裡是要告訴他我們Fragment的布局長怎樣,只是我們還沒有建立

滑鼠游標移動到fragment_main上面按下快捷鍵Alt+Enter,點選第一個Create layout resource file "fragment_main.xml",讓他快速幫我們建立

看兩眼後直接按下OK
就建立好了
隨便拉一個TextView,輸入fragment_main,方便我們判斷到底切換了沒


還記得我說要建立兩個Fragment嗎?
同樣的步驟再做一次,這次名稱叫做RuyutFragment好了^^
那我們layout就叫fragment_ruyut比較好辨認(這次就不截圖了
附上程式碼:
public class RuyutFragment extends Fragment {
public RuyutFragment(){
super(R.layout.fragment_ruyut);
}
}

然後我們到activity_main.xml,建立FragmentContainerView,這是讓之後Fragment顯示的容器

切換到Split顯示模式,貼上程式碼:

<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />



終於可以回到nav_graph.xml了,點選上面的New Destination,選擇我們剛剛建立的MainFragment


然後再做一次新增RuyutFragment,之後把滑鼠游標移動到mainFragment上面的小圓點,滑鼠左鍵按住不放拖曳到ruyutFragment上面,他們就連在一起了



執行之後會再App上面看到mainFragment是因為「房子」(起始目標)在他身上,也可以選擇ruyutFragment之後點選上面的Assign start destination,把「房子」給他

再次執行就會發現首頁不同了


所以,到底要怎麼跳轉?

喔喔對哄,到fragment_ruyut.xml,拉個button

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fragment_ruyut"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
</androidx.constraintlayout.widget.ConstraintLayout>

回到RuyutFragment,Ctrl+O叫出複寫視窗選擇onViewCreated按下OK


利用祖傳findViewById找到按鈕,替按鈕加上點擊事件(我會努力找時間會寫一篇View Binding,讓大家不用再findViewById的...)

然後就是這次的重點,跳轉頁面(現在首頁是ruyutFragment,所以是要跳轉到mainFragment喔)

Navigation.findNavController(view).navigate(R.id.mainFragment);

好啦先附上整個複寫的程式碼,怕有人遇到問題

Button button = view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(view).navigate(R.id.mainFragment);
}
});

執行APP,Ya!成功了,這裡還有更簡單的寫法,六行直接變一行

button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.mainFragment, null));

ㄜ可是雖然比較短,但是好像沒有比用Intent厲害多少啊

(Intent切換頁面可以看這篇:Intent換Activity)

阿那是因為時間不夠啦,不然還可以加上Safe Args達成安全切換(帶值)

還有自動切換、循環邏輯判斷...等等

我會快點補上拉,希望大家留言鼓勵我一下...

留言