Codelab Flexible Fragment di Satu Activity
Selanjutnya kita akan mencoba untuk membuat fragment baru yang fleksibel. Kencangkan sabukmu. Get ready and Go!
- Dengan cara yang sama seperti sebelumnya, buat fragment baru dengan nama CategoryFragment . Jangan lupa untuk uncheck pilihan untuk generate default methods dan callbacks.
- Pada fragment_category silakan kondisikan kode Anda menjadi seperti berikut:
- <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="match_parent"
- android:orientation="vertical"
- android:padding="16dp">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/this_category" />
- <Button
- android:id="@+id/btn_detail_category"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/category_lifestyle" />
- </LinearLayout>
Selesai dengan layout xml, kini pada berkas CategoryFragment modifikasi kodenya menjadi sebagai berikut:
- class CategoryFragment : Fragment(), View.OnClickListener {
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- // Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_category, container, false)
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val btnDetailCategory:Button = view.findViewById(R.id.btn_detail_category)
- btnDetailCategory.setOnClickListener(this)
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_detail_category) {
- }
- }
- }
- public class CategoryFragment extends Fragment implements View.OnClickListener {
- public CategoryFragment() {
- }
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_category, container, false);
- }
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- Button btnDetailCategory = view.findViewById(R.id.btn_detail_category);
- btnDetailCategory.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_detail_category){
- }
- }
- }
- Sama seperti sebelumnya, kita siapkan onClick untuk modul berikutnya yaitu "Mengirim Data Antar Fragment".
- Sekarang kembali pada HomeFragment . Tambahkan baris berikut pada metode onClick()
- override fun onClick(v: View) {
- if (v.id == R.id.btn_category) {
- val mCategoryFragment = CategoryFragment()
- val mFragmentManager = fragmentManager
- mFragmentManager?.beginTransaction()?.apply {
- replace(R.id.frame_container, mCategoryFragment, CategoryFragment::class.java.simpleName)
- addToBackStack(null)
- commit()
- }
- }
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_category) {
- CategoryFragment mCategoryFragment = new CategoryFragment();
- FragmentManager mFragmentManager = getFragmentManager();
- if (mFragmentManager != null) {
- mFragmentManager
- .beginTransaction()
- .replace(R.id.frame_container, mCategoryFragment, CategoryFragment.class.getSimpleName())
- .addToBackStack(null)
- .commit();
- }
- }
- }
Sehingga kode dari HomeFragment menjadi seperti ini
- class HomeFragment : Fragment(), View.OnClickListener {
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- // Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_home, container, false)
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val btnCategory:Button = view.findViewById(R.id.btn_category)
- btnCategory.setOnClickListener(this)
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_category) {
- val mCategoryFragment = CategoryFragment()
- val mFragmentManager = fragmentManager
- mFragmentManager?.beginTransaction()?.apply {
- replace(R.id.frame_container, mCategoryFragment, CategoryFragment::class.java.simpleName)
- addToBackStack(null)
- commit()
- }
- }
- }
- }
- public class HomeFragment extends Fragment implements View.OnClickListener {
- public HomeFragment() {
- // Required empty public constructor
- }
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_home, container, false);
- }
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- Button btnCategory = view.findViewById(R.id.btn_category);
- btnCategory.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_category) {
- CategoryFragment mCategoryFragment = new CategoryFragment();
- FragmentManager mFragmentManager = getFragmentManager();
- if (mFragmentManager != null) {
- mFragmentManager
- .beginTransaction()
- .replace(R.id.frame_container, mCategoryFragment, CategoryFragment.class.getSimpleName())
- .addToBackStack(null)
- .commit();
- }
- }
- }
- }
- Setelah selesai, silakan jalankan aplikasi lagi. Klik tombol Ke Fragment Category. Aplikasi sudah berpindah tampilan tanpa berpindah activity.
Bedah Kode
FragmentTransaction
Anda telah belajar bagaimana berpindah tampilan tanpa harus berpindah activity. Jadi mudah kan dengan fragment? Mari kita breakdown satu demi satu hal yang baru saja Anda tulis:
Dimulai dari kode di dalam HomeFragment:
Dimulai dari kode di dalam HomeFragment:
- val mCategoryFragment = CategoryFragment()
- val mFragmentManager = fragmentManager
- mFragmentManager?.beginTransaction()?.apply {
- replace(R.id.frame_container, mCategoryFragment, CategoryFragment::class.java.simpleName)
- addToBackStack(null)
- commit()
- }
- CategoryFragment mCategoryFragment = new CategoryFragment();
- FragmentManager mFragmentManager = getFragmentManager();
- if (mFragmentManager != null) {
- mFragmentManager
- .beginTransaction()
- .replace(R.id.frame_container, mCategoryFragment, CategoryFragment.class.getSimpleName())
- .addToBackStack(null)
- .commit();
- }
Berbeda dengan Activity yang memanfaatkan supportFragmentManager, Fragment menggunakan fragmentManager untuk mendapatkan FragmentManager. Setelah mendapatkannya, Anda dapat memulai transaksi pergantian fragment.
Apa yang beda di sini? Pastinya kita menggunakan method replace() dan bukan add() ketika ingin menempelkan sebuah fragment baru. Ya, dengan parameter input yang sama pada method add(), method replace() akan mengganti objek fragment yang sedang tampil saat ini, yaitu HomeFragment dengan objek fragment yang baru, yaitu CategoryFragment.
addToBackStack
Anda pasti bertanya kenapa ada .addToBackStack(null) setelahnya? Kita menggunakannya karena objek fragment yang saat ini diciptakan masuk ke dalam sebuah fragment stack. Nantinya ketika kita tekan tombol back, ia akan pop-out keluar dari stack dan menampilkan objek fragment sebelumnya HomeFragment.
Nah, mari kita coba menghilangkan addToBackStack pada kode sebelumnya, maka akan menjadi seperti ini:
- val mCategoryFragment = CategoryFragment()
- val mFragmentManager = fragmentManager
- mFragmentManager?.beginTransaction()?.apply {
- replace(R.id.frame_container, mCategoryFragment, CategoryFragment::class.java.simpleName)
- commit()
- }
- CategoryFragment mCategoryFragment = new CategoryFragment();
- FragmentManager mFragmentManager = getFragmentManager();
- if (mFragmentManager != null) {
- mFragmentManager
- .beginTransaction()
- .replace(R.id.frame_container, mCategoryFragment, CategoryFragment.class.getSimpleName())
- .commit();
- }
Jika Anda menghapus baris addToBackStack, menjalankan ulang aplikasi Anda, dan kemudian klik tombol back pada peranti, maka aplikasi akan langsung tertutup seperti ini: