简体   繁体   中英

Popup inside a recycler View

I need help because I face to an issue since a long time and I can't resolve it... I have this error message and my app crash when I click on a button:

 java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
        at android.app.Activity.startActivityForResult(Activity.java:5251)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
        at android.app.Activity.startActivityForResult(Activity.java:5208)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:662)
        at android.app.Activity.startActivity(Activity.java:5579)
        at androidx.core.content.ContextCompat.startActivity(ContextCompat.java:251)
        at fr.amseu.mystretching.adapter.ChooserAdapter$onBindViewHolder$1.onClick(ChooserAdapter.kt:38)
        at android.view.View.performClick(View.java:7870)
        at android.view.View.performClickInternal(View.java:7839)
        at android.view.View.access$3600(View.java:886)
        at android.view.View$PerformClick.run(View.java:29363)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7948)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)

What happened is that I have a Recycler View of item in a Navigation bar. I would that when we click on an item, it open a popup. But with my code, when I click it happen the upper code. Here is my popup Activity ( that I have simplified to find the problem ):

class MusclePopup(
        private val adapter: ChooserAdapter,
        private val currentItem: ChoosersModel
) : Dialog(adapter.context) {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        setContentView(R.layout.fragment_popup)
        setupComponents()
    }

    private fun setupComponents() {
        findViewById<TextView>(R.id.input_chooser).text = currentItem.description
    }
}

and this is my adapter Activity, the same that is used for my recycler view of the clicked items:

class ChooserAdapter(
        val context: ChooserActivity,
        private val ChooseList: ArrayList<ChoosersModel>)
    :RecyclerView.Adapter<ChooserAdapter.ViewHolder>(){

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var chooserNumber: TextView = view.findViewById(R.id.item_number)
        var chooserDescription: TextView = view.findViewById(R.id.item_description)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.item_chooser, parent, false)

        return ViewHolder(view)
    }
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val currentItem = ChooseList[position]

        holder.chooserNumber.text = currentItem.number
        holder.chooserDescription.text = currentItem.description
        holder.itemView.setOnClickListener {
            MusclePopup(this, currentItem).show()
        }
    }

    override fun getItemCount(): Int = ChooseList.size
}

With my tests, I think that the error comes from this line:

 holder.itemView.setOnClickListener {
            MusclePopup(this, currentItem).show()
        }

If you need more information, I can give it to you, thanks for any help !

Use <YourActivity>.this wherever you need context. I am suspecting that context is null when initializing the Adapter.

I am not exactly sure as to why you are passing the whole adapter to your dialog, to inflate the dialog you just need the context which can be provided without providing the whole Adapter.

Secondly, I feel it would be better if you separate out the code of inflating the dialog to your activity as that is where it should belong for which you can use an interface.

Here are the changes I will recommend.

ChooserAdapter.kt will be as follows now

class ChooserAdapter(
        private val chooserAdapterCallback: ChooserAdapterCallback,
        private val ChooseList: ArrayList<ChoosersModel>)
    :RecyclerView.Adapter<ChooserAdapter.ViewHolder>(){

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var chooserNumber: TextView = view.findViewById(R.id.item_number)
        var chooserDescription: TextView = view.findViewById(R.id.item_description)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.item_chooser, parent, false)

        return ViewHolder(view)
    }
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val currentItem = ChooseList[position]

        holder.chooserNumber.text = currentItem.number
        holder.chooserDescription.text = currentItem.description
        holder.itemView.setOnClickListener {
            chooserAdapterCallback.onChooseAdapterClick(currentItem)
        }
    }

    override fun getItemCount(): Int = ChooseList.size
    
    interface ChooserAdapterCallback{
        fun onChooseAdapterClick(currentItem: ChoosersModel)
    }
}

Next, inside your ChooserActivity , you will have to implement, the interface, which will be roughly around as follows. Also you will need to modify your Adapter initialization and pass this there so roughly as ChooserAdapter(this, chooseList)

class ChooserActivity : AppCompatActivity(), ChooserAdapter.ChooserAdapterCallback {
override fun onChooseAdapterClick(currentItem: ChoosersModel) {
        MusclePopup(this, currentItem).show()
    }
}

Next you will have to modify your MusclePopup class to as follows:

class MusclePopup(
        private val context: Context,
        private val currentItem: ChoosersModel
) : Dialog(context)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM