Android:为什么 Transformation.map 运行 尝试分配给变量?

Android: Why doesn't this Transformation.map run when trying to assign to a variable?

我正在尝试在我的项目中使用 Firebase API,但是视图模型中的变量 authenticationStateTransformations.map 没有 运行。我一直在关注 Google 的教程 here(link 转到该项目的 ViewModel)。

我希望稍后能够将 Transformations.map 代码添加到 FirebaseUserLiveData 文件中,但我似乎无法弄清楚为什么它不能 运行.

FirebaseUserLiveData

class FirebaseUserLiveData: LiveData<FirebaseUser?>() {

    private val firebaseAuth = FirebaseAuth.getInstance()
    private val authStateListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
        value = firebaseAuth.currentUser
    }


    override fun onActive() {
        firebaseAuth.addAuthStateListener { authStateListener }
    }

    override fun onInactive() {
        firebaseAuth.removeAuthStateListener(authStateListener)
    }
}

SearchMovieFragmentViewModel

class SearchMovieFragmentViewModel : ViewModel() {

    enum class AuthenticationState {
        AUTHENTICATED, UNAUTHENTICATED, INVALID_AUTHENTICATION
    }

    var authenticationState = Transformations.map(FirebaseUserLiveData()) { user ->
        Log.d("TEST", "in the state function")
        if (user != null) {
            AuthenticationState.AUTHENTICATED
        } else {
            AuthenticationState.UNAUTHENTICATED
        }
    }

SearchMovieFragment

class SearchMovieFragment : Fragment(), MovieSearchItemViewModel {

    companion object {
        fun newInstance() = SearchMovieFragment()
    }

    private lateinit var searchMovieFragmentViewModel: SearchMovieFragmentViewModel
    private lateinit var binding: SearchMovieFragmentBinding
    private lateinit var movieRecyclerView: RecyclerView

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

        binding = DataBindingUtil.inflate(inflater, R.layout.search_movie_fragment, container, false)
        searchMovieFragmentViewModel = ViewModelProvider(this).get(SearchMovieFragmentViewModel::class.java)
        binding.lifecycleOwner = this
        binding.viewmodel = searchMovieFragmentViewModel

        binding.signOutButton.setOnClickListener {
            AuthUI.getInstance().signOut(requireContext())
        }

        searchMovieFragmentViewModel.authenticationState.observe(viewLifecycleOwner, Observer { state ->
            when (state) {
                AUTHENTICATED -> searchMovieFragmentViewModel.signedIn = View.VISIBLE
                UNAUTHENTICATED -> searchMovieFragmentViewModel.signedIn = View.GONE
            }
        })
        return binding.root
    }
}

那是因为一旦您开始像 Transformations.map(FirebaseUserLiveData()) { user -> 一样观察它,您就没有保留 FirebaseUserLiveData() 的引用。 您必须具有要映射或传输到另一种形式的 Livedata.

Livedata 的引用

它就像一个观察链中的所有LiveData都应该被观察或者应该有某种观察者在下面行,主要use-case是将某种形式的实时数据转换成你想要的东西,例如:

class YourRepository{  // your repo, that connected to a network that keeps up to date some data
  val IntegerResource: LiveData<Int> = SomeRetrofitInstance.fetchFromNetwork() //updating some resource from network
}

class YourViewModel{
  val repository = YourRepository()

 //this will start observe the repository livedata and map it to string resource
  var StringResource: Livedata<String> = Transformations.map( repository.IntegerResource ) { integerValue ->
    integerValue.toString()
}

我的观点是,您必须让正在转换的 LiveData 保持活动状态。希望有所帮助。

应该是.addAuthStateListener(authStateListener)而不是{ authStateListener }