RecyclerView中输入EditText时应用崩溃,求问题原因及解决办法
我想在RecyclerView的每一行中,对相邻EditText的数值进行累加计算,并将累加结果显示在该行的TextView中。应用启动时一切正常,但在任意EditText中输入内容时,应用会崩溃关闭。请问为何输入EditText时应用会崩溃?
MainActivity代码:
package com.example.recyclerview; import android.os.Bundle; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { ArrayList<Model> models = new ArrayList<>(); Adapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); setDataItems(); RecyclerView recyclerView = findViewById(R.id.rv); Adapter adapter = new Adapter(models,this); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemViewCacheSize(100); }public void recalculateTotals(){ double currentTotal = 0; for(int i=0;i<models.size();i++){ currentTotal += Double.parseDouble(models.get(i).getValue()); models.get(i).setRunningTotal(String.valueOf(currentTotal)); }adapter.notifyDataSetChanged(); } private void setDataItems(){ String[] edittexts = getResources().getStringArray(R.array.edittexts); String[] textviews = getResources().getStringArray(R.array.textviews); for(int i =0; i < edittexts.length; i++){ models.add(new Model(edittexts[i],textviews[i])); } } }
Adapter类代码:
package com.example.recyclerview; import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextSwitcher; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import org.w3c.dom.Text; import java.util.ArrayList; import java.util.List; public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolger> { ArrayList<Model> models = new ArrayList<>(); Context context; MainActivity activity; public Adapter(MainActivity activity) { this.activity = activity; } public Adapter(ArrayList<Model> models, Context context) { this.models = models; this.context = context; } @NonNull @Override public Adapter.MyViewHolger onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.row, parent, false); return new MyViewHolger(view); } @Override public void onBindViewHolder(@NonNull Adapter.MyViewHolger holder, int position) { Model currentItem = models.get(position); if(holder.et.getTag()instanceof TextWatcher){ holder.et.removeTextChangedListener((TextWatcher) holder.et.getTag()); } holder.et.setText(currentItem.getValue()); holder.tv.setText(currentItem.getRunningTotal()); MyTextWatcher watcher = new MyTextWatcher(holder.et,position); holder.et.addTextChangedListener(watcher); holder.et.setTag(watcher); } @Override public int getItemCount() { return models.size(); } public static class MyViewHolger extends RecyclerView.ViewHolder { TextView tv; EditText et; public MyViewHolger(@NonNull View itemView) { super(itemView); tv = itemView.findViewById(R.id.tv); et = itemView.findViewById(R.id.et); } } private class MyTextWatcher implements TextWatcher{ EditText et; int position; public MyTextWatcher(EditText et, int position) { this.et = et; this.position = position; } @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { try{ double value = Double.parseDouble((s.toString())); models.get(position).setValue(String.valueOf(value)); }catch (NumberFormatException e){ models.get(position).setValue(String.valueOf(0)); }activity.recalculateTotals(); } } }
崩溃原因分析及修复方案
核心崩溃原因:空指针异常(NullPointerException)
Adapter中的
activity变量未初始化
你在MainActivity中创建Adapter时调用的是new Adapter(models,this),但该构造函数仅给models和context赋值,未初始化activity变量。当EditText输入内容触发onTextChanged时,调用activity.recalculateTotals()会因activity为null抛出空指针异常,直接导致应用崩溃。MainActivity中的成员变量
adapter未正确赋值
在MainActivity的onCreate方法中,你重新定义了局部变量Adapter adapter = new Adapter(models,this),覆盖了成员变量adapter,导致成员变量始终为null。当recalculateTotals()调用adapter.notifyDataSetChanged()时,同样会触发空指针异常。
具体修复步骤:
1. 修改Adapter构造函数,初始化activity
合并或修改Adapter的构造函数,确保创建时能同时传入models、context和activity:
public Adapter(ArrayList<Model> models, Context context, MainActivity activity) { this.models = models; this.context = context; this.activity = activity; }
2. 修复MainActivity中adapter的赋值问题
在onCreate中直接给成员变量adapter赋值,避免定义局部变量覆盖:
// 去掉局部变量定义,直接赋值给成员变量 adapter = new Adapter(models,this,this); recyclerView.setAdapter(adapter);
3. 优化EditText输入处理(可选)
提前判断空输入,避免不必要的异常捕获:
@Override public void onTextChanged(CharSequence s, int start, int before, int count) { String input = s.toString().trim(); if(TextUtils.isEmpty(input)){ models.get(position).setValue("0"); }else{ try{ double value = Double.parseDouble(input); models.get(position).setValue(String.valueOf(value)); }catch (NumberFormatException e){ models.get(position).setValue("0"); } } activity.recalculateTotals(); }
经过以上修复,输入EditText时应用不会再崩溃,累加计算功能也能正常运行。
内容的提问来源于stack exchange,提问作者kaismaqbool hakim

