java .lang.IllegalStateException: pb не должен быть нулевым в TopHeadlinesFragment? - PullRequest
1 голос
/ 18 марта 2020

Я занимаюсь разработкой новостного приложения и внедрил liveata с индикатором выполнения, но в моем коде я получаю следующее исключение

java.lang.IllegalStateException: pb must not be null
 at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$initViewModel$2.onChanged(TopHeadlinesFragment.kt:60)
 at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$initViewModel$2.onChanged(TopHeadlinesFragment.kt:22)
 at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
 at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:144)
 at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:442)
 at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:394)
 at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
 at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
 at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
 at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
 at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
 at androidx.fragment.app.Fragment.performStart(Fragment.java:2637)
 at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
 at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
 at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
 at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
 at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
 at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
 at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
 at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
 at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
 at android.os.Handler.handleCallback(Handler.java:873)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:201)
 at android.app.ActivityThread.main(ActivityThread.java:6820)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)

ниже моего класса TopHeadlinesFragment.kt

class TopHeadlinesFragment : Fragment() {

    private  var binding: FragmentTopHeadlinesBinding? = null
    private val viewModel by viewModel<MainViewModel>()
    private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
    // private   val newsRepository: NewsRepository by inject()
    private  var article:List<Article>? = null


    //3
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(
            R.layout.fragment_top_headlines
            , container, false
        )
        val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
        val pb = view.findViewById(R.id.pb) as ProgressBar
        topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context, article)
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = topHeadlinesAdapter
        initViewModel()

        binding?.lifecycleOwner
        return binding?.root


    }

    private fun initViewModel() {
        viewModel?.sportList?.observe(this, Observer { newList ->
            topHeadlinesAdapter.updateData(newList)
        })

        viewModel?.showLoading?.observe(this, Observer { showLoading ->
            pb.visibility = if (showLoading) View.VISIBLE else View.GONE
        })

        viewModel?.showError?.observe(this, Observer { showError ->
            (showError)
        })

        viewModel?.loadNews()
    }
}

ниже frag_top_headlines. xml

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Я выполнил все предложения, связанные с переполнением стека, но это не решило мою проблему. что я хочу знать, где именно я делаю ошибку, что я должен сделать, чтобы избежать исключения.

то, что я пытался

1. Неверный перезапуск кэша 2. Очистить и восстановить проект 3. Я проверил, что индикатор выполнения уже инициализирован. 4. Я также попробовал эту ссылку на стек-поток Android: индикатор прогресса не должен быть нулевым, используя Kotlin 5. Я попытался индикатор выполнения, объявленный как глобальная переменная, он не работал

ниже мой MainViewModel.kt

@Suppress("UNCHECKED_CAST")
class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    val showLoading = MutableLiveData<Boolean>()
    val sportList = MutableLiveData<List<Article>>()
    val showError = SingleLiveEvent<String>()

    fun loadNews() {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                newsRepository?.getNewsList()
            }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {

                is UseCaseResult.Success<*> -> {
                    sportList.value = result.data as List<Article>
                }
                is Error -> showError.value = result.message
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}

Я попробовал ниже предоставленные ответы, но это не решило проблему

Ответы [ 2 ]

0 голосов
/ 18 марта 2020
    viewModel?.sportList?.observe(this, Observer { newList ->
        topHeadlinesAdapter.updateData(newList)
    })

    viewModel?.showLoading?.observe(this, Observer { showLoading ->
        pb.visibility = if (showLoading) View.VISIBLE else View.GONE
    })

    viewModel?.showError?.observe(this, Observer { showError ->
        (showError)
    })

Должно быть

    viewModel.sportList.observe(viewLifecycleOwner) { newList ->
        topHeadlinesAdapter.updateData(newList)
    }

    viewModel.showLoading.observe(viewLifecycleOwner) { showLoading ->
        pb.visibility = if (showLoading) View.VISIBLE else View.GONE
    }

    viewModel.showError.observe(viewLifecycleOwner) { showError ->
        (showError)
    }

Возможно, вы захотите сделать viewModel в lateinit var.

0 голосов
/ 18 марта 2020

вы не инициализировали свою привязку:

 private  var binding: FragmentTopHeadlinesBinding? = null

она по-прежнему равна нулю

...