在Kotlin Andorid的ViewHolder中的getActivity()/上下文

我正在构建一个ViewHolder和一个片段的适配器,当我尝试为ViewHolder做一个OnClick,没有任何我传递的上下文工作。 我可以使用getActivity()没有任何activity ,并且p0!!.contextitemView.context也可以使用。 我应该从哪里得到我的背景,以及如何参考? 谢谢!

 package com._________.criminalintent import android.os.Bundle import android.support.v4.app.Fragment import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import android.widget.Toast class CrimeListFragment: Fragment() { private var mCrimeRecyclerView: RecyclerView? = null private var mAdapter: CrimeAdapter? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { // fragment_crime_list.xml has a RecyclerView element = crime_recycler_view // inflate the fragment into the activity val view = inflater!!.inflate(R.layout.fragment_crime_list, container, false) // grab the recyclerView and give it a required layoutManager mCrimeRecyclerView = view.findViewById(R.id.crime_recycler_view) mCrimeRecyclerView!!.layoutManager = LinearLayoutManager(activity) updateUI() return view } private fun updateUI() { val crimeLab = CrimeLab.get(activity) val crimes = crimeLab.getCrimes() mAdapter = CrimeAdapter(crimes) // Connect the adapter to the recyclerView mCrimeRecyclerView!!.adapter = mAdapter } /** * in Kotlin, we must give the view passed into the constructor directly * as a substitute for a super() call * * create a ViewHolder that holders the crime list item's view * * super(itemView) = super(inflater!!.inflate(R.layout.list_item_crime, parent, false)) * MUST give it the direct value in Kotlin */ private class CrimeHolder(inflater: LayoutInflater?, parent: ViewGroup): RecyclerView.ViewHolder(inflater!!.inflate(R.layout.list_item_crime, parent, false)), View.OnClickListener { private var mCrime: Crime? = null /** * When given a crime, this CrimeHolder will update the title and date for this Crime */ fun bind(crime: Crime) { mCrime = crime val titleTextView = itemView.findViewById<TextView>(R.id.crime_title) val dateTextView = itemView.findViewById<TextView>(R.id.crime_date) titleTextView.text = mCrime!!.mTitle dateTextView.text = mCrime!!.mDate.toString() } override fun onClick(p0: View?) { Toast.makeText(WHAT_TO_PUT_HERE, "${mCrime!!.mTitle} clicked!", Toast.LENGTH_SHORT / 2) .show() } } private class CrimeAdapter(private var mCrimes: MutableList<Crime>): RecyclerView.Adapter<CrimeHolder>() { /** * - Calls our CrimeHolder to make our custom ViewHolders * - Called by RecyclerView when it needs a new view to display * - Gets the layoutInflater from the ViewGroup and returns a CrimeHolder of it */ override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): CrimeHolder = CrimeHolder(LayoutInflater.from(parent!!.context), parent) /** * Bind the crime (data) to the CrimeHolder */ override fun onBindViewHolder(holder: CrimeHolder?, position: Int) { holder!!.bind(mCrimes[position]) } /** * Sees how many items are in the RecyclerView that need to be shown */ override fun getItemCount(): Int = mCrimes.size } } 

在你的实现中,你可以安全地使用从View提供给你的OnClickListener

 override fun onClick(p0: View) { Toast.makeText(p0.context, "${mCrime!!.mTitle} clicked!", Toast.LENGTH_SHORT / 2) .show() } 

只要记得设置onclick:

 fun bind(crime: Crime) { mCrime = crime val titleTextView = itemView.findViewById<TextView>(R.id.crime_title) val dateTextView = itemView.findViewById<TextView>(R.id.crime_date) titleTextView.text = mCrime!!.mTitle dateTextView.text = mCrime!!.mDate.toString() itemView.setOnClickListener(this) } 

而且所有的Kotlin类都默认是嵌套的( static )。 所以你的private class CrimeHolder相当于Java中的private static class CrimeHolder 。 这就是为什么你没有从CrimeHolder访问getActivity() CrimeHolder

在持有者内使用itemView.context属性。

编辑:为什么你的onClick不“工作”(不叫)是因为你还没有注册onClickListener ,例如:

 itemView.setOnClickListener(this) 

在你的持有者initbind