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
相关产品推荐
相关产品推荐

