【问题标题】:Button possibly not initialized in Android Fragment按钮可能未在 Android 片段中初始化
【发布时间】:2021-04-04 03:13:37
【问题描述】:

我一直在关注有关在 android 应用中实现 crud 功能的教程。

按照指南,提交按钮应该向我的 Firebase RTB 添加一个字符,应用程序正在编译,但当我点击提交时没有发生任何事情,我之前所做的工作我总是初始化按钮,但是当我在这里尝试这样做时我不能使用findViewById(R.id.submit),因为findViewById 会引发未解决的引用错误,如果我不声明该部分,那么它会由于未初始化而按预期崩溃。在本教程中,我关注的按钮也未初始化,但代码按预期工作。

我相信该按钮没有注册被点击,但我不完全确定它为什么不起作用。

这是我的代码

class CreatePlayerFragment: Fragment() {

    private lateinit var viewModel: CharacterViewModel
    private lateinit var submit: Button

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?{

        viewModel = ViewModelProvider(this).get(CharacterViewModel::class.java)
        return inflater.inflate(R.layout.fragment_create_player, container, false)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        submit = clearFindViewById(R.id.submit)

    }


    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)



        viewModel.result.observe(viewLifecycleOwner, Observer {
           val message = if(it == null) {
                getString(R.string.character_added)
            } else {
                getString(R.string.character_failure, it.message)
           }
            Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
        })

        //listener for submission button
        submit.setOnClickListener {
            val name: String = editTextPlayerName.text.toString().trim()
            val race: String = editTextRace.text.toString().trim()
            val classType: String = editTextClass.text.toString().trim()
            if(TextUtils.isEmpty(name)) {

                input_layout_name.error = getString(R.string.field_required_error)
                return@setOnClickListener
            }

            val character = CharacterModel()
            character.name = name
            character.race = race
            character.classType = classType
            viewModel.addCharacter(character)

        }
    }
}

编辑

所以我在类中添加了 ankolistener 以查看按钮是否正在注册被点击并发现它是,我为第二个按钮创建了逻辑以清除片段中的文本字段,这按预期工作,所以我的问题是数据根本没有提交到我的 Firebase 实时数据库。 这是我的 CharacterViewModel 的代码。我正在使用 Android Studio 插件将 Firebase RTB 与此应用程序链接起来。单击提交按钮创建角色时,我没有收到任何错误。

class CharacterViewModel : ViewModel() {

private val _result = MutableLiveData<Exception?>()
val result: LiveData<Exception?>
    get() = _result

/*
    Add character to DB, save a character under the characters node in the DB with a
    unique key id.

 */
fun addCharacter(character: CharacterModel) {
    val dbCharacterModels = FirebaseDatabase.getInstance().getReference(NODE_CHARACTERS)
    character.id = dbCharacterModels.push().key
    dbCharacterModels.child(character.id!!).setValue(character).addOnCompleteListener {
        if(it.isSuccessful){
            _result.value = null
        } else {
            _result.value = it.exception
        }
    }
}

}

【问题讨论】:

  • 检查教程是否使用数据绑定。

标签: android firebase kotlin android-fragments android-activity


【解决方案1】:

findViewById 确实在 Fragment 中工作。但是,您不能只调用此方法。首先,您要等到创建视图。这可以在 onViewCreated 方法中完成。在此方法中,您可以使用此方法查找对象:getView().findViewById

【讨论】:

  • 嗨,我不确定我是否完全关注你,但我尝试了其他方法,所以我将 onActivityCreated 内的所有代码移到 onViewCreated 内,然后我还添加了这一行尝试初始化按钮submit = getView().findViewById(R.id.submit)的代码我收到此错误但是Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type View
  • 调用@Nullable 的方法时可能会出现此错误。为避免这种情况,您需要在对该对象执行任何进一步操作之前检查该对象是否为空。这是一个 Kotlin 问题,而不是 java。因此,一个简单的 if 检查应该可以解决您的问题。
【解决方案2】:

您应该始终在 onViewCreated() 中初始化视图。此生命周期方法确保片段和活动已在屏幕上呈现,并且您可以访问片段内的所有视图。 onCreate() 在屏幕渲染之前被调用,因此按钮没有被初始化。

【讨论】:

  • 好的,所以要解决我的问题,我应该声明一个 ònViewCreated 函数并将代码从 ònActivityCreated 函数移到该函数中吗?
  • 您当前正在 oncreate 中初始化按钮,将其放在 onViewCreated 中。 onActivityCreated 也可以正常工作。
猜你喜欢
  • 2020-12-26
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 2021-04-13
  • 2022-08-23
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
相关资源
最近更新 更多