Kita telah belajar bagaimana berpindah dari satu fragment ke fragment lain. Nah, kurang lengkap rasanya kalau belum tahu bagaimana berpindah fragment dengan membawa data. Terdapat dua cara yakni dengan menggunakan obyek bundle dan setter and getter. Mari langsung praktikkan kedua cara tersebut.
- Buat fragment lagi dengan nama DetailCategoryFragment.
- Pada fragment_detail_category sesuaikan kodenya 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:id="@+id/tv_category_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/category_name" />
<TextView
android:id="@+id/tv_category_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/category_description" />
<Button
android:id="@+id/btn_profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/to_profile" />
<Button
android:id="@+id/btn_show_dialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_dialog" />
</LinearLayout> - Setelah selesai, silakan lengkapi kode pada DetailCategoryFragment. Pertama, tambahkan beberapa view, dan juga casting-nya.
Kotlin class DetailCategoryFragment : Fragment(){
lateinit var tvCategoryName: TextView
lateinit var tvCategoryDescription: TextView
lateinit var btnProfile: Button
lateinit var btnShowDialog: Button
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvCategoryName = view.findViewById(R.id.tv_category_name)
tvCategoryDescription = view.findViewById(R.id.tv_category_description)
btnProfile = view.findViewById(R.id.btn_profile)
btnProfile.setOnClickListener(this)
btnShowDialog = view.findViewById(R.id.btn_show_dialog)
btnShowDialog.setOnClickListener(this)
}
}Java TextView tvCategoryName;
TextView tvCategoryDescription;
Button btnProfile;
Button btnShowDialog;
...
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvCategoryName = view.findViewById(R.id.tv_category_name);
tvCategoryDescription = view.findViewById(R.id.tv_category_description);
btnProfile = view.findViewById(R.id.btn_profile);
btnProfile.setOnClickListener(this);
btnShowDialog = view.findViewById(R.id.btn_show_dialog);
btnShowDialog.setOnClickListener(this);
}Kemudian metode setOnClickListener akan mengalami error karena Anda belum mengimplementasi onClick() ke DetailCategoryFragment. Maka implementasikanlah onClick di kelas fragment-nya dan juga set listener di view-nya.
Kotlin class DetailCategoryFragment : Fragment(), View.OnClickListener {
...
override fun onClick(v: View) {
when (v.id) {
}
}
}Java public class DetailCategoryFragment extends Fragment implements View.OnClickListener {
...
@Override
public void onClick(View v) {
switch (v.getId()) {
}
}
}Dan tambahkan beberapa variabel dan berikan aksi ketika button diklik.
Kotlin class DetailCategoryFragment : Fragment(), View.OnClickListener {
var description: String? = null
companion object {
var EXTRA_NAME = "extra_name"
var EXTRA_DESCRIPTION = "extra_description"
}
...
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
val descFromBundle = savedInstanceState.getString(EXTRA_DESCRIPTION)
description = descFromBundle
}
if (arguments != null) {
val categoryName = arguments?.getString(EXTRA_NAME)
tv_category_name.text = categoryName
tv_category_description.text = description
}
}
override fun onClick(v: View) {
when (v.id) {
R.id.btn_profile -> {
}
R.id.btn_show_dialog -> {
}
}
}
}Java public class DetailCategoryFragment extends Fragment implements View.OnClickListener {
...
public static String EXTRA_NAME = "extra_name";
public static String EXTRA_DESCRIPTION = "extra_description";
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
...
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String categoryName = getArguments().getString(EXTRA_NAME);
tvCategoryName.setText(categoryName);
tvCategoryDescription.setText(getDescription());
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_profile:
break;
case R.id.btn_show_dialog:
break;
}
}
}Kode di atas akan mendemonstrasikan bagaimana melakukan penampilan data yang dikirim melalui perpindahan fragment.
Sehingga DetailCategoryFragment menjadi seperti ini:Kotlin class DetailCategoryFragment : Fragment(), View.OnClickListener {
lateinit var tvCategoryName: TextView
lateinit var tvCategoryDescription: TextView
lateinit var btnProfile: Button
lateinit var btnShowDialog: Button
var description: String? = null
companion object {
var EXTRA_NAME = "extra_name"
var EXTRA_DESCRIPTION = "extra_description"
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail_category, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvCategoryName = view.findViewById(R.id.tv_category_name)
tvCategoryDescription = view.findViewById(R.id.tv_category_description)
btnProfile = view.findViewById(R.id.btn_profile)
btnProfile.setOnClickListener(this)
btnShowDialog = view.findViewById(R.id.btn_show_dialog)
btnShowDialog.setOnClickListener(this)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
val descFromBundle = savedInstanceState.getString(EXTRA_DESCRIPTION)
description = descFromBundle
}
if (arguments != null) {
val categoryName = arguments?.getString(EXTRA_NAME)
tv_category_name.text = categoryName
tv_category_description.text = description
}
}
override fun onClick(v: View) {
when (v.id) {
R.id.btn_profile -> {
}
R.id.btn_show_dialog -> {
}
}
}
}Java public class DetailCategoryFragment extends Fragment implements View.OnClickListener {
TextView tvCategoryName;
TextView tvCategoryDescription;
Button btnProfile;
Button btnShowDialog;
public static String EXTRA_NAME = "extra_name";
public static String EXTRA_DESCRIPTION = "extra_description";
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public DetailCategoryFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail_category, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvCategoryName = view.findViewById(R.id.tv_category_name);
tvCategoryDescription = view.findViewById(R.id.tv_category_description);
btnProfile = view.findViewById(R.id.btn_profile);
btnProfile.setOnClickListener(this);
btnShowDialog = view.findViewById(R.id.btn_show_dialog);
btnShowDialog.setOnClickListener(this);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String categoryName = getArguments().getString(EXTRA_NAME);
tvCategoryName.setText(categoryName);
tvCategoryDescription.setText(getDescription());
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_profile:
break;
case R.id.btn_show_dialog:
break;
}
}
} - Baik, tinggal selangkah lagi kita menyelesaikan proses implementasi pengiriman data melalui perpindahan fragment. Sekarang buka kembali CategoryFragment lalu tambahkan baris berikut pada method onClick().
Kotlin override fun onClick(v: View) {
if (v.id == R.id.btn_detail_category) {
val mDetailCategoryFragment = DetailCategoryFragment()
val mBundle = Bundle()
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle")
val description = "Kategori ini akan berisi produk-produk lifestyle"
mDetailCategoryFragment.arguments = mBundle
mDetailCategoryFragment.description = description
val mFragmentManager = fragmentManager
mFragmentManager?.beginTransaction()?.apply {
replace(R.id.frame_container, mDetailCategoryFragment, DetailCategoryFragment::class.java.simpleName)
addToBackStack(null)
commit()
}
}
}Java @Override
public void onClick(View v) {
if (v.getId() == R.id.btn_detail_category) {
DetailCategoryFragment mDetailCategoryFragment = new DetailCategoryFragment();
Bundle mBundle = new Bundle();
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle");
String description = "Kategori ini akan berisi produk-produk lifestyle";
mDetailCategoryFragment.setArguments(mBundle);
mDetailCategoryFragment.setDescription(description);
FragmentManager mFragmentManager = getFragmentManager();
if (mFragmentManager != null) {
mFragmentManager
.beginTransaction()
.replace(R.id.frame_container, mDetailCategoryFragment, DetailCategoryFragment.class.getSimpleName())
.addToBackStack(null)
.commit();
}
}
}Sehingga kode CategoryFragment kita sekarang menjadi:
Kotlin 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) {
val mDetailCategoryFragment = DetailCategoryFragment()
val mBundle = Bundle()
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle")
val description = "Kategori ini akan berisi produk-produk lifestyle"
mDetailCategoryFragment.arguments = mBundle
mDetailCategoryFragment.description = description
val mFragmentManager = fragmentManager
mFragmentManager?.beginTransaction()?.apply {
replace(R.id.frame_container, mDetailCategoryFragment, DetailCategoryFragment::class.java.simpleName)
addToBackStack(null)
commit()
}
}
}
}Java public class CategoryFragment extends Fragment implements View.OnClickListener {
public CategoryFragment() {
// 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_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) {
DetailCategoryFragment mDetailCategoryFragment = new DetailCategoryFragment();
Bundle mBundle = new Bundle();
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle");
String description = "Kategori ini akan berisi produk-produk lifestyle";
mDetailCategoryFragment.setArguments(mBundle);
mDetailCategoryFragment.setDescription(description);
/*
Method addToBackStack akan menambahkan fragment ke backstack
Behaviour dari back button akan cek fragment dari backstack,
jika ada fragment di dalam backstack maka fragment yang akan di close / remove
jika sudah tidak ada fragment di dalam backstack maka activity yang akan di close / finish
*/
FragmentManager mFragmentManager = getFragmentManager();
if (mFragmentManager != null) {
mFragmentManager
.beginTransaction()
.replace(R.id.frame_container, mDetailCategoryFragment, DetailCategoryFragment.class.getSimpleName())
.addToBackStack(null)
.commit();
}
}
}
} - Sekarang setelah selesai semua, silakan jalankan aplikasinya untuk melihat hasil kode yang di atas. Seharusnya ketika Anda mengklik tombol Kategory Lifestyle pada CategoryFragment akan ada data yang dikirimkan sewaktu perpindahan fragment itu melalui object bundle dan mekanisme metode setter and getter. Tampilan aplikasi Anda sekarang sudah menjadi seperti ini.
Bedah Kode
-
Dengan Menggunakan Bundle
Kotlin val mBundle = Bundle()
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle")Java Bundle mBundle = new Bundle();
mBundle.putString(DetailCategoryFragment.EXTRA_NAME, "Lifestyle");Pada kode di atas kita menggunakan obyek bundle untuk mengirimkan data antar fragment. Perhatikan cara yang digunakan sama dengan cara yang telah kita implementasikan sebelumnya di activity. Setelah dibuat obyeknya dan data yang mau dikirimkan apa, kita hanya perlu menambahkan sebaris kode berikut:
Kotlin mDetailCategoryFragment.arguments = mBundle
Java mDetailCategoryFragment.setArguments(mBundle);
Cara mengambil data yang dikirimkan melalui obyek bundle pada fragment tujuan pun, sangatlah mudah. Cukup memanggil metode getArguments() di fragment DetailCategoryFragment seperti berikut:
Kotlin val categoryName = arguments?.getString(EXTRA_NAME)
Java String categoryName = getArguments().getString(EXTRA_NAME);
Kelas Bundle merupakan kelas map data string untuk obyek-obyek parcelable. Di sini kita bisa menginput lebih dari satu parameter/variabel ke dalam obyek Bundle.
-
Dengan Menggunakan Setter dan Getter
Kelas fragment adalah kelas java pada umumnya, dengan menggunakan metode setter and getter untuk mengirimkan parameter/variabel dari satu fragment ke fragment lainnya. Seperti baris berikut:Kotlin val description = "Kategori ini akan berisi produk-produk lifestyle"
mDetailCategoryFragment.description = descriptionJava String description = "Kategori ini akan berisi produk-produk lifestyle";
mDetailCategoryFragment.setDescription(description);Yang mana isi kode pada kelas DetailCategoryFragment sebagai berikut:Kotlin var description: String? = null
companion object {
var EXTRA_NAME = "extra_name"
var EXTRA_DESCRIPTION = "extra_description"
}Java public static String EXTRA_NAME = "extra_name";
private String description;
public DetailCategoryFragment() {
// Required empty public constructor
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}Cara menggunakannya juga cukup mudah, yakni hanya dengan menempatkan value yang ingin dikirimkan via metode setter lalu diambil dengan menggunakan metode getter seperti pada baris berikut:Kotlin tv_category_description.text = description
Java tvCategoryDescription.setText(getDescription());
Codelab Fragment untuk Dialog
- Buat kembali satu kelas fragment dengan nama OptionDialogFragment . Jangan lupa uncheck pilihan include fragment factory methods dan include interface methods.
- Ketika sudah diciptakan, pada fragment_option_dialog.xml kondisikan kodenya 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="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/question_coach" />
<RadioGroup
android:id="@+id/rg_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:id="@+id/rb_saf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/sir_alex_ferguson" />
<RadioButton
android:id="@+id/rb_mou"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/jose_mourinho" />
<RadioButton
android:id="@+id/rb_lvg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/louis_van_gaal" />
<RadioButton
android:id="@+id/rb_moyes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/david_moyes" />
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_close"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:layout_weight="0.5"
android:text="@string/close" />
<Button
android:id="@+id/btn_choose"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_weight="0.5"
android:text="@string/choose" />
</LinearLayout>
</LinearLayout> - Setelah selesai dengan berkas layout xml, lanjutkan ngoding untuk OptionDialogFragment. Pertama, kenalkan obyek yang ada di dalam layout seperti ini:
Kotlin private lateinit var btnChoose: Button
private lateinit var btnClose: Button
private lateinit var rgOptions: RadioGroup
private lateinit var rbSaf: RadioButton
private lateinit var rbMou: RadioButton
private lateinit var rbLvg: RadioButton
private lateinit var rbMoyes: RadioButton
private var optionDialogListener: OnOptionDialogListener? = null
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnChoose = view.findViewById(R.id.btn_choose)
btnChoose.setOnClickListener(this)
btnClose = view.findViewById(R.id.btn_close)
btnClose.setOnClickListener(this)
rgOptions = view.findViewById(R.id.rg_options)
rbSaf = view.findViewById(R.id.rb_saf)
rbLvg = view.findViewById(R.id.rb_lvg)
rbMou = view.findViewById(R.id.rb_mou)
rbMoyes = view.findViewById(R.id.rb_moyes)
}Java Button btnChoose, btnClose;
RadioGroup rgOptions;
RadioButton rbSaf, rbMou, rbLvg, rbMoyes;
OnOptionDialogListener optionDialogListener;
...
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnChoose = view.findViewById(R.id.btn_choose);
btnChoose.setOnClickListener(this);
btnClose = view.findViewById(R.id.btn_close);
btnClose.setOnClickListener(this);
rgOptions = view.findViewById(R.id.rg_options);
rbSaf = view.findViewById(R.id.rb_saf);
rbLvg = view.findViewById(R.id.rb_lvg);
rbMou = view.findViewById(R.id.rb_mou);
rbMoyes = view.findViewById(R.id.rb_moyes);
}Selanjutnya kita beri aksi untuk button-nya dan beri pula kelas interface dan ubah turunannya dari Fragment menjadi DialogFragment.
Kotlin class OptionDialogFragment : DialogFragment(), View.OnClickListener {
...
override fun onClick(v: View) {
when (v.id) {
R.id.btn_close -> dialog?.cancel()
R.id.btn_choose -> {
val checkedRadioButtonId = rg_options.checkedRadioButtonId
if (checkedRadioButtonId != -1) {
var coach: String? = null
when (checkedRadioButtonId) {
R.id.rb_saf -> coach = rbSaf.text.toString().trim()
R.id.rb_mou -> coach = rbMou.text.toString().trim()
R.id.rb_lvg -> coach = rbLvg.text.toString().trim()
R.id.rb_moyes -> coach = rbMoyes.text.toString().trim()
}
if (optionDialogListener != null) {
optionDialogListener?.onOptionChosen(coach)
}
dialog?.dismiss()
}
}
}
}
interface OnOptionDialogListener {
fun onOptionChosen(text: String?)
}
}Java public class OptionDialogFragment extends DialogFragment implements View.OnClickListener {
...
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_close:
getDialog().cancel();
break;
case R.id.btn_choose:
int checkedRadioButtonId = rgOptions.getCheckedRadioButtonId();
if (checkedRadioButtonId != -1) {
String coach = null;
switch (checkedRadioButtonId) {
case R.id.rb_saf:
coach = rbSaf.getText().toString().trim();
break;
case R.id.rb_mou:
coach = rbMou.getText().toString().trim();
break;
case R.id.rb_lvg:
coach = rbLvg.getText().toString().trim();
break;
case R.id.rb_moyes:
coach = rbMoyes.getText().toString().trim();
break;
}
if (optionDialogListener != null) {
optionDialogListener.onOptionChosen(coach);
}
getDialog().dismiss();
}
break;
}
}
public interface OnOptionDialogListener {
void onOptionChosen(String text);
}
}Kemudian tambahkan kode berikut untuk mengelola optionDialogListener ketika fragment dipanggil dan dimatikan:
Kotlin override fun onAttach(context: Context) {
super.onAttach(context)
val fragment = parentFragment
if (fragment is DetailCategoryFragment) {
val detailCategoryFragment = fragment
this.optionDialogListener = detailCategoryFragment.optionDialogListener
}
}
override fun onDetach() {
super.onDetach()
this.optionDialogListener = null
}Java @Override
public void onAttach(Context context) {
super.onAttach(context);
Fragment fragment = getParentFragment();
if (fragment instanceof DetailCategoryFragment) {
DetailCategoryFragment detailCategoryFragment = (DetailCategoryFragment) fragment;
this.optionDialogListener = detailCategoryFragment.optionDialogListener;
}
}
@Override
public void onDetach() {
super.onDetach();
this.optionDialogListener = null;
}Kondisikan kodenya menjadi sebagai berikut:
Kotlin class OptionDialogFragment : DialogFragment(), View.OnClickListener {
private lateinit var btnChoose: Button
private lateinit var btnClose: Button
private lateinit var rgOptions: RadioGroup
private lateinit var rbSaf: RadioButton
private lateinit var rbMou: RadioButton
private lateinit var rbLvg: RadioButton
private lateinit var rbMoyes: RadioButton
private var optionDialogListener: OnOptionDialogListener? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_option_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnChoose = view.findViewById(R.id.btn_choose)
btnChoose.setOnClickListener(this)
btnClose = view.findViewById(R.id.btn_close)
btnClose.setOnClickListener(this)
rgOptions = view.findViewById(R.id.rg_options)
rbSaf = view.findViewById(R.id.rb_saf)
rbLvg = view.findViewById(R.id.rb_lvg)
rbMou = view.findViewById(R.id.rb_mou)
rbMoyes = view.findViewById(R.id.rb_moyes)
}
override fun onAttach(context: Context) {
super.onAttach(context)
val fragment = parentFragment
if (fragment is DetailCategoryFragment) {
val detailCategoryFragment = fragment
this.optionDialogListener = detailCategoryFragment.optionDialogListener
}
}
override fun onDetach() {
super.onDetach()
this.optionDialogListener = null
}
override fun onClick(v: View) {
when (v.id) {
R.id.btn_close -> dialog?.cancel()
R.id.btn_choose -> {
val checkedRadioButtonId = rg_options.checkedRadioButtonId
if (checkedRadioButtonId != -1) {
var coach: String? = null
when (checkedRadioButtonId) {
R.id.rb_saf -> coach = rbSaf.text.toString().trim()
R.id.rb_mou -> coach = rbMou.text.toString().trim()
R.id.rb_lvg -> coach = rbLvg.text.toString().trim()
R.id.rb_moyes -> coach = rbMoyes.text.toString().trim()
}
if (optionDialogListener != null) {
optionDialogListener?.onOptionChosen(coach)
}
dialog?.dismiss()
}
}
}
}
interface OnOptionDialogListener {
fun onOptionChosen(text: String?)
}
}Java public class OptionDialogFragment extends DialogFragment implements View.OnClickListener {
Button btnChoose, btnClose;
RadioGroup rgOptions;
RadioButton rbSaf, rbMou, rbLvg, rbMoyes;
OnOptionDialogListener optionDialogListener;
public OptionDialogFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_option_dialog, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnChoose = view.findViewById(R.id.btn_choose);
btnChoose.setOnClickListener(this);
btnClose = view.findViewById(R.id.btn_close);
btnClose.setOnClickListener(this);
rgOptions = view.findViewById(R.id.rg_options);
rbSaf = view.findViewById(R.id.rb_saf);
rbLvg = view.findViewById(R.id.rb_lvg);
rbMou = view.findViewById(R.id.rb_mou);
rbMoyes = view.findViewById(R.id.rb_moyes);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Fragment fragment = getParentFragment();
if (fragment instanceof DetailCategoryFragment) {
DetailCategoryFragment detailCategoryFragment = (DetailCategoryFragment) fragment;
this.optionDialogListener = detailCategoryFragment.optionDialogListener;
}
}
@Override
public void onDetach() {
super.onDetach();
this.optionDialogListener = null;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_close:
getDialog().cancel();
break;
case R.id.btn_choose:
int checkedRadioButtonId = rgOptions.getCheckedRadioButtonId();
if (checkedRadioButtonId != -1) {
String coach = null;
switch (checkedRadioButtonId) {
case R.id.rb_saf:
coach = rbSaf.getText().toString().trim();
break;
case R.id.rb_mou:
coach = rbMou.getText().toString().trim();
break;
case R.id.rb_lvg:
coach = rbLvg.getText().toString().trim();
break;
case R.id.rb_moyes:
coach = rbMoyes.getText().toString().trim();
break;
}
if (optionDialogListener != null) {
optionDialogListener.onOptionChosen(coach);
}
getDialog().dismiss();
}
break;
}
}
public interface OnOptionDialogListener {
void onOptionChosen(String text);
}
}Ingat, jangan lupa untuk menambahkan inherit ke kelas DialogFragment.
- Tambahkan beberapa baris pada metode onClick() di DetailCategoryFragment menjadi sebagai berikut:
Kotlin override fun onClick(v: View) {
when (v.id) {
R.id.btn_profile -> {
}
R.id.btn_show_dialog -> {
val mOptionDialogFragment = OptionDialogFragment()
val mFragmentManager = childFragmentManager
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment::class.java.simpleName)
}
}
}Java @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_profile:
break;
case R.id.btn_show_dialog:
OptionDialogFragment mOptionDialogFragment = new OptionDialogFragment();
FragmentManager mFragmentManager = getChildFragmentManager();
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment.class.getSimpleName());
break;
}
} - Kemudian tambahkan OptionDialogFragment pada DetailCategoryFragment seperti berikut:
Kotlin class DetailCategoryFragment : Fragment(), View.OnClickListener {
...
internal var optionDialogListener: OptionDialogFragment.OnOptionDialogListener = object : OptionDialogFragment.OnOptionDialogListener {
override fun onOptionChosen(text: String?) {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show()
}
}
}Java public class DetailCategoryFragment extends Fragment implements View.OnClickListener {
...
OptionDialogFragment.OnOptionDialogListener optionDialogListener = new OptionDialogFragment.OnOptionDialogListener() {
@Override
public void onOptionChosen(String text) {
Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
}
};
} - Sehingga kode DetailCategoryFragment kita saat ini menjadi seperti ini:
Kotlin class DetailCategoryFragment : Fragment(), View.OnClickListener {
lateinit var tvCategoryName: TextView
lateinit var tvCategoryDescription: TextView
lateinit var btnProfile: Button
lateinit var btnShowDialog: Button
var description: String? = null
companion object {
var EXTRA_NAME = "extra_name"
var EXTRA_DESCRIPTION = "extra_description"
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail_category, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvCategoryName = view.findViewById(R.id.tv_category_name);
tvCategoryDescription = view.findViewById(R.id.tv_category_description);
btnProfile = view.findViewById(R.id.btn_profile);
btnProfile.setOnClickListener(this);
btnShowDialog = view.findViewById(R.id.btn_show_dialog);
btnShowDialog.setOnClickListener(this);
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
val descFromBundle = savedInstanceState.getString(EXTRA_DESCRIPTION)
description = descFromBundle
}
if (arguments != null) {
val categoryName = arguments?.getString(EXTRA_NAME)
tv_category_name.text = categoryName
tv_category_description.text = description
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(EXTRA_DESCRIPTION, description)
}
override fun onClick(v: View) {
when (v.id) {
R.id.btn_profile -> {
val mIntent = Intent(activity, ProfileActivity::class.java)
startActivity(mIntent)
}
R.id.btn_show_dialog -> {
val mOptionDialogFragment = OptionDialogFragment()
val mFragmentManager = childFragmentManager
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment::class.java.simpleName)
}
}
}
internal var optionDialogListener: OptionDialogFragment.OnOptionDialogListener = object : OptionDialogFragment.OnOptionDialogListener {
override fun onOptionChosen(text: String?) {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show()
}
}
}Java public class DetailCategoryFragment extends Fragment implements View.OnClickListener {
TextView tvCategoryName;
TextView tvCategoryDescription;
Button btnProfile;
Button btnShowDialog;
public static String EXTRA_NAME = "extra_name";
public static String EXTRA_DESCRIPTION = "extra_description";
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public DetailCategoryFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail_category, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvCategoryName = view.findViewById(R.id.tv_category_name);
tvCategoryDescription = view.findViewById(R.id.tv_category_description);
btnProfile = view.findViewById(R.id.btn_profile);
btnProfile.setOnClickListener(this);
btnShowDialog = view.findViewById(R.id.btn_show_dialog);
btnShowDialog.setOnClickListener(this);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
String descFromBundle = savedInstanceState.getString(EXTRA_DESCRIPTION);
setDescription(descFromBundle);
}
if (getArguments() != null) {
String categoryName = getArguments().getString(EXTRA_NAME);
tvCategoryName.setText(categoryName);
tvCategoryDescription.setText(getDescription());
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_DESCRIPTION, getDescription());
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_profile:
break;
case R.id.btn_show_dialog:
OptionDialogFragment mOptionDialogFragment = new OptionDialogFragment();
FragmentManager mFragmentManager = getChildFragmentManager();
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment.class.getSimpleName());
break;
}
}
OptionDialogFragment.OnOptionDialogListener optionDialogListener = new OptionDialogFragment.OnOptionDialogListener() {
@Override
public void onOptionChosen(String text) {
Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
}
};
} - Sekarang jalankan kembali aplikasi dan klik pada tombol Tampilkan sebuah dialog. Hasilnya akan muncul obyek OptionDialogFragment yang baru saja dibuat. Coba Anda pilih salah satu option yang ada dan klik tombol Pilih. Lihat, hasil dari yang kita pilih, tampil dalam bentuk soft message (Toast).
Bedah Kode
DialogFragment
Kotlin |
class OptionDialogFragment : DialogFragment() |
Java |
public class OptionDialogFragment extends DialogFragment |
Kotlin |
internal var optionDialogListener: OptionDialogFragment.OnOptionDialogListener = object : OptionDialogFragment.OnOptionDialogListener { |
Java |
public final OptionDialogFragment.OnOptionDialogListener optionDialogListener = new OptionDialogFragment.OnOptionDialogListener() { |
OptionDialogFragment mOptionDialogFragment = new OptionDialogFragment();
mOptionDialogFragment.setOnOptionDialogListener(new OptionDialogFragment.OnOptionDialogListener() {
@Override
public void onOptionChosen(String text) {
Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
}
});
Kotlin |
val mFragmentManager = childFragmentManager |
Java |
FragmentManager mFragmentManager = getChildFragmentManager(); |
Kotlin |
val mFragmentManager = childFragmentManager |
Java |
FragmentManager mFragmentManager = getChildFragmentManager(); |
Kotlin |
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment::class.java.simpleName) |
Java |
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment.class.getSimpleName()); |
Kotlin |
interface OnOptionDialogListener { |
Java |
public interface OnOptionDialogListener{ |
Kotlin |
val checkedRadioButtonId = rgOptions.checkedRadioButtonId |
Java |
int checkedRadioButtonId = rgOptions.getCheckedRadioButtonId(); |
Kotlin |
internal var optionDialogListener: OptionDialogFragment.OnOptionDialogListener = object : OptionDialogFragment.OnOptionDialogListener { |
Java |
mOptionDialogFragment.setOnOptionDialogListener(new OptionDialogFragment.OnOptionDialogListener() { |
Kotlin |
optionDialogListener?.onOptionChosen(coach) |
Java |
getOnOptionDialogListener().onOptionChosen(coach); |
Kemudian metode onOptionChosen() pada baris ini akan dipanggil untuk menampilkan nilai dari pilihan yang dipilih pada toast.
Kotlin |
internal var optionDialogListener: OptionDialogFragment.OnOptionDialogListener = object : OptionDialogFragment.OnOptionDialogListener { |
Java |
mOptionDialogFragment.setOnOptionDialogListener(new OptionDialogFragment.OnOptionDialogListener() { |
Codelab Memanggil Activity dari fragment
Terakhir sebelum sesi ini selesai kita akan belajar bagaimana menjalankan sebuah activity dari fragment. Caranya pun hampir sama dengan apa yang telah kita pelajari di activity.
- Buat sebuah activity dengan nama ProfileActivity.
- Setelah terbentuk, pada activity_profile.xml kondisikan kode yang ada menjadi sebagai berikut:
<?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"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/this_profile" />
</RelativeLayout> - Kemudian pada method onClick() pilihan R.id.btn_profile di kelas DetailCategoryFragment , tambahkan beberapa baris berikut untuk menjalankan ProfileActivity:
Kotlin override fun onClick(v: View) {
when (v.id) {
R.id.btn_profile -> {
val mIntent = Intent(activity, ProfileActivity::class.java)
startActivity(mIntent)
}
R.id.btn_show_dialog -> {
val mOptionDialogFragment = OptionDialogFragment()
val mFragmentManager = childFragmentManager
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment::class.java.simpleName)
}
}
}Java @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_profile:
Intent mIntent = new Intent(getActivity(), ProfileActivity.class);
startActivity(mIntent);
break;
case R.id.btn_show_dialog:
OptionDialogFragment mOptionDialogFragment = new OptionDialogFragment();
FragmentManager mFragmentManager = getChildFragmentManager();
mOptionDialogFragment.show(mFragmentManager, OptionDialogFragment.class.getSimpleName());
break;
}
} -
Setelah selesai semua, coba jalankan aplikasi Anda dan klik tombol Ke Halaman Profile Activity.
Bedah Kode
Perbedaan Activity dan Fragment
Kotlin |
val mIntent = Intent(activity, ProfileActivity::class.java) |
Java |
Intent mIntent = new Intent(getActivity(), ProfileActivity.class); |
Kotlin |
class DetailCategoryFragment : Fragment(){ |
Java |
@Override |
Jadi, itulah dua perbedaan antara fragment dan activity dari segi kode yaitu:
- Context menggunakan getActivity/activity, bukan this@MainActivity/MainActivity.this
- Pemanggilan id menggunakan view.findFiewById, bukan findFiewById