Home > Net >  Inflating BottomSheetDialog from an item click in a RecyclerVIew?
Inflating BottomSheetDialog from an item click in a RecyclerVIew?

Time:06-15

I have implemented a method that launches the BottomSheetDialog but I am facing this error

 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
    at android.view.ViewRootImpl.setView(ViewRootImpl.java:907)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:387)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
    at android.app.Dialog.show(Dialog.java:342)
    at com.example.moveapplication.adapter.PostAdapter.openBottomSheet(PostAdapter.kt:136)
    at com.example.moveapplication.adapter.PostAdapter.onBindViewHolder$lambda-2(PostAdapter.kt:53)
    at com.example.moveapplication.adapter.PostAdapter.$r8$lambda$Ya4NMbtCP1ASbfWIkCscOWrPyOw(Unknown Source:0)
    at com.example.moveapplication.adapter.PostAdapter$$ExternalSyntheticLambda2.onClick(Unknown Source:4)
    at android.view.View.performClick(View.java:7125)
    at android.view.View.performClickInternal(View.java:7102)
    at android.view.View.access$3500(View.java:801)
    at android.view.View$PerformClick.run(View.java:27336)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Here is method called after an item click

private fun openBottomSheet(publisher: String) {
     val inflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
     val view = inflater.inflate(R.layout.bottom_sheet_dialog, null)
     val uImage = view.findViewById<ImageView>(R.id.sheetIvProfileImage)
     val uNumber = view.findViewById<TextView>(R.id.sheetTvOwnerNumber)
     val uEmail = view.findViewById<TextView>(R.id.tvOwnerEmail)
     val uAbout = view.findViewById<TextView>(R.id.tvOwnerAbout)
     val uTitle = view.findViewById<TextView>(R.id.sheetTvOwnerTitle)

     val ownersRef = FirebaseFirestore.getInstance().collection("owners").document(publisher)
     ownersRef.get().addOnSuccessListener { document ->
         val ownerModel = document.toObject(Owner::class.java)
         Glide.with(mContext)
             .load(ownerModel!!.profileImage)
             .into(uImage)
         uTitle.text = ownerModel.username
         uNumber.text = ownerModel.phoneNumber
         uEmail.text = ownerModel.email
         uAbout.text = ownerModel.about
     }

    val bottomSheetDialog = Dialog(mContext)
    bottomSheetDialog.apply {
        setContentView(view)
        setCancelable(true)
        window?.setLayout(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT)
        window?.setGravity(Gravity.BOTTOM)
        show()
    }

 }

I am not familiar with another way of doing inflating the bottomsheetdialog. Using the method was a trial to see if it could work.

on my onBindViewHolder the item responsible for click i've implemented it this way

 holder.publisher.setOnClickListener {
        openBottomSheet(post.publisher)
    }

CodePudding user response:

To do that you can easily use material design bottom sheet. first you need to add material dependency to your build.gradle:

dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
    // ...
}

then you should create a kotlin file/class and extend BottomSheetDialogFragment()

class ModalBottomSheet : BottomSheetDialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? = inflater.inflate(R.layout.modal_bottom_sheet_content, container, false)
}

you can also set different styles to your custom bottomsheet

you can see the basic usage below:

class MainActivity : AppCompatActivity() {
    ...
    val modalBottomSheet = ModalBottomSheet()
    modalBottomSheet.show(supportFragmentManager, TAG)
    ...
}

CodePudding user response:

Create a interface

interface RecyclerClickListeners {
fun onRecyclerViewItemClick(view: View, str: String) }

Add interface to RecyclerAdapter and Fragment

Fragment:

class TestFragment :
Fragment(),    
RecyclerClickListeners {
private val recyclerAdapter = TestRecyclerAdapter(arrayListOf(),this)... }

Recycler Adapter:

class TestRecyclerAdapter(private val myList: ArrayList<TestModel>, val listener: RecyclerClickListeners) ...

Send your string in onBindViewHolder to Fragment

        holder.binding.myBtn.setOnClickListener {
        listener.onRecyclerViewItemClick(it, "Mystring")
    }

In Fragment call or create bottomsheetdialog

override fun onRecyclerViewItemClick(view: View, str: String) { println(str) }
  • Related