Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow selecting text from different textview items at once in android recyclerview

There are many Textviews in a Recyclerview, selecting the text content of each one with long click all right but selection pins don't allow to select test from next TextView, it allow selecting only inside current TextView. How to allow overflow text selection that contains different TextView items?

For exampe as seen on the picture below, TextView one is green, TextView two is purple, when selection start on green one the selection doesn't countinue to beyond the green one. So both green and purple TextViews should be selectable sometime.

(After that I should get the selected text and its TextViews.)

enter image description here

like image 244
ATES Avatar asked Jun 06 '20 02:06

ATES


People also ask

How do you select items in the Recycler view?

Single Selection in Android RecyclerView When user clicks the another position, forget previous one and make new position as hold position. Make a new position on hold is not the big thing to do, but main thing is to forget the previous position. For that we are using notifyItemChanged(position) method of recyclerview.


1 Answers

Solution

  • Since Selection can be done for 1 TextView not a multiple of them at the same time, I think to do what you want we kinda wanna mock that behavior using BackgroundColorSpan
  • Note that we will be able to show thee highlight like a selection but won't be able to show selection handlers

Preview

UI Preview

Code

Activity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import android.widget.TextView
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.maproductions.mohamedalaa.stackoverflow_solutions.R
import com.maproductions.mohamedalaa.stackoverflow_solutions.view.rv_adapter.RVAdapterRVTextViewsSeveralTextSelectionActivity
import kotlinx.android.synthetic.main.activity_r_v_text_views_several_text_selection.*
import mohamedalaa.mautils.core_android.extensions.toast

class RVTextViewsSeveralTextSelectionActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_r_v_text_views_several_text_selection)

        val adapter = RVAdapterRVTextViewsSeveralTextSelectionActivity()
        recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter

        toastAllMaterialButton.setOnClickListener {
            toast(adapter.getAllSelectedTexts().joinToString("\n"))
        }
    }
}

activity.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".view.RVTextViewsSeveralTextSelectionActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"

        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/toastAllMaterialButton"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        android:layout_margin="16dp"

        android:text="Toast all selected texts as several lines"
        android:textAllCaps="false"
        android:textSize="20sp"/>

</LinearLayout>

RecyclerViewAdapter.kt

import android.annotation.SuppressLint
import android.graphics.Color
import android.text.style.BackgroundColorSpan
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.text.buildSpannedString
import androidx.recyclerview.widget.RecyclerView
import com.maproductions.mohamedalaa.stackoverflow_solutions.R
import mohamedalaa.mautils.core_android.extensions.inflateLayout
import mohamedalaa.mautils.core_android.extensions.plusAssign

@SuppressLint("SetTextI18n")
class RVAdapterRVTextViewsSeveralTextSelectionActivity
    : RecyclerView.Adapter<RVAdapterRVTextViewsSeveralTextSelectionActivity.ViewHolder>() {

    // Set this color to whichever color you want.
    private val highlightingTextColor = Color.parseColor("#CBDCFF")

    private val selectedIndices = mutableListOf<Int>()

    override fun getItemCount(): Int = 20

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            parent.context.inflateLayout(R.layout.rv_item_activity_r_v_text_views_several_text_selection)
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = buildSpannedString {
            append(getTextAtIndex(position))

            if (position in selectedIndices) {
                this += BackgroundColorSpan(highlightingTextColor)
            }
        }

        holder.itemView.setOnLongClickListener {
            if (position in selectedIndices) {
                selectedIndices -= position
            }else {
                selectedIndices += position
            }

            notifyItemChanged(position)

            true
        }
    }

    fun getAllSelectedTexts(): List<String> {
        return selectedIndices.map { getTextAtIndex(it) }
    }

    // getTextAtIndex is instead of myData.get(position).name
    private fun getTextAtIndex(index: Int): String {
        return "I am a text with index -> $index"
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textView: TextView = itemView.findViewById(R.id.textView)
    }

}

recycler_view_item.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/textView"

    android:padding="16dp"

    android:textSize="24sp"
    android:textColor="@android:color/black"

    tools:text="I am a text with index -> 0" />
like image 80
Mohamed Alaa Avatar answered Oct 12 '22 16:10

Mohamed Alaa