首页 > 解决方案 > 允许在 android recyclerview 中一次从不同的 textview 项目中选择文本

问题描述

Recyclerview 中有很多 Textview,长按可以选择每个文本的文本内容,但是选择引脚不允许从下一个 TextView 中选择测试,它只允许在当前 TextView 内选择。如何允许包含不同 TextView 项的溢出文本选择?

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. 所以绿色和紫色的 TextViews 应该在某个时候都可以选择。

(之后我应该得到选定的文本及其 TextViews。)

在此处输入图像描述

标签: javaandroidandroid-layoutandroid-recyclerview

解决方案


解决方案

  • 由于可以同时对 1 个TextView而不是其中的多个进行选择,我认为要做你想做的事情,我们有点想用BackgroundColorSpan
  • 请注意,我们将能够像选择一样显示突出显示,但无法显示选择处理程序

预习

用户界面预览

代码

活动.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"))
        }
    }
}

活动.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" />

推荐阅读