android - 如何在 RecyclerView Adapter 中使用 TextWatcher

标签 android android-recyclerview kotlin android-adapter

我有一个 recyclerview,这就是项目。

enter image description here

适配器几乎可以正常工作。问题是当我尝试使用 EditText 添加数量时,它不起作用。我尝试添加一个 TextWatcher 但没有任何反应。我想我没有正确使用它。这是我在适配器中的类:

class ProductoViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    var nombreProducto: TextView = view.tv_producto_seleccion
    var especialidadProducto: TextView = view.tv_especialidad_producto
    var btnMinus: ImageView = view.img_minus
    var btnPlus: ImageView = view.img_plus
    var cantidadProducto: EditText = view.tv_producto_cantidad
    var layoutWrapper: LinearLayout = view.layoutWrapper
    var checkBoxProductos: CheckBox = view.cb_productos

    fun bindItem(producto: Producto) {
        nombreProducto.text = producto.nombre
        especialidadProducto.text = producto.categoria

        btnPlus.setOnClickListener {
            producto.cantidad += 1
            cantidadProducto.setText(producto.cantidad.toString())
        }

        btnMinus.setOnClickListener {
            if (producto.cantidad > 0) {
                producto.cantidad -= 1
            } else if (producto.cantidad == 0) {
                val mySnackbar = Snackbar.make(itemView, "Ya no puedes disminuir la cantidad", Snackbar.LENGTH_LONG)
                mySnackbar.show()
            }
            cantidadProducto.setText(producto.cantidad.toString())
        }

        checkBoxProductos.isChecked = producto.checked
        cantidadProducto.setText(producto.cantidad.toString())

        if (producto.checked) {
            btnPlus.setImageResource(R.drawable.ic_plus)
            btnPlus.isEnabled = true
            btnMinus.setImageResource(R.drawable.ic_minus)
            btnMinus.isEnabled = true
            cantidadProducto.isEnabled = true


            //this is the TextWatcher//
            if(cantidadProducto.isEnabled){
                cantidadProducto.addTextChangedListener(object : TextWatcher{
                    override fun afterTextChanged(s: Editable?) {
                    }

                    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                    }

                    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                        producto.cantidad = s.toString().trim().toInt()
                    }

                })
            }else{
                cantidadProducto.addTextChangedListener(null)
            }


        } else {
            btnPlus.setImageResource(R.drawable.ic_plus_disabled)
            btnPlus.isEnabled = false
            btnMinus.setImageResource(R.drawable.ic_minus_disabled)
            btnMinus.isEnabled = false
            cantidadProducto.isEnabled = false

            cantidadProducto.addTextChangedListener(null)

        }

        checkBoxProductos.setOnClickListener {

            producto.checked = checkBoxProductos.isChecked

            btnPlus.isEnabled = checkBoxProductos.isChecked
            btnMinus.isEnabled = checkBoxProductos.isChecked

            if (checkBoxProductos.isChecked) {
                btnPlus.setImageResource(R.drawable.ic_plus)
                btnPlus.isEnabled = true
                btnMinus.setImageResource(R.drawable.ic_minus)
                btnMinus.isEnabled = true
                cantidadProducto.isEnabled = true


            } else {
                btnPlus.setImageResource(R.drawable.ic_plus_disabled)
                btnPlus.isEnabled = false
                btnMinus.setImageResource(R.drawable.ic_minus_disabled)
                btnMinus.isEnabled = false
                cantidadProducto.setText("0")
                cantidadProducto.isEnabled = false

                producto.cantidad = 0

            }

        }


    }

}

试了很多方法还是不行。现在有一个 NullPointerException。关于如何解决它的任何想法?

更新:

这是 LogCat

