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

Kotlin开发类Tinder应用时Fragment中添加CardStackView出现空指针异常求助

解决CardStackView空指针异常(Attempt to invoke virtual method...)

嘿,我看到你在开发类Tinder应用时遇到了空指针问题,这个错误其实很常见,咱们一步步来解决它。

问题根源

你遇到的NullPointerException是因为在HomePageFragment的onCreateView方法里,直接使用了kotlin synthetic提供的stack_view引用,但这个引用此时还没有被初始化。因为你是手动inflate了布局文件到变量v中,而synthetic的view绑定是在fragment的root view被设置之后才完成的——也就是你return v之后。所以在return之前调用stack_view.layoutManager时,stack_view还是null,自然就崩溃了。

另外,你的HomeUserAdapter还有一个潜在的崩溃点:homeUserList初始是null,但getItemCount()直接返回homeUserList!!.size,这肯定会触发空指针;而且onBindViewHolder里每次都调用generateUser()生成新列表,会导致数据不一致。

解决方案

1. 修复Fragment中的CardStackView引用问题

把直接使用synthetic的stack_view改成从inflate的view中获取实例:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val v = inflater.inflate(R.layout.fragment_home_page, container, false)
    layoutManager = CardStackLayoutManager(context,this).apply {
        setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
        setOverlayInterpolator(LinearInterpolator())
    }
    // 从inflate的view中获取CardStackView实例
    val cardStackView = v.findViewById<com.yuyakaido.android.cardstackview.CardStackView>(R.id.stack_view)
    cardStackView.layoutManager = layoutManager
    cardStackView.adapter = adapter
    cardStackView.itemAnimator.apply {
        if(this is DefaultItemAnimator){
            supportsChangeAnimations = false
        }
    }
    return v
}

2. 修复Adapter的数据源问题

修改HomeUserAdapter,初始化数据源并正确使用它:

class HomeUserAdapter:RecyclerView.Adapter<HomeUserAdapter.HomeUserViewHolder>() {
    // 初始化列表,避免null值
    private var homeUserList: List<HomeUserItem> = generateUser()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeUserViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.user_card,parent,false)
        return HomeUserViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: HomeUserViewHolder, position: Int) {
        // 直接使用已初始化的列表,不要每次生成新数据
        val currentItem = homeUserList[position]
        Picasso.get().load(currentItem.user_img).into(holder.user_img)
        holder.user_name.text = currentItem.user_name
        holder.medal_num.text = currentItem.medal_num
        holder.id_num.text = currentItem.userId
        holder.user_intro.text = currentItem.user_intro
        holder.user_give_num.text = currentItem.user_give_num
        holder.user_receive_num.text = currentItem.user_receive_num
    }

    private fun generateUser(): ArrayList<HomeUserItem> {
        val list = ArrayList<HomeUserItem>()
        list.add(
            HomeUserItem(
                "https://i.pinimg.com/236x/8c/64/03/8c6403cc892231f15a6845e00d7433a9.jpg",
                "Maria",
                "200",
                "510uu",
                "I am from USA ,I am an engineer ,I hope to make the world a better place",
                "500",
                "100")
        )
        return list
    }

    override fun getItemCount(): Int {
        return homeUserList.size
    }

    class HomeUserViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
        val user_img : ImageView = itemView.user_img
        val user_name : TextView = itemView.user_name
        val medal_num : TextView = itemView.medal_num
        val id_num : TextView = itemView.id_num
        val user_intro : TextView = itemView.user_intro
        val user_give_num : TextView = itemView.user_give_num
        val user_receive_num : TextView = itemView.user_receive_num
    }
}

改动说明

  • Fragment部分:通过v.findViewById直接获取刚inflate出来的CardStackView,确保引用有效,避开了kotlin synthetic的初始化时机问题。
  • Adapter部分:
    • 初始化homeUserList为generateUser()的返回值,避免null导致的崩溃;
    • onBindViewHolder直接使用已有的列表,不再每次生成新数据,保证数据一致性。

这样修改后,你的空指针问题应该就能解决了,Adapter也不会再有潜在的崩溃风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:27:37