title: How to set String key in recyclerview-selection in Android?
body: <p>I am implementing <code>RecyclerView</code> and want to get details of selected items.
  I am following a tutorial given <a href="https://code.tutsplus.com/tutorials/how-to-add-selection-support-to-a-recyclerview--cms-32175" rel="nofollow noreferrer">here</a>. But I want to get some string key instead of item position.</p>
  
  <p>For example, if i do like this:</p>
  
  <pre><code>for (selection in selectionTracker?.selection!!)
      Log.e("tag", selection.toString())                   
  </code></pre>
  
  <p>I get indexes as output, but I want to get string keys here.</p>
  
  <p>But I don't know what further changes should be made if I do like this:</p>
  
  <pre><code>fun getItemDetails() = object: ItemDetailsLookup.ItemDetails&lt;Long&gt;() {
      override fun getSelectionKey() = itemId
      override fun getPosition() = adapterPosition
  }
  </code></pre>
  
  <p>and change it into:</p>
  
  <pre><code>fun getItemDetails() = object: ItemDetailsLookup.ItemDetails&lt;Long&gt;() {
      override fun getSelectionKey() = myData[adapterPosition].myKey // a string
      override fun getPosition() = adapterPosition
  }
  </code></pre>
  
  <p>----EDIT----
  These are my codes:</p>
  
  <p>The adapter class:</p>
  
  <pre><code>class AdapterSubjectsIndexRV (
      private val indexList: ArrayList&lt;ModelSubjectsIndex&gt;,
      val itemClick: (String) -&gt; Unit
  ): RecyclerView.Adapter&lt;AdapterSubjectsIndexRV.MyViewHolder&gt;() {
  
      // every recycler view item has unique id
      init {
          setHasStableIds(true)
      }
  
      // Provide a reference to the views for each data item
      // Complex data items may need more than one view per item, and
      // you provide access to all the views for a data item in a view holder.
      inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
          val courseValue = itemView.findViewById&lt;TextView&gt;(R.id.course_value)!!
          val courseCode = itemView.findViewById&lt;TextView&gt;(R.id.course_code)!!
          val courseName = itemView.findViewById&lt;TextView&gt;(R.id.course_name)!!
          val progressValue = itemView.findViewById&lt;TextView&gt;(R.id.progress_value)!!
          val progressBar = itemView.findViewById&lt;ProgressBar&gt;(R.id.progress_bar)!!
          val selectedOverlay = itemView.findViewById&lt;View&gt;(R.id.subjects_card_view_selected)!!
  
          // set click events
          init {
              itemView.setOnClickListener {
                  itemClick(courseCode.text.toString())
              }
          }
  
          // get item details
          fun getItemDetails() = object: ItemDetailsLookup.ItemDetails&lt;String&gt;() {
              // override fun getSelectionKey() = itemId
              override fun getSelectionKey() = indexList[adapterPosition].courseCode
              override fun getPosition() = adapterPosition
          }
  
      }
  
      // lookup class
      class MyItemDetailsLookup(private val rv: RecyclerView): ItemDetailsLookup&lt;String&gt;() {
          override fun getItemDetails(e: MotionEvent): ItemDetails&lt;String&gt;? {
              val v = rv.findChildViewUnder(e.x, e.y)
              return if (v != null) {
                  (rv.getChildViewHolder(v) as MyViewHolder).getItemDetails()
              } else null
          }
      }
  
      // set tracker
      var tracker: SelectionTracker&lt;Long&gt;? = null
  
      // Create new views (invoked by the layout manager)
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AdapterSubjectsIndexRV.MyViewHolder {
          // create a new view
          val itemView = LayoutInflater.from(parent.context).inflate(R.layout.subjects_card, parent, false)
          return MyViewHolder(itemView)
      }
  
      // Replace the contents of a view (invoked by the layout manager)
      override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
          holder.courseValue.text = indexList[position].courseValue
          holder.courseCode.text = indexList[position].courseCode
          holder.courseName.text = indexList[position].courseName
          holder.progressValue.text = "${indexList[position].progress}%"
          holder.progressBar.progress = indexList[position].progress
  
          // Highlight the item if it's selected
          holder.selectedOverlay.visibility = if (tracker!!.isSelected(position.toLong())) View.VISIBLE else View.INVISIBLE
      }
  
      // Return the size of your data set (invoked by the layout manager)
      override fun getItemCount() = indexList.size
  
      override fun getItemId(position: Int): Long {
          return position.toLong()
      }
  }
  </code></pre>
  
  <p>And this is how I am setting my fragment:</p>
  
  <pre><code>val rvAdapter = AdapterSubjectsIndexRV(getSubjectsIndexList(subjectsList)) {
      // if not in selection mode
      if (selectionTracker?.selection?.size() == 0) {
          listener.showSubjectDetails(it)
      }
  }
  
  // set recycler view
  val recyclerView = theView.findViewById&lt;RecyclerView&gt;(R.id.subjects_recycler_view)
  recyclerView.apply {
      setHasFixedSize(true)
      layoutManager = LinearLayoutManager(activity)
  
      adapter = rvAdapter
  }
  
  // set selection tracker
  selectionTracker = SelectionTracker
       .Builder&lt;Long&gt;(
          "subjects_index_selection",
          recyclerView,
          StableIdKeyProvider(recyclerView),
         AdapterSubjectsIndexRV.MyItemDetailsLookup(recyclerView),
          StorageStrategy.createLongStorage()
     ).withSelectionPredicate(
          SelectionPredicates.createSelectAnything()
     ).build()
  
  rvAdapter.tracker = selectionTracker
  
  if(savedInstanceState != null)
         selectionTracker?.onRestoreInstanceState(savedInstanceState)
  
  return theView
  </code></pre>