Process: syscomestic.theapplabperu.com.syscosmetic, PID: 13508
java.lang.NullPointerException: Attempt to invoke interface method 'void android.text.TextWatcher.beforeTextChanged(java.lang.CharSequence, int, int, int)' on a null object reference
    at android.widget.TextView.sendBeforeTextChanged(TextView.java:8450)
    at android.widget.TextView.access$1300(TextView.java:253)
    at android.widget.TextView$ChangeWatcher.beforeTextChanged(TextView.java:10690)
    at android.text.SpannableStringBuilder.sendBeforeTextChanged(SpannableStringBuilder.java:1038)
    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:534)
    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:503)
    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:39)
    at android.text.method.NumberKeyListener.onKeyDown(NumberKeyListener.java:121)
    at android.widget.TextView.doKeyDown(TextView.java:6396)
    at android.widget.TextView.onKeyDown(TextView.java:6209)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2702)
    at android.view.View.dispatchKeyEvent(View.java:9328)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1679)
    at com.android.internal.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2445)
    at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1758)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2759)
    at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:534)
    at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:58)
    at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:316)
    at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:58)
    at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2353)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4659)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4615)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4111)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4164)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4130)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4276)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4138)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4333)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4111)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4164)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4130)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4138)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4111)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6593)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6567)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6510)
    at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3891)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:5728)
    at java.lang.reflect.Method.invoke(Native Method)

这是持有者的 XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layoutWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:baselineAligned="false"
android:minHeight="60dp"
android:orientation="horizontal">

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:gravity="center">

    <CheckBox
        android:id="@+id/cb_productos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="5"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_producto_seleccion"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="7dp"
        android:layout_marginBottom="5dp"
        android:text="@string/item_resultado_tv_producto"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_especialidad_producto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="7dp"
        android:text="@string/item_resultado_tv_especialidad" />

</LinearLayout>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"
    android:layout_weight="3"
    android:gravity="center"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center">

        <ImageView
            android:id="@+id/img_minus"
            android:layout_width="17dp"
            android:layout_height="17dp"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:clickable="false"
            android:focusable="true"
            android:src="@drawable/ic_minus_disabled" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center">

        <EditText
            android:id="@+id/tv_producto_cantidad"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:background="@drawable/shape_text_view"
            android:gravity="center"
            android:imeOptions="actionDone"
            android:inputType="number"
            android:paddingLeft="10dp"
            android:paddingTop="6dp"
            android:paddingRight="10dp"
            android:paddingBottom="6dp"
            android:text="0" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center">

        <ImageView
            android:id="@+id/img_plus"
            android:layout_width="17dp"
            android:layout_height="17dp"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:clickable="true"
            android:focusable="false"
            android:src="@drawable/ic_plus_disabled" />
    </LinearLayout>
</LinearLayout>

最佳答案

更改此部分:

    if(cantidadProducto.isEnabled){
        cantidadProducto.addTextChangedListener(object : TextWatcher{
            override fun afterTextChanged(s: Editable?) {
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                producto.cantidad = s.toString().trim().toInt()
            }

        })
    }else{
        cantidadProducto.addTextChangedListener(null)
    }

至:

cantidadProducto.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(s: Editable?) {
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        if(cantidadProducto.isEnabled)
            producto.cantidad = s.toString().trim().toInt()
    }

})

所以你不要将 textwatcher 设置为 null 看看会发生什么。

关于android - 如何在 RecyclerView Adapter 中使用 TextWatcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52821759/

相关文章:

android - RecyclerView 未填充,可能是一个愚蠢的适配器问题

android - CollapsingToolbarLayout 上的 Fling 滚动在折叠时停止

Android Jetpack 撰写从图像旁边开始并在图像下方继续的文本

android - 房间+ Dagger 2. NPE

android - 调用 Android API 在单元测试中总是返回 0

android - 图像淡入不保持最终的 alpha

android - 在网格布局中调整 imageViews 的大小

android - 检查回收站中位置的文本

使用 Rx-Java 时,旋转后 Android View 为空

java - ButterKnife onclick 不起作用