I trying to implement item click with RecyclerView about 2 days. I tried doing all that was suggested stackoverflow about this subject. I have no any ideas already what to do anymore. Therefore I want to ask you.
This is my code:
class CustomAdapter(var data: List<DataSource>, val clickListener: OnWordItemClickListener):
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
{
val tv_front: TextView = view.findViewById(R.id.tv_front) as TextView
val tv_back: TextView = view.findViewById(R.id.tv_back) as TextView
// Define the click listener
fun initialize(dataSource: DataSource, action: OnWordItemClickListener)
{
tv_front.text = dataSource._front
tv_back.text = dataSource._back
itemView.setOnClickListener {
action.onItemClick(dataSource, adapterPosition)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.row_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
/*val currentItem = data[position]
holder.tv_front.text = currentItem._front
holder.tv_back.text = currentItem._back*/
holder.initialize(data[position], clickListener)
}
override fun getItemCount(): Int = data.size
}
interface OnWordItemClickListener
{
fun onItemClick(dataSource: DataSource, position: Int)
}
And code from MainActivity:
class MainActivity : AppCompatActivity(), OnWordItemClickListener {
val PERMISSION_REQUEST_CODE: Int = 123
private lateinit var linearLayoutManager: LinearLayoutManager
lateinit var rv_allWords: RecyclerView
lateinit var adapter: CustomAdapter
lateinit var databaseHandler: DatabaseHandler
lateinit var dataSource: DataSource
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
permissions()
rv_allWords = findViewById(R.id.rv_allWords) as RecyclerView
linearLayoutManager = LinearLayoutManager(this)
rv_allWords.layoutManager = linearLayoutManager
databaseHandler = DatabaseHandler(this)
val exampleList = databaseHandler.read_from()
adapter = CustomAdapter(exampleList, this)
rv_allWords.adapter = adapter
adapter.notifyDataSetChanged()
}
fun permissions()
{
//var permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) +
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED)
{
// permission granted
} else {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE)
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode)
{
PERMISSION_REQUEST_CODE ->
{
if ((grantResults.isNotEmpty()) && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED)
{
// permissions is granted. Continue the action or workflow
Toast.makeText(this, "Permissions granted", Toast.LENGTH_SHORT).show()
} else {
// Explain to the user that the feature is unavailable because
// the features requires a permission the the user has denied
val alertDialog: AlertDialog? = this?.let {
val builder = AlertDialog.Builder(it)
builder.apply {
setPositiveButton(R.string.OK, DialogInterface.OnClickListener { dialog, id ->
finish()
System.exit(0)
})
setMessage("The app needs to save some data to external storage.")
}
builder.show()
}
}
return
}
// Add other 'when' line to check for other
// permissions this app might request
else ->
{
// Ignore all other requests
}
}
}
fun generateTestList(size: Int): List<DataSource> {
val list = ArrayList<DataSource>()
for (i in 0 until size)
{
val item = DataSource(i, "Item $i", "$i")
list += item
}
return list
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
var id = item.itemId
if(id == R.id.menu_refresh)
{
}
return super.onOptionsItemSelected(item)
}
override fun onResume() {
super.onResume()
databaseHandler.read_from()
}
override fun onItemClick(dataSource: DataSource, position: Int) {
Toast.makeText(this, dataSource._back, Toast.LENGTH_SHORT).show()
Log.i("onItemClick", dataSource._back)
}
}
When I run the app on device or emulator, happens nothing. That is when I try to click on any item in RecyclerView, my message doesn't displayed and the app runs without errors. Sorry for my english. What else can i do?
Where is itemView
defined? I may be wrong but you should change itemView
for view
inside initialize()
method.
Try to implement View.OnClickListener
with ViewHolder
class.
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
//(...)
fun initialize(dataSource: DataSource, action: OnWordItemClickListener)
{
tv_front.text = dataSource._front
tv_back.text = dataSource._back
view.setOnClickListener{action.onItemClick(dataSource, adapterPosition)}
}
UPDATE: So after investigating the rest of the code i found two LinearLayouts inside xml used for ViewHolder layout. I deleted the 'parent one' and it started working. Here is row_item.xml after changes.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/tv_front"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:text="Front"
android:textSize="32sp"
android:gravity="left"
android:layout_weight="1" />
<TextView
android:id="@+id/tv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:text="Back"
android:textSize="32sp"
android:gravity="right"
android:layout_weight="1" />
</LinearLayout>