Heyyoo gengs! Kembali bersama saya. Kali ini saya ingin meimplementasikan Navigation Component pada Kotlin.
Komponen Navigasi Android Jetpack berfungsi untuk membantu mengimplementasikan navigasi, dari klik tombol sederhana hingga pola yang lebih kompleks, seperti bilah aplikasi dan panel navigasi. Komponen Navigasi juga memastikan pengalaman pengguna yang konsisten dan dapat diprediksi dengan mengikuti seperangkat prinsip yang telah ditetapkan .
Implementasi Navigation
- Add Dependency navigation
def nav_version = “2.3.4” // Kotlin implementation “androidx.navigation:navigation-fragment-ktx:$nav_version” implementation “androidx.navigation:navigation-ui-ktx:$nav_version” |
- Buat Fragment dengan memilih Fragment Blank.
Lalu Finish
Lalu hapus bagian yang tidak digunakan dengan menyisakan codingan seperti berikut:
class MainFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_main2, container, false) } } |
Fragment yang telah dibuat:
- Membuat desain layout
- Layout MainFragment
Tambahkan komponen yang dibutuhkan pada masing-masing fragment, dan tambahkan button untuk mentrigger navigasi.
Dengan codingan seperti ini:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent”> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:orientation=”vertical” tools:context=”.MainFragment”> <TextView android:id=”@+id/etEmail” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:layout_marginBottom=”20dp” android:hint=”Email” /> <TextView android:id=”@+id/etPass” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:hint=”Password” /> <Button android:id=”@+id/btnLogin” android:text=”Login” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” /> <Button android:id=”@+id/btnRegister” android:text=”Register” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” /> </LinearLayout> </RelativeLayout> |
Lalu buat drawable untuk memperindah tampilan:
- border_gray
- background_blue
Selanjutnya implementasi drawable border_gray pada MainFragment yang diletakan pada text_view:
android:background=”@drawable/border_gray” |
dan implementasi drawable background_blue pada button:
android:background=”@drawable/background_blue” |
Tampilan akhir:
Codingan akhir:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent”> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:orientation=”vertical” tools:context=”.MainFragment”> <TextView android:id=”@+id/etEmail” android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:inputType=”textEmailAddress” android:padding=”10dp” android:textSize=”14sp” android:background=”@drawable/border_gray” android:layout_marginBottom=”20dp” android:hint=”Email” /> <TextView android:id=”@+id/etPassword” android:layout_width=”match_parent” android:layout_height=”50dp” android:inputType=”textPassword” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:padding=”10dp” android:textSize=”14sp” android:background=”@drawable/border_gray” android:hint=”Password” /> <androidx.appcompat.widget.AppCompatButton android:id=”@+id/btnLogin” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:textColor=”@android:color/white” android:background=”@drawable/background_blue” android:text=”Login” android:layout_marginTop=”20dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” /> <androidx.appcompat.widget.AppCompatButton android:id=”@+id/btnRegister” android:text=”Register” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:textColor=”@android:color/white” android:background=”@drawable/background_blue” android:layout_marginTop=”10dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” /> </LinearLayout> </RelativeLayout> |
- Layout Register1
Membuat tampilan layout seperti dibawah
Dengan codingan seperti ini:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”.Register1Fragment”> <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:drawableStart=”@drawable/ic_back” android:padding=”50dp” android:text=”Step 1″ android:textColor=”@color/black” android:textSize=”30sp” /> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:orientation=”vertical” tools:context=”.MainFragment”> <TextView android:id=”@+id/etName” android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:layout_marginBottom=”20dp” android:background=”@drawable/border_gray” android:hint=”Name” android:padding=”10dp” android:textSize=”14sp” /> <TextView android:id=”@+id/etEmail” android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:background=”@drawable/border_gray” android:hint=”Email” android:inputType=”textPassword” android:padding=”10dp” android:textSize=”14sp” /> <androidx.appcompat.widget.AppCompatButton android:id=”@+id/btnNext” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginTop=”20dp” android:layout_marginEnd=”30dp” android:background=”@drawable/background_blue” android:text=”Next” android:textColor=”@android:color/white” /> </LinearLayout> </RelativeLayout> |
- Layout Register2
Source Code:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”.Register1Fragment”> <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:drawableStart=”@drawable/ic_back” android:padding=”50dp” android:text=”Step 2″ android:textColor=”@color/black” android:textSize=”30sp” /> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:orientation=”vertical” tools:context=”.MainFragment”> <TextView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”Halo $etName1 untuk melanjutkan register silahkan mengisi password” android:layout_marginBottom=”20dp” android:textColor=”@color/black” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” /> <EditText android:id=”@+id/etPassword2″ android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:layout_marginBottom=”20dp” android:inputType=”textPassword” android:background=”@drawable/border_gray” android:hint=”Password” android:padding=”10dp” android:textSize=”14sp” /> <EditText android:id=”@+id/etConfirmPassword2″ android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:background=”@drawable/border_gray” android:hint=”Confirmation Password” android:inputType=”textPassword” android:padding=”10dp” android:textSize=”14sp” /> <androidx.appcompat.widget.AppCompatButton android:id=”@+id/btnFinish” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginTop=”20dp” android:layout_marginEnd=”30dp” android:background=”@drawable/background_blue” android:text=”Finish” android:textColor=”@android:color/white” /> </LinearLayout> </RelativeLayout> |
- Layout ResultFragment
Source Code:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”.Register1Fragment”> <TextView android:layout_width=”match_parent” android:layout_height=”wrap_content” android:drawableStart=”@drawable/ic_back” android:padding=”50dp” android:text=”Result” android:textColor=”@color/black” android:textSize=”30sp” /> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:orientation=”vertical” tools:context=”.MainFragment”> <TextView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”Congratulations” android:textSize=”20sp” android:layout_gravity=”center_horizontal” android:layout_marginBottom=”20dp” android:textColor=”@color/black” /> <TextView android:id=”@+id/tvName” android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:layout_marginBottom=”20dp” android:background=”@drawable/border_gray” android:hint=”Name” android:padding=”10dp” android:textSize=”14sp” /> <TextView android:id=”@+id/tvEmail” android:layout_width=”match_parent” android:layout_height=”50dp” android:layout_marginStart=”30dp” android:layout_marginEnd=”30dp” android:background=”@drawable/border_gray” android:hint=”Confirmation Password” android:inputType=”textPassword” android:padding=”10dp” android:textSize=”14sp” /> <androidx.appcompat.widget.AppCompatButton android:id=”@+id/btnBacktoLogin” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_marginStart=”30dp” android:layout_marginTop=”20dp” android:layout_marginEnd=”30dp” android:background=”@drawable/background_blue” android:text=”Back to Login” android:textColor=”@android:color/white” /> </LinearLayout> </RelativeLayout> |
- Layout HomeFragment
Source Code:
<?xml version=”1.0″ encoding=”utf-8″?> <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” xmlns:tools=”http://schemas.android.com/tools” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”.HomeFragment”> <TextView android:id=”@+id/tvWelcome” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_centerInParent=”true” android:gravity=”center_horizontal” android:text=”Welcome” android:textColor=”@color/black” android:textSize=”20sp” /> <TextView android:id=”@+id/tvEmail” android:layout_width=”match_parent” android:layout_height=”wrap_content” android:layout_below=”@id/tvWelcome” android:layout_centerInParent=”true” android:layout_marginTop=”20dp” android:gravity=”center_horizontal” android:text=”Email” android:textColor=”@color/black” android:textSize=”20sp” /> </RelativeLayout> |
- Navigation Graph dan Navigation Host
- Navigation Graph
Navigation Graph adalah file resource yang berisi semua tujuan dan tindakan Anda. Graph tersebut mewakili semua jalur navigasi aplikasi Anda. Jadi Navigation Graph salah satu 3 kunci utama dari jetpack navigation component.
Langkah membuatnya: Create nav_graph.xml, res -> New -> Android Resource File -> set
Resource type Navigation -> beri nama nav_graph -> OK
- Navigation Host
Menambahkan navigation host di activty_main.
<fragment 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” /> |
- Design Navigation Graph
- Menambahkan Destination pada nav_graph. Dengan cara klik dibagian New Destination, lalu masukan semua destinasi dari layout yang dibuat tadi.
- Lalu buat flow dari masing-masing destination
- Implementation Navigation
Langkah-langkah:
- Membuat aksi pada button
Dengan menambahkan function onActivityCreated, disini tempat dimana semua aksi dibuat.
override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) btnLogin.setOnClickListener { Navigation.findNavController(it) .navigate(R.id.action_mainFragment2_to_homeFragment2) } btnRegister.setOnClickListener { Navigation.findNavController(it) .navigate(R.id.action_mainFragment2_to_register1Fragment2) } } |
- Lakukan hal yang sama pada button lainnya.
- Dan tambahkan aksi back jika dibutuhkan.
back.setOnClickListener { Navigation.findNavController(it) .navigate(R.id.action_register1Fragment2_to_mainFragment2) } |
- Dan lalukan juga pada Fragment lainnya seperti (Register1Fragment, Register2Fragment, ResultFragment)
Source Code Akhir:
class Register1Fragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_register1, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) btnNext.setOnClickListener{ Navigation.findNavController(it) .navigate(R.id.action_register1Fragment2_to_register2Fragment2) } back.setOnClickListener { Navigation.findNavController(it) .navigate(R.id.action_register1Fragment2_to_mainFragment2) } } } |
- Animation Navigation
Animation Navigation ini digunakan supaya aplikasi menjadi smooth dan enak dilihat.
- Membuat xml Animation Navigation
Add package anim, klik kanan package res -> New -> Directory
Create animation, klik kanan package anim -> New -> Animation resource file
lalu buat Animation resource file dengan nama:
- slide_in_left.xml
- slide_in_right.xml
- slide_out_left.xml
- slide_out_right.xml
Dengan source code:
- slide_in_left
<translate android:fromXDelta=”-100%” android:toXDelta=”0%” android:fromYDelta=”0%” android:toYDelta=”0%” android:duration=”400″/> |
- slide_in_right
<translate android:fromXDelta=”100%” android:toXDelta=”0%” android:fromYDelta=”0%” android:toYDelta=”0%” android:duration=”400″/> |
- slide_out_left
<translate android:fromXDelta=”0%” android:toXDelta=”-100%”
<translate android:fromXDelta=”100%” android:toXDelta=”0%” android:fromYDelta=”0%” android:toYDelta=”0%” android:duration=”400″/> |
- slide_out_right
<translate android:fromXDelta=”0%” android:toXDelta=”100%” android:fromYDelta=”0%” android:toYDelta=”0%” android:duration=”400″/> |
- Implementasi
Menambahkan animation dibagian action di nav_graph
<action android:id=”@+id/action_mainFragment_to_viewAnotherFragment” app:destination=”@id/viewAnotherFragment” app:popEnterAnim=”@anim/slide_in_left” app:popExitAnim=”@anim/slide_out_right” app:enterAnim=”@anim/slide_in_right” app:exitAnim=”@anim/slide_out_left”/> |
- Passing Data
Melakukan navigasi dengan membawa data pada fragment sebelumnya dan dibawa ke fragment tujuan.
- Passing Data Register1 ke Register2.
- Buat variable bundle yang akan menampung datanya di Register1.
val bundle = bundleOf(“name” to etName1.text.toString(), “email” to etEmail1.text.toString()) |
- Lalu buat panggil variable bundle dibagian navigation
Navigation.findNavController(it) .navigate(R.id.action_register1Fragment2_to_register2Fragment2, bundle) |
- Lalu buat validasi jika button next diklik tetapi datanya tidak diinputkan, maka akan mucul pesan error, setelah itu masukan variable bundle dan navigation tadi.
btnNext.setOnClickListener{ if (etName1.text.toString().isEmpty()){ etName1.error = “Nama harus diisi” }else if (etEmail1.text.toString().isEmpty()){ etEmail1.error = “Email harus diisi” }else{ val bundle = bundleOf(“name” to etName1.text.toString(), “email” to etEmail1.text.toString()) Navigation.findNavController(it) .navigate(R.id.action_register1Fragment2_to_register2Fragment2, bundle) } } |
- Setelah itu panggil data yang telah diinputkan ke Register2.Dengan membuat variable global terlebih dahulu di Register2, untuk menampung datanya.
var get_name : String? = null var get_email : String? = null |
- Lalu panggil.
get_name = arguments?.getString(“name”) get_email = arguments?.getString(“email”) |
- Passing Data Register2 ke ResultFragment
- Buat terlebih dahulu validasi ketika password tidak diisi maka muncul pesan error di button Finnish (Register2).
if(etPassword2.text.toString().isEmpty()){ etPassword2.error = “Password harus diisi” }else if (etConfirmPassword2.text.toString().isEmpty()){ etConfirmPassword2.error = “Confirmation Password harus diisi” } |
- Setelah itu buat validasi password sama atau tidak sama. Jika sama maka akan pindah ke ResultFragment, jika tidak maka akan memunculkan Toast.
else{ if(etPassword2.text.toString().equals(etConfirmPassword2.text.toString())){ Navigation.findNavController(it) .navigate(R.id.action_register2Fragment2_to_resultFragment2) }else{ Toast.makeText(context, “Password tidak sama dengan Confirmation Password”, Toast.LENGTH_LONG).show() } } |
- Lalu buat variable untuk menampun data yang berisi nama, email dan password. Serta panggil variable tersebut dibagian navigate.
val bundle = bundleOf(“name” to get_email, “email” to get_email, “password” to etPassword2.text.toString()) Navigation.findNavController(it) .navigate(R.id.action_register2Fragment2_to_resultFragment2, bundle) |
- Kemudian panggil datanya di ResultFragment. Dengan membuat variable global terlebih dahulu.
var get_name: String? = nullvar get_email: String? = null |
- Lalu panggil variable global tadi di bagian onActivityCreated.
get_name = arguments?.getString(“name”) get_email = arguments?.getString(“email”) |
- Setelah itu tampilkan nama dan email nya.
tvName.text = get_name tvEmail.text = get_email |
- Bottom Navigation
- Implementation Bottom Navigation 1
menambah botton navigation di home dengan mengganti homefragment menjadi activity
dengan menambahkan activity HomeActivity dan menambah 2 fragment BerandaFragment dan NoteFragment sebagai bottomnya
selanjutnya tambahkan bottom navigation component dibagian design BottomNavigationView di activity_home.xml. lalu atur layout_width 0dp dan layout_height wrap_content
lalu buat Android Resource File dengan nama nav_bottom.xml sebagai menu
lalu tambahkan gambar vector asset untuk bottom dari beranda dan note.
dengan cara tambahkan di drawable
selanjutnya kita akan menambahkan menu di nav_bottom.xml tersebut
<item android:icon=”@drawable/ic_home” android:title=”Beranda” /> <item android:icon=”@drawable/ic_notes” android:title=”Note” /> |
lalu panggil bottom nav_bottom dibagian activity_home.xml
app:menu=”@menu/nav_bottom” |
maka akan muncul seperti ini
- Implementation Bottom Navigation 2
selanjutnya buat navigation graph untuk activity_home.xml
dengan cara membuat menu resource file dengan nama home_nav_graph.xml
lalu pindahkan source code dari fragment_home.xml ke fragment_beranda.xml
lalu hapus HomeFragment dan layout fragment_home.xml
selanjutnya tambahkan navigation host di HomeActivity.
dengan cara masuk ke layout dari HomeActivity, di activity_home.xml
lalu masukan NavHostFragment dan pilih home_nav_graph untuk navigationnya
lalu set seperti ini
setelah itu tambahkan destination pada home_nav_graph.xml
pilih berandaFragment dan noteFragment
lalu masuk ke layout nav_graph.xml
tambahkan destination homeActivity dan beri flow mainFragment ke homeActivity
selanjutnya tambahkan id di nav_bottom.xml dari masing-masing fragment
<item android:id=”@+id/berandaFragment” android:icon=”@drawable/ic_home” android:title=”Beranda” /> <item android:id=”@+id/noteFragment” android:icon=”@drawable/ic_notes” android:title=”Note” /> |
setelah itu set navigate bottom navigation di HomeActivity.
val navController = Navigation.findNavController(this,R.id.home_nav_host_fragment) NavigationUI.setupWithNavController(btmNavigation, navController) |
Lalu Jalankan
- Menu
- Register step 1
- Register step 2
- Register result