RecyclerView适配器中获取上下文实现Fragment跳转崩溃问题求助
问题解决:RecyclerView Adapter中安全获取FragmentManager并传递Modelo数据到Fragment
崩溃原因
直接将view.getContext()强转为AppCompatActivity会触发ClassCastException——View的Context不一定是Activity实例(可能是Application Context或其他上下文),强转失败就会导致应用崩溃。
解决方案一:安全获取Activity上下文
修改Adapter中点击事件的代码,先判断Context类型再执行跳转:
holder.RLAYOUT.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Context context = view.getContext(); // 先判断上下文是否为Activity实例 if (context instanceof AppCompatActivity) { AppCompatActivity activity = (AppCompatActivity) context; activity.getSupportFragmentManager().beginTransaction() .replace(R.id.frameLayout, new DescDenuncia( model.getEmpresa(), model.getArea(), model.getSetor(), model.getTipo(), model.getRisco(), model.getImg(), model.getData(), model.getPrazo(), model.getDesc(), model.getResolucao(), model.getID() )) .addToBackStack(null) .commit(); } } });
解决方案二:接口回调解耦(推荐)
这种方式让Adapter不直接依赖Activity,更符合模块化设计原则:
- 定义点击回调接口
public interface OnItemClickListener { void onItemClick(Modelo modelo); }
- 修改Adapter,添加接口实例并调整构造方法
public class Adapter extends FirestoreRecyclerAdapter<Modelo, Adapter.myviewholder> { private OnItemClickListener listener; public Adapter(@NonNull FirestoreRecyclerOptions<Modelo> options, OnItemClickListener listener) { super(options); this.listener = listener; } @Override protected void onBindViewHolder(@NonNull myviewholder holder, int position, @NonNull final Modelo model) { // 原有数据绑定代码不变 holder.IDText.setText(model.getID()); holder.tipoText.setText(model.getTipo()); Glide.with(holder.img1.getContext()).load(model.getImg()).into(holder.img1); // 点击事件交给回调处理 holder.RLAYOUT.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { listener.onItemClick(model); } }); } // 其余代码不变 }
- 在宿主Activity中实现接口,处理Fragment跳转
public class YourHostActivity extends AppCompatActivity implements OnItemClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); // 初始化Adapter时传入回调实例 FirestoreRecyclerOptions<Modelo> options = // 你的Firestore配置 Adapter adapter = new Adapter(options, this); // 为RecyclerView设置Adapter... } @Override public void onItemClick(Modelo modelo) { getSupportFragmentManager().beginTransaction() .replace(R.id.frameLayout, new DescDenuncia( modelo.getEmpresa(), modelo.getArea(), modelo.getSetor(), modelo.getTipo(), modelo.getRisco(), modelo.getImg(), modelo.getData(), modelo.getPrazo(), modelo.getDesc(), modelo.getResolucao(), modelo.getID() )) .addToBackStack(null) .commit(); } }
额外优化:规范Fragment参数传递
建议用setArguments()传递参数,避免Fragment重建时数据丢失:
修改DescDenuncia Fragment:
public class DescDenuncia extends Fragment { private static final String KEY_EMPRESA = "empresa"; // 定义其他参数的key... public static DescDenuncia newInstance(Modelo modelo) { DescDenuncia fragment = new DescDenuncia(); Bundle args = new Bundle(); args.putString(KEY_EMPRESA, modelo.getEmpresa()); args.putString("area", modelo.getArea()); args.putString("setor", modelo.getSetor()); args.putString("tipo", modelo.getTipo()); args.putString("risco", modelo.getRisco()); args.putString("img", modelo.getImg()); args.putString("data", modelo.getData()); args.putString("prazo", modelo.getPrazo()); args.putString("desc", modelo.getDesc()); args.putString("resolucao", modelo.getResolucao()); args.putString("ID", modelo.getID()); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { String empresa = getArguments().getString(KEY_EMPRESA); // 读取其他参数... } } }
跳转时替换为:
// 方案一中的写法 activity.getSupportFragmentManager().beginTransaction() .replace(R.id.frameLayout, DescDenuncia.newInstance(model)) .addToBackStack(null) .commit(); // 方案二中的写法 getSupportFragmentManager().beginTransaction() .replace(R.id.frameLayout, DescDenuncia.newInstance(modelo)) .addToBackStack(null) .commit();
内容的提问来源于stack exchange,提问作者Natan guimarães dos Santos
相关产品推荐
相关产品推荐

