【问题标题】:Getting NullPointerException when trying to display the data of passed object from one fragment to another尝试将传递的对象的数据从一个片段显示到另一个片段时出现 NullPointerException
【发布时间】:2021-07-20 04:38:01
【问题描述】:

这是我在发件人片段上的代码

 override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_list_card,container,false)
        rcvAdapter = CardAdapter(cardList,this)
        view.cardRecyclerView.layoutManager = LinearLayoutManager(container?.context,LinearLayoutManager.VERTICAL,false)
        view.cardRecyclerView.adapter = rcvAdapter
        return view
    }
    override fun onClick(card: Card) {
        val cardBundle  = Bundle()
        cardBundle.putSerializable("Card",card)
        val infoFrag = CardInfoFrag()
        infoFrag.arguments = cardBundle
        val transaction = activity?.supportFragmentManager?.beginTransaction()
        transaction?.replace(R.id.fragmentContainer,infoFrag)
        transaction?.commit()
    }

这是接收器上的代码

class CardInfoFrag : Fragment() {
    private val card : Card? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val bundle = Bundle(arguments)
        val card : Card = bundle.getSerializable("Card") as Card
        Log.d("CARDINFO: ",card.name+" "+ card.cardDate+" "+card.cardNum)
    }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        cardNameInfo.text = card?.name
        cardExDateInfo.text = card?.cardDate
        cardNumInfo.text = card?.cardNum
        return inflater.inflate(R.layout.fragment_card_info,container,false)
    }
}

cardList 被声明为ArrayList<Card>

Card 对象

class Card (val cardNum : String, val cardDate : String, val name : String) :Serializable{

}

当我尝试使用来自传递的对象的数据创建一个新片段时,logcat 说我的cardNameInfo.text 不能为空,而 log 命令清楚地表明我收到了对象及其数据。我无法找出可能导致问题的原因

感谢任何提示

【问题讨论】:

    标签: android kotlin android-fragments


    【解决方案1】:

    顾名思义,onCreateView 在片段视图创建之前被调用;因此,在onCreateView 中,您需要显式使用它将返回的视图来访问任何底层视图。

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_card_info,container,false)
        cardNameInfo = view.findViewById<TextView>(R.id.foo1)
        cardExDateInfo= view.findViewById<TextView>(R.id.foo2)
        cardNumInfo= view.findViewById<TextView>(R.id.foo3)
    
        cardNameInfo.text = card?.name
        cardExDateInfo.text = card?.cardDate
        cardNumInfo.text = card?.cardNum
        return view
    }
    

    foo ids更改为片段布局中对应的ids

    【讨论】:

    • NVM 我之前的评论,我开始了。只是一个简单的问题,通常我可以通过 textFieldId.text = .... 将文本设置为文本字段,但在这种情况下,我必须声明一个新的 val,像上面所做的那样将其转换为 texField 以使其工作。请您详细说明这部分吗?
    • 可能您使用的是合成视图绑定...它允许您访问视图而无需调用 findViewById。但它现在已被弃用
    • 您已经将它们定义为片段/活动类字段并在另一个上下文中使用 findViewById 的时间比您调用 .text 属性时更早。所以它已经与这个问题中的情况相同
    【解决方案2】:

    尝试一次,当您获得Bundle 时,arguments 已经是Bundle 对象。也许如果你做这样的事情它可能会起作用:(我的答案基于this 答案:))

    class CardInfoFrag : Fragment() {
    
        ...
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val bundle: Bundle? = arguments
    
            bundle?.let{
    
              val card : Card = it.getSerializable("Card") as Card
              Log.d("CARDINFO: ",card.name+" "+ card.cardDate+" "+card.cardNum) 
            }
            
        }
    
        ...
    }
    

    【讨论】:

    • 我试过了,但问题仍然存在,谢谢你的提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多