Select App Fragments

The page provides instructions on how to add dialog box functionalities to the sample app.

Select App Directory

The following directories lie inside the android studio project:

├── ui
│   ├── selectapp
│      ├── AllocationDetailsBottomScreenFragment.kt (Bottom sheet fragment for displaying allocation details)
│      ├── DetailsListAdapter.kt (Adapter for generalised list view)
│      ├── NetworkDetailsBottomScreenFragment.kt (Bottom Sheet fragment for displaying network details)
│      ├── SelectAppFragment.kt  (Navigates to bolt or vult app.)
│      └── WalletDetailsBottomScreenFragment.kt (wallet details bottom sheet fragment in SelectAppFragment.)
       └── DetailsBottomSheetFragment.kt(Bottom sheet fragment for displaying all details )    
ui/selectapp/AllocationDetailsBottomScreenFragment.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.zus.bolt.helloworld.R
import org.zus.bolt.helloworld.databinding.GenericBottomSheetDetailsFragmentBinding
import org.zus.bolt.helloworld.models.vult.AllocationModel
import org.zus.bolt.helloworld.utils.Utils
import org.zus.bolt.helloworld.databinding.RowDetailsListItemBinding
import org.zus.bolt.helloworld.models.selectapp.DetailsListModel
import org.zus.bolt.helloworld.models.selectapp.DetailsModel
import org.zus.bolt.helloworld.ui.vult.VultViewModel
import org.zus.bolt.helloworld.utils.Utils.Companion.getConvertedDateTime
import org.zus.bolt.helloworld.utils.Utils.Companion.getConvertedSize

class AllocationDetailsBottomScreenFragment(
    private val allocationModel: Allocation,
) : BottomSheetDialogFragment() {
      
    private lateinit var binding: GenericBottomSheetDetailsFragmentBinding
    private lateinit var vultViewModel: VultViewModel
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = GenericBottomSheetDetailsFragmentBinding.inflate(inflater, container, false)
        vultViewModel = ViewModelProvider(requireActivity())[VultViewModel::class.java]
        binding.tvPageTitle.text = getString(R.string.allocation_details_title)

        CoroutineScope(Dispatchers.Main).launch {

            val statsModel = vultViewModel.getAllocation()?.let { vultViewModel.getStats(it.stats) }

            val allocationDetailsModel = DetailsListModel(
                title = getString(R.string.details),
                detailsList = listOf(
                    DetailsModel(
                        title = "Allocation ID: ${allocationModel.id}",
                        value = allocationModel.id,
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Name: ${allocationModel.name}",
                        value = allocationModel.name,
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Expiration: ${allocationModel.expiration.getConvertedDateTime()}",
                        value = allocationModel.expiration.getConvertedDateTime(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Size: ${allocationModel.size.getConvertedSize()}",
                        value = allocationModel.size.getConvertedSize(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Used Size: ${statsModel?.used_size?.getConvertedSize() ?: "0"}",
                        value = statsModel?.used_size?.getConvertedSize() ?: "0",
                        showArrowButton = false
                    )
                )
            )

            val shardsAndChallengesDetails = DetailsListModel(
                title = getString(R.string.shards_and_challenges_details_title),
                detailsList = listOf(
                    DetailsModel(
                        title = "Data Shards: ${allocationModel.dataShards}",
                        value = allocationModel.dataShards.toString(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Parity Shards: ${allocationModel.parityShards}",
                        value = allocationModel.parityShards.toString(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Number of Writes: ${statsModel?.num_of_writes ?: 0}",
                        value = statsModel?.num_of_writes.toString(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Number of Reads: ${statsModel?.num_of_reads ?: 0}",
                        value = statsModel?.num_of_reads.toString(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Number of Challenges: ${statsModel?.num_success_challenges ?: 0}",
                        value = statsModel?.num_success_challenges.toString(),
                        showArrowButton = false
                    ),
                    DetailsModel(
                        title = "Latest Closed Challenge: ${statsModel?.latest_closed_challenge ?: "No value provided"}",
                        value = statsModel?.latest_closed_challenge ?: "No value provided",
                        showArrowButton = false
                    )
                )
            )
               val allocationDetails = listOf(
                allocationDetailsModel,
                shardsAndChallengesDetails
            )

            binding.detailsListView.removeAllViews()

            for (detailsModel in allocationDetails) {
                val rowDetailsListItemBindings = RowDetailsListItemBinding.inflate(
                    LayoutInflater.from(requireActivity()),
                    binding.detailsListView,
                    false
                )
                rowDetailsListItemBindings.tvDetails.text = detailsModel.title
                rowDetailsListItemBindings.detailsListView.adapter = DetailsListAdapter(
                    requireActivity(),
                    detailsModel.detailsList
                )

                binding.detailsListView.addView(rowDetailsListItemBindings.root)
            }

        }
        return binding.root
    }
}

Describing Code

  • Line 3 to 20 import packages to create view/UI for Allocation Details in the sample app.

  • Line 22 defines a class AllocationDetailsBottomScreenFragment which has following fields:

  • Line 25 defines a private late initialized binding variable that holds Bottom Sheet Dialog object instance

  • Line 28 overrides the onCreateView function which creates and returns the view hierarchy associated with the AllocationDetailsBottomScreen.

  • Line 38 to 71 defines a coroutine allocationDetailsModel that awaits execution of AllocationDetails and sharders/challenges details in the defined format by Details Model instance.

  • Line 73 to 107 defines how sharders and challenges information should be displayed. The display format is similar to Details Model instance.

  • Line 109 to 132 takes all the allocation and sharder information and binds it to the entire view to outermost container in layout.

ui/selectapp/DetailsListAdapter.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.annotation.SuppressLint
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.text.SpannableString
import android.text.SpannedString
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import org.zus.bolt.helloworld.R
import org.zus.bolt.helloworld.databinding.DialogItemViewBinding
import org.zus.bolt.helloworld.databinding.RowDetailsBinding
import org.zus.bolt.helloworld.models.selectapp.DetailsModel
import org.zus.bolt.helloworld.ui.TAG_CREATE_WALLET
import org.zus.bolt.helloworld.utils.Utils.Companion.isValidJson
import org.zus.bolt.helloworld.utils.Utils.Companion.isValidUrl
import org.zus.bolt.helloworld.utils.Utils.Companion.prettyJsonFormat

class DetailsListAdapter(
    private val fragmentActivity: FragmentActivity,
    private val detailsList: List<DetailsModel>,
) : BaseAdapter() {

    override fun getCount(): Int = detailsList.size

    override fun getItem(position: Int): Any {
        return detailsList[position]
    }

    override fun getItemId(position: Int): Long {
        return 0
    }

    @SuppressLint("RestrictedApi")
    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val rowDetailsBinding = RowDetailsBinding.inflate(LayoutInflater.from(parent?.context))
        rowDetailsBinding.tvDetailTitle.text = detailsList[position].title

        rowDetailsBinding.rowDetailsRoot.setOnLongClickListener {
            val clipboard =
                fragmentActivity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
            clipboard.setPrimaryClip(
                android.content.ClipData.newPlainText(
                    detailsList[position].title,
                    detailsList[position].value
                )
            )
            Toast.makeText(
                fragmentActivity,
                "${detailsList[position].title} Copied to clipboard",
                Toast.LENGTH_SHORT
            ).show()
            true
        }

        if (detailsList[position].value.isValidUrl()) {
            val text = SpannableString(detailsList[position].title).apply {
                if (detailsList[position].title.isValidUrl()) {
                    rowDetailsBinding.tvDetailTitle.setTextColor(
                        ContextCompat.getColor(
                            fragmentActivity,
                            R.color.color_url
                        )
                    )
                } else {
                    val colonIndex = detailsList[position].title.indexOf(":")
                    setSpan(
                        ForegroundColorSpan(
                            ContextCompat.getColor(
                                fragmentActivity,
                                R.color.color_url
                            )
                        ),
                        colonIndex,
                        detailsList[position].title.length,
                        SpannedString.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
            }

            rowDetailsBinding.tvDetailTitle.text = text

            rowDetailsBinding.rowDetailsRoot.setOnClickListener {
                val openUrl = android.content.Intent(android.content.Intent.ACTION_VIEW)
                openUrl.data = android.net.Uri.parse(detailsList[position].value)
                fragmentActivity.startActivity(openUrl)
            }
        }

        if (detailsList[position].showArrowButton) {
            rowDetailsBinding.ibnArrowDetails.visibility = View.VISIBLE

            rowDetailsBinding.rowDetailsRoot.setOnClickListener {
                val detailsBottomSheetDialogFragment =
                    DetailsBottomSheetFragment(detailsList[position])
                detailsBottomSheetDialogFragment.show(
                    fragmentActivity.supportFragmentManager,
                    "detailsBottomSheetDialogFragment"
                )
            }
        } else {
            rowDetailsBinding.ibnArrowDetails.visibility = View.GONE
        }

        return rowDetailsBinding.root
    }
}

Describing Code

  • DetailsListAdapter class defines fields and functions that handles functionality of addition and removal of data in a list without the need to redraw the entire view.

ui/selectapp/NetworkDetailsBottomScreenFragment.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.gson.Gson
import org.zus.bolt.helloworld.R
import org.zus.bolt.helloworld.databinding.GenericBottomSheetDetailsFragmentBinding
import org.zus.bolt.helloworld.databinding.RowDetailsListItemBinding
import org.zus.bolt.helloworld.models.NetworkModel
import org.zus.bolt.helloworld.models.selectapp.DetailsListModel
import org.zus.bolt.helloworld.models.selectapp.DetailsModel
import org.zus.bolt.helloworld.utils.Utils

class NetworkDetailsBottomScreenFragment : BottomSheetDialogFragment() {
    lateinit var binding: GenericBottomSheetDetailsFragmentBinding
    lateinit var networkModel: NetworkModel
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        binding =
            GenericBottomSheetDetailsFragmentBinding.inflate(inflater, container, false)

        binding.tvPageTitle.text = getString(R.string.network_details_title)

        networkModel = Gson().fromJson(
            Utils(requireContext()).getConfigFromAssets("config.json"),
            NetworkModel::class.java
        )

        val networkDetailsModel = DetailsListModel(
            title = getString(R.string.details),
            detailsList = listOf(
                DetailsModel(
                    title = "Name: ${networkModel.domainUrl}",
                    value = networkModel.domainUrl,
                    showArrowButton = false
                ),
                DetailsModel(
                    title = "Url: ${networkModel.config.blockWorker}",
                    value = networkModel.config.blockWorker,
                    showArrowButton = false
                ),
                DetailsModel(
                    title = "0box Url: ${networkModel.zboxUrl}",
                    value = networkModel.zboxUrl,
                    showArrowButton = false
                )
            )
        )

        val url = DetailsListModel(
            title = "",
            detailsList = listOf(
                DetailsModel(
                    title = networkModel.config.blockWorker,
                    value = networkModel.config.blockWorker,
                    showArrowButton = false
                )
            )
        )


        val networkDetails = listOf(
            networkDetailsModel,
            url
        )

        binding.detailsListView.removeAllViews()

        for (detailsModel in networkDetails) {
            val rowDetailsListItemBindings = RowDetailsListItemBinding.inflate(
                LayoutInflater.from(requireActivity()),
                binding.detailsListView,
                false
            )
            rowDetailsListItemBindings.tvDetails.text = detailsModel.title
            rowDetailsListItemBindings.detailsListView.adapter = DetailsListAdapter(
                requireActivity(),
                detailsModel.detailsList
            )

            binding.detailsListView.addView(rowDetailsListItemBindings.root)
        }

        return binding.root
    }
}

Describing Code:

  • Line 3 to 16 import packages required to create UI for Network Details in App.See gif here

  • Line 18 defines a class NetworkDetailsBottomScreenFragment which has following fields:

  • (Line 20) A private variable that holds access to NetworkModel instance.

  • Line 21 overrides the onCreateView function which creates and returns the view hierarchy associated with the NetworkDetailsBottomScreenFragment.

  • (Line 27) A private late initialized binding variable that holds Bottom Sheet Dialog object instance.

  • Line 31 to 33 retrieves network configuration from config.json

  • Line 36 to 66 defines how network details should be displayed in UI of the app. The format is defined by DetailsModel

  • Line 69 to 90 defines view binding that help interact code with views defined in line 36 to 66.

  • Line 91 binding.root ties the entire view to outermost container in layout of the app.

ui/selectapp/SelectAppFragment.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.zus.bolt.helloworld.R
import org.zus.bolt.helloworld.databinding.SelectAppFragmentBinding
import org.zus.bolt.helloworld.models.bolt.WalletModel
import org.zus.bolt.helloworld.ui.mainactivity.MainViewModel
import org.zus.bolt.helloworld.ui.vult.VultViewModel
import org.zus.bolt.helloworld.utils.Utils

class SelectAppFragment : Fragment() {
    lateinit var binding: SelectAppFragmentBinding
    lateinit var mainViewModel: MainViewModel
    lateinit var vultViewModel: VultViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        // Inflate the layout for this fragment
        binding = SelectAppFragmentBinding.inflate(inflater, container, false)
        mainViewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
        vultViewModel = ViewModelProvider(requireActivity())[VultViewModel::class.java]

        binding.cvWalletDetails.setOnClickListener {
            val walletDetailsBottomScreenFragment =
                WalletDetailsBottomScreenFragment(mainViewModel.wallet!!)
            walletDetailsBottomScreenFragment.show(
                parentFragmentManager,
                "WalletDetailsBottomScreenFragment"
            )
        }
        binding.cvAllocationDetails.setOnClickListener {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    val allocationModel = vultViewModel.getAllocation()
                    requireActivity().runOnUiThread {
                        if (allocationModel != null)
                            AllocationDetailsBottomScreenFragment(allocationModel).show(
                                parentFragmentManager,
                                "AllocationDetailsBottomScreenFragment")
                        else
                            Snackbar.make(
                                binding.root,
                                "Error: Allocation not found",
                                Snackbar.LENGTH_LONG
                            ).show()
                    }
                } catch (e: Exception) {
                    requireActivity().runOnUiThread {
                        Snackbar.make(
                            binding.root,
                            "Error: ${e.message}",
                            Snackbar.LENGTH_LONG
                        ).show()
                    }
                }
            }

        }
        binding.cvNetworkDetails.setOnClickListener {
            val networkDetailsBottomScreenFragment =
                NetworkDetailsBottomScreenFragment()
            networkDetailsBottomScreenFragment.show(
                parentFragmentManager,
                "NetworkDetailsBottomScreenFragment"
            )
        }

        binding.cvBolt.setOnClickListener {
            if (!Utils(requireContext()).isWalletExist()) {
                findNavController().navigate(R.id.action_selectAppFragment_to_boltFragment)
            } else {
                mainViewModel.wallet =
                    Gson().fromJson(
                        Utils(requireContext()).readWalletFromFileJSON(),
                        WalletModel::class.java
                    )
                mainViewModel.setWalletJson(Utils(requireContext()).readWalletFromFileJSON())
                findNavController().navigate(R.id.action_selectAppFragment_to_boltFragment)
            }
        }
        binding.cvVult.setOnClickListener {
            if (!Utils(requireContext()).isWalletExist()) {
                findNavController().navigate(R.id.action_selectAppFragment_to_vultFragment)
            } else {
                mainViewModel.wallet =
                    Gson().fromJson(
                        Utils(requireContext()).readWalletFromFileJSON(),
                        WalletModel::class.java
                    )
                mainViewModel.setWalletJson(Utils(requireContext()).readWalletFromFileJSON())
                findNavController().navigate(R.id.action_selectAppFragment_to_vultFragment)
            }
        }
        return binding.root
    }
}

Describing Code:

  • Line 3 to 16 import packages that are required to create views for the selected app parts in the app.

  • Line 22 defines a class SelectAppFragment which has following fields

    • A late intialized variable binding that holds SelectAppFragment Binding instance.

    • A late initialized variable mainViewModel that holds MainViewModel instance.

    • A late initialized variable vultViewModel that holds VultViewModel instance

  • Line 27 overrides the onCreateView function which creates and returns the view hierarchy associated with the SelectAppFragment.

    • Line 32 selected app fragment binding is called via inflate which will uncompress all the binding data and provide the container with the uncompressed data

    • Line 33 mainViewModel variable get assigned with a ViewModelProvider instance which provides Models to produce Views for MainViewModel.

    • Line 34 VultViewModel variable gets assigned with a ViewModelProvider instance which provides Models to produce Views for VultViewModel.

  • Line 36 to 42 defines view for for data related to Wallet Details. On button click present the recyclable view in WalletDetailsBottomScreenFragment

  • Line 44 to 71 defines view for the data related to Allocation Details. On button click present the recyclable view in AllocationDetailsBottomScreenFragment

  • Line 72 to 79 defines view for the data related to Network Details.On button click present the view in NetworkDetailsBottomScreenFragment

  • Line 81 to 93 defines view for Bolt selected part. It sets the wallet via WalletModel on and navigates the user to Bolt UI on button click.

  • Line 94 to 105 defines view for Vult selected part. It sets the wallet via WalletModel and navigates the user to VultUI on button click.

  • Line 107 binding.root binds the entire view to outermost container in layout.

ui/selectapp/WalletDetailsBottomScreenFragment.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.zus.bolt.helloworld.R
import org.zus.bolt.helloworld.databinding.GenericBottomSheetDetailsFragmentBinding
import org.zus.bolt.helloworld.databinding.RowDetailsListItemBinding
import org.zus.bolt.helloworld.models.bolt.WalletModel
import org.zus.bolt.helloworld.models.selectapp.DetailsListModel
import org.zus.bolt.helloworld.models.selectapp.DetailsModel
import org.zus.bolt.helloworld.utils.Utils.Companion.prettyJsonFormat

class WalletDetailsBottomScreenFragment(
    private val walletModel: WalletModel,
) : BottomSheetDialogFragment() {
    private lateinit var binding: GenericBottomSheetDetailsFragmentBinding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        binding = GenericBottomSheetDetailsFragmentBinding.inflate(inflater, container, false)

        binding.tvPageTitle.text = getString(R.string.wallet_details_title)

        val walletDetailsListModel = DetailsListModel(
            title = getString(R.string.details),
            detailsList = listOf(
                DetailsModel(
                    title = "ClientID",
                    value = walletModel.mClientId,
                    showArrowButton = true
                ),
                DetailsModel(
                    title = "Private Encryption Key",
                    value = walletModel.mKeys[0].mPrivateKey,
                    showArrowButton = true
                ),
                DetailsModel(
                    title = "Public Encryption Key",
                    value = walletModel.mKeys[0].mPublicKey,
                    showArrowButton = true
                ),
                DetailsModel(
                    title = "Mnemonics",
                    value = walletModel.mMnemonics,
                    showArrowButton = true
                )
            )
        )
        val walletJsonModel = DetailsListModel(
            title = getString(R.string.wallet_json_title),
            detailsList = listOf(
                DetailsModel(
                    title = walletModel.walletJson.prettyJsonFormat(),
                    value = walletModel.walletJson,
                    showArrowButton = false
                )
            )
        )

        val detailsListModel = listOf(walletDetailsListModel, walletJsonModel)
        //linear layout adapter

        binding.detailsListView.removeAllViews()

        for (detailsModel in detailsListModel) {
            val rowDetailsListItemBindings = RowDetailsListItemBinding.inflate(
                LayoutInflater.from(requireActivity()),
                binding.detailsListView,
                false
            )
            rowDetailsListItemBindings.tvDetails.text = detailsModel.title
            rowDetailsListItemBindings.detailsListView.adapter = DetailsListAdapter(
                requireActivity(),
                detailsModel.detailsList
            )

            binding.detailsListView.addView(rowDetailsListItemBindings.root)
        }

        return binding.root
    }
}
  • Line 3 to 12 import packages required to create UI for Network Details in App.

  • Line 15 defines a class NetworkDetailsBottomScreenFragment which has following fields:

    • (Line 16) A private variable that holds access to NetworkModel instance.

    • (Line 15) A private late initialized binding variable that holds Bottom Sheet Dialog object instance

  • Line 17 overrides the onCreateView function which creates and returns the view hierarchy associated with the NetworkDetailsBottomScreenFragment.

    • The view hierarchy as follows:(Line 25 to 35) in a BottomSheetDialog Network Name ,URL,0box URL and Domain are list as list pairs. See gif for reference

    • The Network Details are fetched via [Utils.kt] method and from config.json stored in assets.

  • Line 41 and 43 defines a variable linearArrayAdapter that holds Network details in DetailListAdaptertype. DetailsListView handles addition and removal without the need to redraw the entire view

  • Line 43 binding.root binds the entire view to outermost container in layout.

ui/selectapp/DetailsBottomSheetFragment.kt
package org.zus.bolt.helloworld.ui.selectapp

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.zus.bolt.helloworld.databinding.DetailsFragmentBinding
import org.zus.bolt.helloworld.models.selectapp.DetailsModel

class DetailsBottomSheetFragment(
    private val detailsModel: DetailsModel,
) : BottomSheetDialogFragment() {
    private lateinit var binding: DetailsFragmentBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DetailsFragmentBinding.inflate(inflater, container, false)

        /* Header title. */
        binding.tvHeaderTitle.text = detailsModel.title
        binding.btnBack.setOnClickListener {
            findNavController().popBackStack()
        }

        binding.tvDetails.text = detailsModel.value
        binding.tvDetails.setOnLongClickListener {
            val clipboard =
                requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
            val clip = ClipData.newPlainText("label", detailsModel.value)
            clipboard.setPrimaryClip(clip)
            Toast.makeText(requireContext(), "Copied to clipboard", Toast.LENGTH_SHORT).show()
            true
        }

        return binding.root
    }
}

Describing Code :

  • Line 3 to 14 import packages to create fragment for viewing details in the sample app.

  • Line 16 defines a class DetailsBottomScreenFragment which has following fields

  • Line 19 defines a private late initialized binding variable that holds DetailsFragmentBinding object.

  • Line 21 to 42 overrides the onCreateView function which creates and returns the view for the details reusable portion of the sample app.

  • Line 44 binds the entire view to outermost container in layout.

Last updated