RecyclerView到Activity共享元素过渡报错:匿名OnClickListener无法转为Activity
解决RecyclerView卡片图片共享元素过渡的类型转换错误
Hey there!我看你在给带图片的CardView做RecyclerView,想实现点击图片跳转到新Activity的共享元素过渡时,碰到了这个类型转换错误,这个问题其实挺常见的,咱们来一步步搞定它~
错误原因解析
你看到的报错:
Error:(64, 88) error: incompatible types:
cannot be converted to Activity
本质是你在创建共享元素过渡的ActivityOptions时,传错了Context实例——因为你是在OnClickListener的匿名内部类里写的跳转代码,这里的this指向的是这个点击监听器对象,而不是你的Activity实例,所以系统会报类型不兼容的错误。
针对性解决方案
根据你的Adapter写法不同,有两种常见的解决方式:
情况1:Adapter是Activity的内部类
这种情况下,直接用你的Activity类名+.this来代替监听器里的this就行,比如你的Activity叫MainActivity:
cardViewImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 1. 创建跳转Intent Intent intent = new Intent(MainActivity.this, TargetActivity.class); // 2. 创建共享元素过渡的Options,这里要用Activity的实例 ActivityOptions transitionOptions = ActivityOptions.makeSceneTransitionAnimation( MainActivity.this, // 重点:这里用Activity的this,不是监听器的this v, // 要共享的图片View ViewCompat.getTransitionName(v) // 记得给图片View设置transitionName属性 ); // 3. 启动Activity并传入过渡参数 startActivity(intent, transitionOptions.toBundle()); } });
情况2:Adapter是独立的Java类
如果你的Adapter是单独的类,那需要在Adapter的构造方法里传入Activity的引用,之后在点击事件里用这个引用:
// 首先是Adapter的构造方法 public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> { private Activity mHostActivity; private List<CardData> mCardDataList; // 构造方法里传入Activity实例 public CardAdapter(Activity hostActivity, List<CardData> cardDataList) { mHostActivity = hostActivity; mCardDataList = cardDataList; } // 在绑定ViewHolder时设置点击事件 @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.cardImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(mHostActivity, TargetActivity.class); ActivityOptions transitionOptions = ActivityOptions.makeSceneTransitionAnimation( mHostActivity, // 用传入的Activity实例 v, ViewCompat.getTransitionName(v) ); mHostActivity.startActivity(intent, transitionOptions.toBundle()); } }); } // ViewHolder和其他方法省略... }
额外的必做配置
要让共享元素过渡真正生效,还得做好这两步:
- 在XML里给源图片View和目标Activity里的图片View设置相同的
transitionName属性,比如:<!-- 源RecyclerView里的图片View --> <ImageView android:id="@+id/card_image" android:transitionName="shared_card_image" <!-- 其他属性省略 --> /> <!-- 目标Activity里的图片View --> <ImageView android:id="@+id/detail_image" android:transitionName="shared_card_image" <!-- 其他属性省略 --> /> - 在你的App主题里启用窗口过渡动画,在
styles.xml里添加:<item name="android:windowContentTransitions">true</item>
如果是用AndroidX的话,建议用ActivityOptionsCompat来更好地兼容低版本系统哦~
内容的提问来源于stack exchange,提问作者notnavindu
相关产品推荐
相关产品推荐

