You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Adapter中点击RLAYOUT触发Fragment跳转时AppCompatActivity致应用崩溃

RecyclerView点击跳转Fragment崩溃排查与解决

问题描述

在FirestoreRecyclerAdapter中给RelativeLayout设置点击事件,点击时从Home Fragment切换到Perfil Fragment(注:用户描述中提到的是DescDenuncia Fragment,代码中实际为Perfil),传递Model中的多个参数,但每次点击都会导致应用崩溃。已确认model.getEmpresa等参数本身无问题,怀疑Fragment事务逻辑存在错误。

崩溃代码

package com.example.safe;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;

//Vinculando o reclycler view ao firestore
public class Adapter extends FirestoreRecyclerAdapter<Modelo, Adapter.myviewholder> {


    public Adapter(@NonNull FirestoreRecyclerOptions<Modelo> options) {
        super(options);
    }

    //Sobrescrevendo o método
    @Override
    protected void onBindViewHolder(@NonNull myviewholder holder, int position, @NonNull final Modelo model) {
        //Associando os itens do atalho ocorrências
        holder.IDText.setText(model.getID());
        holder.tipoText.setText(model.getTipo());
        Glide.with(holder.img1.getContext()).load(model.getImg()).into(holder.img1);

        ///////////////////////////////////////THE PROBLEM IS HERE///////////////////////////////////////////
        holder.RLAYOUT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AppCompatActivity activity = (AppCompatActivity) view.getContext();
                activity.getSupportFragmentManager().beginTransaction().replace(R.id.frameLayout, new Perfil(
                        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();

            }
        });
        //////////////////////////////////////////////////////////////////////////////////////////////////////
    }


    @NonNull
    @Override
    public myviewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.modelo_atalho_ocorrencias, parent, false);
        return new myviewholder(view);

    }

    //Coneção do reclycler view com essa classe
    public class myviewholder extends RecyclerView.ViewHolder {

        //Variáveis do modelo atalho
        TextView tipoText, IDText;
        RelativeLayout RLAYOUT;
        ImageView img1;

        //Associando os objetos ao modelo atalho
        public myviewholder(@NonNull View itemView) {
            super(itemView);


            tipoText = itemView.findViewById(R.id.txtTipo);
            img1 = itemView.findViewById(R.id.imageView);
            IDText = itemView.findViewById(R.id.txtModeloID);
            RLAYOUT = itemView.findViewById(R.id.RLlayout);
        }
    }

}

解决方案

1. 修复上下文强转问题

直接将view.getContext()强转为AppCompatActivity存在风险,如果当前上下文是Fragment(而非Activity),会抛出ClassCastException。添加类型判断确保安全:

holder.RLAYOUT.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Context context = view.getContext();
        if (!(context instanceof AppCompatActivity)) {
            Toast.makeText(context, "跳转失败:无效上下文", Toast.LENGTH_SHORT).show();
            return;
        }
        AppCompatActivity activity = (AppCompatActivity) context;
        // 后续事务代码
    }
});

2. 使用Bundle传递Fragment参数(推荐)

Android不推荐通过构造函数给Fragment传参,Fragment重建时会丢失参数并可能引发异常。改用静态newInstance方法+Bundle传递:

第一步:修改Perfil Fragment

public class Perfil extends Fragment {
    // 静态方法创建Fragment实例并传递参数
    public static Perfil newInstance(String empresa, String area, String setor, String tipo, String risco, String img, String data, String prazo, String desc, String resolucao, String id) {
        Perfil fragment = new Perfil();
        Bundle args = new Bundle();
        args.putString("empresa", empresa);
        args.putString("area", area);
        args.putString("setor", setor);
        args.putString("tipo", tipo);
        args.putString("risco", risco);
        args.putString("img", img);
        args.putString("data", data);
        args.putString("prazo", prazo);
        args.putString("desc", desc);
        args.putString("resolucao", resolucao);
        args.putString("id", id);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 从Bundle中取出参数
        if (getArguments() != null) {
            String empresa = getArguments().getString("empresa");
            String area = getArguments().getString("area");
            // 其他参数同理取出
        }
    }

    // 其他Fragment逻辑...
}

第二步:修改Adapter中的跳转代码

holder.RLAYOUT.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Context context = view.getContext();
        if (!(context instanceof AppCompatActivity)) {
            Toast.makeText(context, "跳转失败:无效上下文", Toast.LENGTH_SHORT).show();
            return;
        }
        AppCompatActivity activity = (AppCompatActivity) context;
        // 使用newInstance创建Fragment
        Perfil perfilFragment = Perfil.newInstance(
                model.getEmpresa(),
                model.getArea(),
                model.getSetor(),
                model.getTipo(),
                model.getRisco(),
                model.getImg(),
                model.getData(),
                model.getPrazo(),
                model.getDesc(),
                model.getResolucao(),
                model.getID()
        );
        // 执行Fragment事务
        activity.getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.frameLayout, perfilFragment)
                .addToBackStack(null)
                .commit();
    }
});

3. 验证容器ID正确性

确认R.id.frameLayout确实存在于当前Activity的布局文件中,且是专门用于承载Fragment的容器(比如FrameLayout)。ID错误会导致replace操作失败崩溃。

4. 查看崩溃日志定位根源

打开Logcat,找到崩溃时的异常信息:

  • 如果是ClassCastException:对应上下文强转问题;
  • 如果是IllegalStateException:可能是Activity处于不可操作状态(比如正在销毁)时执行事务;
  • 如果是NullPointerException:检查Bundle参数读取或Fragment容器是否为空。

内容的提问来源于stack exchange,提问作者Rodrigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:45:35