如何在片段上获取函数并在 Kotlin 上的另一个 class 中使用它

how to get function on fragment and use it in another class on Kotlin

试图从我的片段中获取 String 并想在我的 class 上使用它,但我不断收到错误:getSampleData on a null object reference 错误。你能帮帮我吗?

我的片段

class sampleFragment : Fragment() {
    val sample= ""
    ...
    some codes r here
    ...

    fun getSampleData(): String {

    search_edit_text.addTextChangedListener(object : TextWatcher{
        override fun afterTextChanged(s: Editable) {}
        override fun beforeTextChanged(s: CharSequence, start: Int,
                                       count: Int, after: Int) {
        }
        override fun onTextChanged(s: CharSequence, start: Int,
                                   before: Int, count: Int) {
            sample= "${s}"
        }
    })
    return sample

}

这个是我的另一个class

    class sampleAPIService()  {
    val getSample= sampleFragment()
    fun getSearchModel(): Single<search>{
    return api.getSearch(getSample.getSampleData())
    }

同样,当我 Log.e 到片段上的 getSampleData() 时,我可以正确获取用户输入,因此它不为空,但我无法将其传输到我的另一个 class

getSampleData()函数没有意义。每次调用它时,它都会向 EditText 添加另一个重复的冗余侦听器,然后 return 无论 EditText 的当前值是什么(但前提是之前调用过该函数并且 EditText 的内容自那时起发生了变化).如果您所做的只是用文本更新 属性 ,那么无论如何您都不需要侦听器。当前文本可以直接从editText.text.toString().

中获取

当您的另一个 class 通过调用其构造函数创建您的 Fragment 的新副本时,它现在正在使用一些孤立的、无用的 Fragment 实例,该实例尚未附加到 window 并且具有与实际显示在屏幕上的那个无关。

总的来说,您需要以不同的方式设计 classes,这样 classes 就不必来回调用彼此的函数。这是非常复杂的。例如,API 助手 class 不必知道任何特定的片段。这就是separation of concerns的编程原理,或者封装

API 助手 class 应该设计得更像这样,它根据与它正在做的事情直接相关的输入提供一些东西。 Fragment 与 API 需要知道什么来获取某些东西没有直接关系。在这种情况下,输入应该是一个字符串。例如:

class SampleAPIService()  {

    private val api = TODO()
    //...

    fun getSearch(searchText: String): Single<search>{
        return api.getSearch(searchText)
    }

}

片段应在 onViewCreated() 中设置其视图侦听器,因此只添加一次。据推测,在您的 Fragment 中的某处,您有一个启动搜索的按钮,因此您应该从那里调用您的 API。

class SampleFragment : Fragment() {
    val sample= ""
    private val sampleApiService = SampleApiService()
    // ...
    // some codes r here
    // ...

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // ...

        someSearchButton.setOnClickListener {
            val searchResultSingle = sampleApiService.getSearch(search_edit_text.text.toString())
            // do something with result
        }
    }

}

顺便说一下,按照惯例,所有 class 名称都应以大写字母开头,否则您的代码将难以阅读。