0

For a school project, I made a custom arrayadapter with a context, resources and items attribute. Today I received feedback from my teacher and he wants me to find a solution where I don't have a Context attribute because he doesnt like that I always need to specify the context.

This is my code:

class TalentListAdapter(
    var mCtx: Context,
    var resources: Int,
    var items: MutableList<Talent>
) : ArrayAdapter<Talent>(mCtx, resources, items) {

    lateinit var mItem: Talent

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val layoutInflater: LayoutInflater = LayoutInflater.from(mCtx)
        val view: View = layoutInflater.inflate(resources, null)
        mItem = items[position]

        //set name of talent
        val talentTextView: TextView = view.findViewById(R.id.talentName)
        talentTextView.text = mItem.toString()

        return view
    }
}

He wants to get rid of the mCtx: Context attribute, but I don't find a solution for it. Any suggestions?

The adapter is created like this atm:

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val listView: ListView = binding.talentList

        // set custom adapter for talent_list
        val adapter = TalentListAdapter(view.context, R.layout.talentlayout, binding.talentViewModel?.getTalents()?.value as MutableList<Talent>)
        listView.adapter = adapter

    }
EwoutxD
  • 53
  • 2
  • If you want to use `ArrayAdapter` you need to pass context as param. You should always pass `aplicationContext` to avoid memory leaks. Your question does not specify what the adapter is used for, possibly there are alternatives, such as RecyclerView Adapter or BaseAdapter. – Sylwek845 Oct 29 '20 at 22:12

2 Answers2

0

Can you try this

class YourAdapter() : RecyclerView.Adapter<YourAdapter.ViewHolder>() {

    inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view)

    var Data: List<YourResponse> = emptyList()
        set(value) {
            field = value
            notifyDataSetChanged()
        }

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

    override fun getItemCount(): Int {
        return Data.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val getYourModel = Data[position]

        val Binding = holder.view

        Binding.yourTextView.apply{
            text = getYourModel.yourField
        }

        .....
    }

}

and pass Data from your Fragment or Activity (my example uses Retrofit2)

private var theList: List<YourResponse> = emptyList()
private val theAdapter =yourAdapter()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    onUpdateData()
}

 private fun onUpdateData() {
     ...
         override fun onResponse(call: Call<YourResponse>, response: Response<YourResponse>) {
             val body = response.body()?.results
             if (response.isSuccessful && body != null) {
                 onUpdateDataSuccess(body)
             } else {
                 // Something
             }
         }
     ...
 }

 private fun onUpdateDataSuccess(data: List<YourResponse>) {
     theList = data
     theAdapter.Data = data
 }

...
Dharman
  • 30,962
  • 25
  • 85
  • 135
Aldan
  • 674
  • 9
  • 23
0

You only need context while inflating so you should use parent.context instead of explicit context. Parent.Context represent the Activity/Fragment where this recycler view is implemented.

Hamza Israr
  • 411
  • 2
  • 7