I have an application that performs writing by NFC on a card, depending on the number that has passed will perform a number or other reads. I guess I do this with a simple for loop, the problem is that I do not know where to put that for loop. I give you an example of the class:
class HomeFragment : Fragment(), OnClickDetailsMonuments {
private lateinit var homeFragmentViewModel: HomeFragmentViewModel
private lateinit var homeMonumentsAdapter: MonumentsAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.home_fragment, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
getObservers()
onClickGoToMaps(view)
homeFragmentViewModel.loadJsonFromRetrofit()
}
private fun onClickGoToMaps(view: View) {
fbGoToMaps.setOnClickListener {
view.findNavController().navigate(R.id.googleMapsMonumentsFragment)
}
}
private fun getObservers() {
viewModel.getNFCInfo().observe(viewLifecycleOwner, Observer {
when(it.status){
AsyncResult.Status.SUCCESS -> {
NFCProvider.initialize(context, it.data)
}
AsyncResult.Status.ERROR -> {
}
AsyncResult.Status.LOADING -> {
}
}
})
}
override fun onClickFavListener(monuments: MonumentsVO) {
homeFragmentViewModel.updateDatabaseFavoriteCheckFromViewModel(monuments.id, monuments.fav)
}
override fun onClickRowListenerExtras(monuments: MonumentsVO, position: Int, extras: FragmentNavigator.Extras) {
val bundle = bundleOf(BUNDLE_MONUMENT to monuments)
view?.findNavController()?.navigate(R.id.detailsMonumentsFragment, bundle, null, extras)
}
override fun onClickRowListener(monuments: MonumentsVO, position: Int) {}
private fun initViews() {
homeFragmentViewModel = ViewModelProviders.of(this).get(HomeFragmentViewModel::class.java)
rvHomeFragmentMonumentsRetrofit.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(context)
rvHomeFragmentMonumentsRetrofit.layoutManager = layoutManager
}
override fun onResume() {
super.onResume()
(activity as AppCompatActivity).supportActionBar?.show()
}
private fun showDialog(title: String, process: String, titleButton: String) {
val dialog = CustomSuccessDialog(title, process, titleButton)
dialog.show()
}
override onNewIntentResult(intent) {
val message = NFCProvider.retrieveNfcMessage(intent)
if(message) {
showDialog("Correct reading", "1 de 4", "Continue")
} else {
showDialog("Error reading", "1 de 4", "Retry")
}
}
}
As you can see the problem is that when I start the NFC is when I pass the message. I get this message from an internet service and it returns the number of cards that I have to record, which is the one I have to go through, and since on the one hand I have the onNewIntent that I need for the NFC and on the other hand the observer, I don't know how to do it to put it all together and that every time I write an NFC card I get the correct dialogue and when I continue to the next one, the number of the dialogue increases: 1 of 4, 2 of 4, 3 of 4, etc. See if you can give me a hand. Thank you very much.
You can save the instance of the dialog and update your textView in your dialog like this:
if(message) {
if(mDialog?.isShowing == false) {
showDialog("Correct reading", "1 de 4", "Continue")
} else {
mDialog.updateText("$count de 4")
count ++
}
}
And your showDialog method will look something like this:
private fun showDialog(title: String, process: String, titleButton: String) {
mDialog = CustomSuccessDialog(title, process, titleButton)
mDialog.show()
}
Related
I had a working app that does some arithmetic functionality that is out of the scope of the question, then I wanted to add more functionality to it, so i separated the layout into activity and fragment in order to later add other fragments that will do extra functions.
yet when I separated the layout taking some buttons along with a TextView (R.id.Result) to the new fragment, the text property of the TextView still updates as expected, but the display stays the same, always showing the initialization value initially assigned to it on its creation time.
I confirmed that the objects are the same as I expected them to be during runtime verified through logcat, what I need OFC is for the TextView display to update when I change its text property, numberInsertAction is called from the buttons properly and send proper data.
Important Note: below is only the relevant parts of code, it is much larger and I know what you see below can be simplified but it is built this way because of other classes and functionality that aren't shown below, if you need to see or ask about something outside the below code please do, yet again I only included the related part only and removed the business functionality.
Thanks in advance.
just to reiterate: numberInsertAction(view: View) is the entry point/function called by the buttons on the fragment.
MainActivity.kt
class MainActivity : AppCompatActivity(), AddObserverToActivity {
private lateinit var binding: ActivityMainBinding
private lateinit var stateManager: StateManager
override fun onCreate(savedInstanceState: Bundle?) {
//initialize layout
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val activityRoot = binding.root
setContentView(activityRoot)
stateManager = StateManager()
}
override fun addResultObserver(observer: Observer) {
Log.d(TAG, "addObserver! ${observer.toString()} ${observer::class.toString()}")
StateManager.addDisplayObserver(observer)
}
fun numberInsertAction(view: View) {
if (view is Button) {
StateManager.enterDigit(view.text.toString())
}
}
}
CalculatorFragment.kt
class CalculatorFragment : Fragment() {
companion object {
fun newInstance() = CalculatorFragment()
}
private lateinit var binding: FragmentCalculatorBinding
private lateinit var mainActivityHandle: AddObserverToActivity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG, "onCreateView")
binding = FragmentCalculatorBinding.inflate(inflater, container, false)
return inflater.inflate(R.layout.fragment_calculator, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG, "using on view created")
mainActivityHandle = context as AddObserverToActivity
Log.d(TAG, "${binding.Result} ${(binding.Result)::class.simpleName.toString()}")
Log.d(TAG, mainActivityHandle::class.toString())
mainActivityHandle.addResultObserver(DisplayPanel(binding.Result))
}
}
StateManager.kt
class StateManager : Observable() {
private val displayBuffer = DisplayBuffer(DecimalVariable("0"))
fun enterDigit(digit: String) {
Log.d(TAG, "enterDigit: $digit, $currentState")
displayBuffer.insertDigit(digit)
}
fun addDisplayObserver(observer: Observer) {
Log.d(TAG, "addDisplayObserver: $observer")
displayBuffer.addObserver(observer)
}
private fun doNotify(Notified: Any) {
Log.d(TAG, "doNotify: $Notified")
setChanged()
notifyObservers(Notified)
}
}
DisplayBuffer.kt
class DisplayBuffer(initializationValue: SomeClass) : Observable() {
private var initialValue = initializationValue
private var resultString = "0"
var value = initialValue
set(value) {
Log.d(TAG, "setter: $value")
field = value
doNotify()
}
fun set(value: String) {
Log.d(TAG, "set: $value")
this.value = value as Int
}
private fun doNotify() {
Log.d(TAG, "doNotify")
setChanged()
notifyObservers(value.toString())
}
fun insertDigit(digit: String) {
Log.d(TAG, "insertDigit: $digit result: $resultString")
resultString = resultString + digit
Log.d(TAG, "new value: $resultString")
setChanged()
notifyObservers(resultString)
}
}
DisplayPanel.kt
class DisplayPanel(calculationTextView: TextView) : Observer {
private val displayField: TextView = calculationTextView
private val maxDigits = 16
private fun setDisplay(text: String) {
Log.d(TAG, "setDisplay: $text")
if (text.length <= maxDigits) {
displayField.text = text
//displayField.invalidate()
}
}
override fun update(observable: Observable?, targetObjects: Any?) {
Log.d(TAG, "update: $this $observable, $targetObjects")
setDisplay(targetObjects as String)
}
}
Add binding.lifecycleOwner = viewLifecycleOwner in onCreateView or onViewCreated method.
was answered by #Mike M in Comments:
In CalculatorFragment,
He instructed me to change
return inflater.inflate(R.layout.fragment_calculator, container, false) to return binding.root.
as the problem was that this function inflated two instances of the fragment calculator layout and returned the later while it used the former as observer.
to qoute #Mike-M:
The inflater.inflate() call is creating a new instance of that layout that is completely separate from the one that FragmentCalculatorBinding is creating and using itself.
FragmentCalculatorBinding is inflating the view internally, which is why it is passed the inflater in its inflate() call.
I've been trying to delete an item from my list so that it updates without the removed item, but the list seems to redraw itself and keeps displaying all the original items as before. For a short bit of time it's possible to see the item as if it's being removed, however, due to this redrawing everything gets back to what it was before the removal.
I've tried several combinations of the following methods but none of them seem to work in this case.
adapter.notifyItemRangeChanged(position, adapter.itemCount)
adapter.notifyItemRemoved(position)
adapter.notifyItemChanged(position)
adapter.notifyDataSetChanged()
These are my files. Please notice I'm using the Groupie library as a replacement for the default RecyclerView.
class RecyclerProductItem(
private val activity: MainActivity,
private val product: Product,
private val onItemClickListener: OnItemClickListener?
) : Item<GroupieViewHolder>() {
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.apply {
with(viewHolder.itemView) {
ivTrash.setOnClickListener {
if (onItemClickListener != null) {
Toast.makeText(context, "delete method to be added here", Toast.LENGTH_SHORT).show()
onItemClickListener.onClick(viewHolder.adapterPosition)
// deleteProduct(product.id)
}
}
}
}
}
interface OnItemClickListener {
fun onClick(position: Int) //pass your object types.
}
override fun getLayout() = R.layout.recyclerview_item_row
}
And here my fragment:
class ProductsListFragment : Fragment() {
private lateinit var adapter: GroupAdapter<GroupieViewHolder>
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_products_list, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val linearLayoutManager = LinearLayoutManager(activity)
recyclerView.layoutManager = linearLayoutManager
adapter = GroupAdapter()
recyclerView.adapter = adapter
loadProducts()
}
/**
* API calls
*/
private fun loadProducts() {
GetProductsAPI.postData(object : GetProductsAPI.ThisCallback,
RecyclerProductItem.OnItemClickListener {
override fun onSuccess(productList: List<JsonObject>) {
Log.i(LOG_TAG, "successful network call")
for (jo in productList) {
val gson = GsonBuilder().setPrettyPrinting().create()
val product: Product =
gson.fromJson(jo, Product::class.java)
adapter.add(
RecyclerProductItem(
activity as MainActivity,
Product(
product.id,
product.title,
product.description,
product.price
), this
)
)
}
}
override fun onClick(position: Int) {
Log.i(LOG_TAG, position.toString())
adapter.notifyItemRangeChanged(position,
adapter.itemCount)
adapter.notifyItemRemoved(position)
}
})
}
}
Many thanks.
Simple sample
class GroupAdapter(private val items: MutableList<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
fun removeByPosition(position: Int) {
items.removeAt(position)
notifyItemRemoved(position)
}
I am using live data from a shared ViewModel across multiple fragments. I have a sign-in fragment which takes user's phone number and password and then the user presses sign in button I am calling the API for that, now if the sign-in fails I am showing a toast "Sign In failed", now if the user goes to "ForgotPassword" screen which also uses the same view model as "SignInFragment" and presses back from the forgot password screen, it comes to sign-in fragment, but it again shows the toast "Sign In failed" but the API is not called, it gets data from the previously registered observer, so is there any way to fix this?
SignInFragment.kt
class SignInFragment : Fragment() {
private lateinit var binding: FragmentSignInBinding
//Shared view model across two fragments
private val onBoardViewModel by activityViewModels<OnBoardViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_sign_in,
container,
false
)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
onBoardViewModel.signInResponse.observe(viewLifecycleOwner) { response ->
//This is calling again after coming back from new fragment it.
showToast("Sign In Failed")
}
}
override fun onClick(v: View?) {
when (v?.id!!) {
R.id.forgotPasswordTV -> {
findNavController().navigate(SignInFragmentDirections.actionSignInFragmentToForgotPasswordFragment())
}
R.id.signInTV -> {
val phoneNumber = binding.phoneNumberET.text
val password = binding.passwordET.text
val signInRequestModel = SignInRequestModel(
phoneNumber.toString(),
password.toString(),
""
)
//Calling API for the sign-in
onBoardViewModel.callSignInAPI(signInRequestModel)
}
}
}
}
ForgotPasswordFragment
class ForgotPasswordFragment : Fragment() {
private lateinit var binding: FragmentForgotPasswordBinding
//Shared view model across two fragments
private val onBoardViewModel by activityViewModels<OnBoardViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_forgot_password,
container,
false
)
return binding.root
}
}
OnBoardViewModel
class OnBoardViewModel : ViewModel() {
private var repository: OnBoardRepository = OnBoardRepository.getInstance()
private val signInRequestLiveData = MutableLiveData<SignInRequestModel>()
//Observing this data in sign in fragment
val signInResponse: LiveData<APIResource<SignInResponse>> =
signInRequestLiveData.switchMap {
repository.callSignInAPI(it)
}
//Calling this function from sign in fragment
fun callSignInAPI(signInRequestModel: SignInRequestModel) {
signInRequestLiveData.value = signInRequestModel
}
override fun onCleared() {
super.onCleared()
repository.clearRepo()
}
}
I have tried to move this code inside onActivityCreated but it's still getting called after coming back from new fragment.
onBoardViewModel.signInResponse.observe(viewLifecycleOwner) { response ->
showToast("Sign In Failed")
}
Using SingleLiveEvent class instead of LiveData in OnBoardViewModel class will solve your problem:
val signInResponse: SingleLiveEvent <APIResource<SignInResponse>>.
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val pending = AtomicBoolean(false)
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, Observer<T> { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
override fun setValue(t: T?) {
pending.set(true)
super.setValue(t)
}
fun call() {
postValue(null)
}
}
This is a lifecycle-aware observable that sends only new updates after subscription. This LiveData only calls the observable if there's an explicit call to setValue() or call().
I would provide a way to reset your live data. Give it a nullable type. Your observers can ignore it when they get a null value. Call this function when you receive login data, so you also won't be repeating messages on a screen rotation.
class OnBoardViewModel : ViewModel() {
// ...
fun consumeSignInResponse() {
signInRequestLiveData.value = null
}
}
onBoardViewModel.signInResponse.observe(viewLifecycleOwner) { response ->
if (response != null) {
showToast("Sign In Failed")
onBoardViewModel.consumeSignInResponse()
}
}
For Kotlin users #Sergey answer can also be implemented using delegates like below
class SingleLiveEvent<T> : MutableLiveData<T>() {
var curUser: Boolean by Delegates.vetoable(false) { property, oldValue, newValue ->
newValue != oldValue
}
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, Observer<T> { t ->
if (curUser) {
observer.onChanged(t)
curUser = false
}
})
}
override fun setValue(t: T?) {
curUser = true
super.setValue(t)
}
fun call() {
postValue(null)
}
}
I'm using Navigation Component, although I don't think that's the problem. The thing is that when I'm in a fragment that contains a ViewPager and I navigate to another one, when I go back using the back button or the gesture of the mobile phone, it returns to the previous fragment but it stops showing the ViewPager. I'll leave you my code for that fragment:
class HomeFragment : Fragment() {
private lateinit var homeFragmentViewModel: HomeFragmentViewModel
private var listAdapter: FlagsListAdapter? = null
private var regionName: String? = null
private val hashtagLabel: TextView by lazy { home_fragment__label__hashtag }
private val flagViewPager: ViewPager by lazy { home_fragment__viewpager__countries }
private val countryLabel: TextView by lazy { home_fragment__label__country_name }
private val showCasesButton: Button by lazy { home_fragment__button__country_cases }
companion object {
fun newInstance(): HomeFragment {
return HomeFragment()
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
homeFragmentViewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
homeFragmentViewModel.getCountriesFlagLiveData().observeOnce(viewLifecycleOwner, Observer {
setFlagsAdapter(it)
})
showCasesButton.setOnClickListener {
val actionNavigateToShowCasesFragment = HomeFragmentDirections.navigateHomeFragmentToShowCasesFragment()
regionName?.let { regionName -> actionNavigateToShowCasesFragment.regionName = regionName }
it.findNavController().navigate(actionNavigateToShowCasesFragment)
}
setFormatHashtag()
}
private fun setFlagsAdapter(flagModelList: List<FlagModel>) {
listAdapter = context?.let {
FlagsListAdapter(
flagModelList,
it
)
}
flagViewPager.adapter = listAdapter
flagViewPager.setPadding(130, 0, 130, 0)
flagViewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
Toast.makeText(GlobalApplication.getContextFromApplication, "Hola", Toast.LENGTH_SHORT).show()
}
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
countryLabel.text = ""
countryLabel.text = flagModelList[position].regionName
regionName = flagModelList[position].regionName
}
override fun onPageSelected(position: Int) {
countryLabel.text = flagModelList[position].regionName }
})
}
private fun setFormatHashtag() {
val text = getString(R.string.home_fragment_hashtag)
val spannableString = SpannableString(text)
val foregroundColorSpan = context?.let {
ForegroundColorSpan(ContextCompat.getColor(it, R.color.hashtagColor))
}
spannableString.setSpan(foregroundColorSpan, 0, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
hashtagLabel.text = spannableString
}
}
This is my activity:
class MainActivity : AppCompatActivity() {
private val navigationBottomBar by lazy { activity_main__navigation_view__bottom_bar }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setUpNavigation()
}
private fun setUpNavigation() {
val navController = Navigation.findNavController(this, R.id.activity_main__graph__nav_host)
NavigationUI.setupWithNavController(navigationBottomBar, navController)
}
}
When you load the fragment the first time it is shown like this, which is how it should be shown, and if I use the Bottom Navigation View it does well too:
But when I use the back button on my phone, here's what happens:
The problem is in your HomeFragment,setFlagsAdapter(it)` doesn't get called when you come back to this fragment. Either
change observeOnce to observe
or
Move
homeFragmentViewModel.getCountriesFlagLiveData().observeOnce(viewLifecycleOwner, Observer {
setFlagsAdapter(it)
})
from onCreateView to
override fun onResume(){
super.onResume()
homeFragmentViewModel.getCountriesFlagLiveData().observeOnce(viewLifecycleOwner, Observer {
setFlagsAdapter(it)
})
}
the question is how to pass data from BottomSheetDialogFragment to Fragment or Activity and what would be the correct way ?
Here is my Fragment dialog that will be opened in my Frament and should save data from textview that is getting clicked on.
class BallTypeDialogFragment : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
inflater.inflate(R.layout.fragment_blood_type_dialog, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
text_view_ball_O.setOnClickListener {
text_view_ball_O.text
Toast.makeText(context, "O+", Toast.LENGTH_SHORT).show()
}
text_view_ball_A.setOnClickListener {
text_view_ball_A.text
Toast.makeText(context, "A+", Toast.LENGTH_SHORT).show()
}
text_view_ball_AA.setOnClickListener {
Toast.makeText(context, "AA+", Toast.LENGTH_SHORT).show()
}
text_view_blood_grop_minus.setOnClickListener {
text_view_blood_grop_minus.text
Toast.makeText(context, "-", Toast.LENGTH_SHORT).show()
}
text_view_ball_AAR.setOnClickListener {
text_view_ball_AAR.text
Toast.makeText(context, "R -", Toast.LENGTH_SHORT).show()
}
text_view_ball_AARS.setOnClickListener {
text_view_ball_AARS.text
Toast.makeText(context, "AARS -", Toast.LENGTH_SHORT).show()
}
text_view_ball_OO.setOnClickListener {
text_view_ball_OO.text
Toast.makeText(context, "OO -", Toast.LENGTH_SHORT).show()
}
}
}
And i Simply open it in my Fragment like this,even though I understand it is incorrect.
private fun showDialog() {
val dialog = BallTypeDialogFragment()
dialog.show(childFragmentManager, "BallTypeDialogFragment")
}
So here is how I solved the problem.
I created an interface in my BottomSheetDialogFragment with String variable for a class
private var ballType: String = ""
interface OnBallGroupSelectedListener {
fun onBalldGroupListener(ballType: String)
}
When I was selecting value in my Dialog I was setting value to a string and then using method to pass the values to my parent Fragment.
private fun getBloodGroupResults() {
val listener = targetFragment as OnBallGroupSelectedListener?
listener?.onBalldGroupListener(ballType)
dismiss()
}
Then in my parent Fragment simply implementing the Interface and creating String variable that will be set in the Interface
private var ballType: String? = ""
override fun onBallGroupListener(ballType: String) {
this.ballType = ballType
}
Since you're using kotlin, you might consider passing a lambda to your dialogfragment.
E.g.
BallTypeDialogFragment(onData: (String) -> Unit)
and then you pass it by
private fun showDialog(onData: (String) -> Unit)) {
val dialog = BallTypeDialogFragment(onData)
dialog.show(childFragmentManager, "BallTypeDialogFragment")
}
then in your DialogFragment you just do:
//something something
text_view_ball_O.setOnClickListener {
onData(text_view_ball_O.text)
Toast.makeText(context, "O+", Toast.LENGTH_SHORT).show()
}
//something something
1- Create an interface.
interface DialogActivityContract{
fun onPassDataRequsted(dataType: DataType)
}
2- Implement that interface to the activity:
class ActivityThatHoldsTheDialogActivity : SomeAppCompactActivity(),DialogActivityContract{
//other methods here
override public void onPassDataRequsted(DataType dataType){
//handle data here
}
}
And in your fragment:
lateinit var dialogActivityContract: DialogActivityContract
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialogActivityContract = (activity as ActivityThatHoldsTheDialogActivity)
}
// some methods here
fun whenYouNeedToSendThatData(){
dialogActivityContract.onPassDataRequsted(yourData)
}
Another way of doing it is using the EventBus library.
You can use listeners as follows
open class BallTypeDialogFragment<L: BallTypeDialogFragment.BottomSheetClickListener.SingleAction> : BottomSheetDialogFragment(){
open fun showWithListener(listener: L, fm : FragmentManager, tag : String) {
this.listener = listener
show(fm, tag)
}
interface BottomSheetClickListener {
interface SingleAction : BottomSheetClickListener {
fun passData(ballType: String)
}
}
}
}
And then in the calling Fragment.
activity?.supportFragmentManager?.let {
BallTypeDialog<LocationBottomSheet.BottomSheetClickListener.SingleAction>().showWithListener(object : BallTypeDialogFragment.BottomSheetClickListener.SingleAction {
override fun passData(data : String)
}, it, "test" )
}