活动与片段通信:当我尝试从活动中更新片段中的文本视图时,出现空指针异常

问题描述


我有一个活动和片段。我想在其中将值从活动发送到片段。从活动中,我会调用片段中的方法来更新Text视图。但是无法更新UI却得到了空指针异常。

首先,在案例2中,我检查了此链接link:我遵循了这段代码,该代码能够将活动中的值发送给片段,使其工作正常。但是当我在fragment.sendData("Some Text") 单击按钮并在按钮外部粘贴,单击该按钮会得到空指针异常。

fragment.sendData("Some Text")在按钮单击内部如何工作而不在按钮单击外部工作?

我还尝试了相同的概念,添加代码错误行。那么任何人都可以帮助我为什么不更新片段>

中的文本视图吗?

错误

com.example.fragments E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fragments,PID: 3104
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragments/com.example.fragments.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.fragments.FragmentTwo.displayUI(FragmentTwo.kt:30)
        at com.example.fragments.MainActivity.loadDetailsView(MainActivity.kt:38)
        at com.example.fragments.MainActivity.onCreate(MainActivity.kt:32)
        at android.app.Activity.performCreate(Activity.java:7825)
        at android.app.Activity.performCreate(Activity.java:7814)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
        at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3245)

MainActivity

import android.os.Bundle
import android.util.LogAv
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    lateinit var detailsView:FragmentTwo
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        loadDetailsView()
    }
    private fun loadDetailsView() {
        detailsView= FragmentTwo()
        supportFragmentManager.beginTransaction().replace(R.id.frameLayout,detailsView).commit()
        detailsView.displayUI("HELLO")
    }  
}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:layout_width="match_parent" android:id="@+id/frameLayout"
        android:layout_height="match_parent"></FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

FragmentTwo

package com.example.fragments

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.row_names.*

class FragmentTwo:Fragment() {
  

        fun displayUI(string: String)
        {
            txtName.setText(string)
        }
  
    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        val view:View
        view=inflater.inflate(R.layout.fragment_two,container,false)
            return view
    }
}

fragment_two.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="415dp"
        android:layout_height="200dp"
        android:text="HAI"
        android:id="@+id/txtName"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.201"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.09" />

</androidx.constraintlayout.widget.ConstraintLayout>

解决方法

Var txtName为空。 您是否在fragment_two.xml中设置其ID?

,

不能在事务替换方法之后立即访问片段方法。 您可以使用AndroidX Fragment 1.3.0-beta01

中的the new api在它们之间传递数据

关于文字更改

Activity.supportFragmentManager.setFragmentResult("some_key",bundle_of_data)

并开始从片段onCreate收听它

Fragment.setFragmentResultListener()