简体   繁体   English

进度条加载不显示服务器的响应?

[英]progress bar loading not showing response from server?

I am developing news app but TopHeadlinesFragment loading progress bar not showing response from server what I want to know where I am making mistake what I have to do in order to show response from server.我正在开发新闻应用程序,但 TopHeadlinesFragment 加载进度条没有显示来自服务器的响应我想知道我在哪里犯了错误我必须做什么才能显示来自服务器的响应。 Maybe something wrong with my observer in topHeadlinesFragment.kt or koin network module我在 topHeadlinesFragment.kt 或 koin 网络模块中的观察者可能有问题

below my screenshot of the app在我的应用截图下方

loading progress加载进度

below my TopHeadlinesFragment.kt在我的 TopHeadlinesFragment.kt 下面

class TopHeadlinesFragment : Fragment() {

    private lateinit var binding: FragmentTopHeadlinesBinding
    private val viewModel by viewModel<MainViewModel>()


    private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
    // private val newsRepository: NewsRepository by inject()


    //3
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding =
            DataBindingUtil.inflate(inflater, R.layout.fragment_top_headlines, container, false)
        binding.lifecycleOwner = this
        topHeadlinesAdapter = TopHeadlinesAdapter()
        return binding.root
    }

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


    }

    private fun initViewModel() {
        viewModel.sportList.observe(this, Observer { result ->

            when (result) {
                is Results.Success -> {
                    val newList = result.data
                    if (newList != null) {
                        topHeadlinesAdapter.updateData(newList)
                    }
                    binding.recyclerView.adapter = topHeadlinesAdapter
                    topHeadlinesAdapter.notifyDataSetChanged()

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


        }

        viewModel.loadNews()
    })



    }


    }

below NewsRepository.kt在 NewsRepository.kt 下面

class NewsRepository(
    private val sportNewsApi: SportNewsInterface,
    private val sportNewsDao: SportNewsDao
) {


    companion object{
        const val  TAG=  "Error"
    }

    val data = sportNewsDao.getAllData()

    suspend fun refresh() = withContext(Dispatchers.IO) {
        val articles = sportNewsApi.getNewsAsync().body()?.articles
        if (articles != null) {
            sportNewsDao.addAll(articles)
          Log.e(TAG,"Error")
            Results.Success(articles)
        } else {
            Results.Failure("MyError")
        }
    }
}

below My MainViewModel.kt在我的 MainViewModel.kt 下面

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

    private val _showLoading = MutableLiveData<Boolean>()
    private val _sportList = MutableLiveData<Results>()

    val showLoading: LiveData<Boolean>
        get() = _showLoading

    val sportList: LiveData<Results>
        get() = _sportList


    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 =  newsRepository.refresh()
            _sportList.value = result
            _showLoading.value = false
        }
    }

    override fun onCleared() {
        job.cancel()
    }

}

below my KoinNetworkModule.kt在我的 KoinNetworkModule.kt 下面

const val BASE_URL = "https://newsapi.org/"
val netModule = module {


    single {
        createWebService<SportNewsInterface>(
            okHttpClient = createHttpClient(),
            factory = RxJava2CallAdapterFactory.create(),
            baseUrl = BASE_URL
        )
    }
}

/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
    val client = OkHttpClient.Builder()
    client.readTimeout(5 * 60, TimeUnit.SECONDS)
    return client.addInterceptor {
        val original = it.request()
        val requestBuilder = original.newBuilder()
        requestBuilder.header("Content-Type", "application/json")
        val request = requestBuilder.method(original.method, original.body).build()
        return@addInterceptor it.proceed(request)
    }.build()
}

/* function to build our Retrofit service */
inline fun <reified T> createWebService(
    okHttpClient: OkHttpClient,
    factory: CallAdapter.Factory, baseUrl: String
): T {
    val retrofit = Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .addCallAdapterFactory(factory)
        .client(okHttpClient)
        .build()
    return retrofit.create(T::class.java)
}

I fixed problem by changing my code followingly.我通过以下更改我的代码来解决问题。

 private fun initViewModel() {
        viewModel.sportList.observe(this, Observer { result ->

            when (result) {
                is Results.Success -> {
                    val newList = result.data
                    if (newList != null) {
                        topHeadlinesAdapter.updateData(newList)
                    }
                    binding.recyclerView.adapter = topHeadlinesAdapter
                    topHeadlinesAdapter.notifyDataSetChanged()
                }
            }
        })

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

        viewModel.loadNews()
    }

Got your Problem.有你的问题。 If you seriously want to show the response, whatever you are getting use this code in the Retrofit Instance.如果您真的想显示响应,无论您得到什么,都可以在 Retrofit 实例中使用此代码。 The role of Intercepter is used to show the request and response at the Log level. Intercepter 的作用是在 Log 级别显示请求和响应。 You can findout the URL of API, Request and resonse in the Log window.您可以在日志 window 中找到 API、请求和响应的 URL。

Now modify KoinNetworkModule.kt like this现在像这样修改 KoinNetworkModule.kt

            const val BASE_URL = "https://newsapi.org/"
            val netModule = module {


                single {
                    createWebService<SportNewsInterface>(
                        okHttpClient = createHttpClient(),
                        factory = RxJava2CallAdapterFactory.create(),
                        baseUrl = BASE_URL
                    )
                }
            }

            /* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
            fun createHttpClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY

        val client1 = OkHttpClient.Builder()
            .connectTimeout(2, TimeUnit.MINUTES)
            .writeTimeout(2, TimeUnit.MINUTES) // write timeout
            .readTimeout(2, TimeUnit.MINUTES) // read timeout

            .addInterceptor(interceptor)
            .build()

            /* function to build our Retrofit service */
            inline fun <reified T> createWebService(
                okHttpClient: OkHttpClient,
                factory: CallAdapter.Factory, baseUrl: String
            ): T {



                val retrofit = Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
                    .addCallAdapterFactory(CoroutineCallAdapterFactory())
                    .addCallAdapterFactory(factory)
                    .client(client1)
                    .build()
                return retrofit.create(T::class.java)
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM