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

RecyclerView点击跳转Activity失败,如何正确获取Context?

解决RecyclerView点击无法打开新Activity的问题

嘿,我来帮你搞定这个问题!咱们先拆解下你遇到的报错和Context的疑问:

问题根源:Context使用错误

你现在Toast能正常显示,但启动Activity失败,核心原因是用了getApplicationContext()或者v.getContext()启动Activity。getApplicationContext()是全局的Application上下文,它不属于任何一个Activity实例,而启动Activity需要依附于一个Activity的任务栈,用Application Context启动的话,系统找不到对应的任务栈,就会抛出你看到的handleWindowVisibility: no activity for token警告。

而Toast可以正常工作,是因为Toast不需要绑定到特定的Activity任务栈,所以用Application Context也没问题。

快速修复当前代码

你只需要把启动Intent的Context换成当前Activity的实例就行,比如你的Activity叫MainActivity,就这么改:

adapter.setOnItemClickListener(new AdapterView.OnClickListener() {
    @Override
    public void onClick(View v) {
        int pos = recyclerViewFestivales.getChildAdapterPosition(v);
        Festival festivalSeleccionado = listaFestivales.get(pos);
        String nombreFestival = listaFestivales.get(pos).getNombre();
        Toast.makeText(MainActivity.this, "seleccion: " + nombreFestival, Toast.LENGTH_SHORT).show();
        // 把v.getContext()换成当前Activity的实例
        Intent intent = new Intent(MainActivity.this, FestivalActivity.class);
        intent.putExtra("nombreFestival", nombreFestival);
        startActivity(intent);
    }
});

RecyclerView中获取正确Context的规范方式

其实RecyclerView本身没有像ListView那样内置setOnItemClickListener方法,更规范的做法是在Adapter的ViewHolder中设置点击监听,同时在Adapter构造时传入Activity的Context,这样能确保Context的正确性:

第一步:自定义Adapter并添加点击监听接口

public class FestivalAdapter extends RecyclerView.Adapter<FestivalAdapter.FestivalViewHolder> {
    private List<Festival> mFestivalList;
    private Context mContext;
    private OnItemClickListener mListener;

    // 构造方法传入Activity Context、数据列表和点击回调
    public FestivalAdapter(Context context, List<Festival> festivalList, OnItemClickListener listener) {
        mContext = context;
        mFestivalList = festivalList;
        mListener = listener;
    }

    // 定义点击回调接口
    public interface OnItemClickListener {
        void onItemClick(Festival selectedFestival);
    }

    @NonNull
    @Override
    public FestivalViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 用传入的Context加载布局,确保是Activity的Context
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_festival_layout, parent, false);
        return new FestivalViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull FestivalViewHolder holder, int position) {
        Festival currentFestival = mFestivalList.get(position);
        // 这里绑定你的数据,比如设置节日名称
        // holder.tvNombre.setText(currentFestival.getNombre());
        
        // 给itemView设置点击监听
        holder.itemView.setOnClickListener(v -> {
            mListener.onItemClick(currentFestival);
        });
    }

    @Override
    public int getItemCount() {
        return mFestivalList.size();
    }

    // ViewHolder类
    static class FestivalViewHolder extends RecyclerView.ViewHolder {
        // 声明你的控件,比如TextView tvNombre;
        public FestivalViewHolder(@NonNull View itemView) {
            super(itemView);
            // 初始化控件:tvNombre = itemView.findViewById(R.id.tv_nombre);
        }
    }
}

第二步:在Activity中初始化Adapter并处理点击

// 在你的Activity的onCreate方法里
FestivalAdapter adapter = new FestivalAdapter(
        this, // 直接传入当前Activity的Context
        listaFestivales,
        selectedFestival -> {
            String nombreFestival = selectedFestival.getNombre();
            Toast.makeText(this, "seleccion: " + nombreFestival, Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(this, FestivalActivity.class);
            intent.putExtra("nombreFestival", nombreFestival);
            startActivity(intent);
        }
);
recyclerViewFestivales.setAdapter(adapter);

这种方式不仅能确保Context的正确性,还让点击逻辑和Adapter解耦,更符合Android的设计规范。

内容的提问来源于stack exchange,提问作者Iván Martínez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 06:59:09