我是靠谱客的博主 悲凉冷风,最近开发中收集的这篇文章主要介绍Kotlin协程 - - - Flow+Retrofit 应用一.添加依赖二.创建实体类三.封装Retrofit和编写ArticleApi 四.封装viewHolder并完成adapter五.在ViewModel用Flow请求数据六.通过页面交互,获取参数请求对应的内容,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一.添加依赖

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

二.创建实体类

data class Article(val id: Int, val text: String)

三.封装Retrofit和编写ArticleApi 

interface ArticleApi {
    @GET("article")
    suspend fun searchArticles(
        @Query("key")Key:String
    ):List<Article>

}
object RetrofitClient {
    //lazy 懒加载 在使用时构造Retrofit对象
    private val instance: Retrofit by lazy {
        Retrofit.Builder()
            .client(OkHttpClient.Builder().build())
            .baseUrl("http://192.168.1.34:8080/kotlinstudyserver/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    val articleApi: ArticleApi by lazy {
        instance.create(ArticleApi::class.java)
    }
}

四.封装viewHolder并完成adapter

class BindingViewHolder (val binding:ViewBinding):RecyclerView.ViewHolder(binding.root){


}
class ArticleAdapter(private val context: Context) : RecyclerView.Adapter<BindingViewHolder>() {
    private val data=ArrayList<Article>()

    fun setData(data:List<Article>){
        this.data.clear();
        this.data.addAll(data)
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder {
        val inflate = ItemUserBinding.inflate(LayoutInflater.from(context), parent, false)
        return BindingViewHolder(inflate)
    }

    override fun onBindViewHolder(holder: BindingViewHolder, position: Int) {
       val item=data[position]
        val itemUserBinding = holder.binding as ItemUserBinding
        itemUserBinding.text.text=item.text
    }

    override fun getItemCount(): Int {
       return data?.size
    }
}

五.在ViewModel用Flow请求数据

class ArticleViewModel(application: Application) : AndroidViewModel(application) {
    val articles=MutableLiveData<List<Article>> ()

    fun searchArticles(key:String){
        //因为双flow会造成嵌套 ,所以在这里收获后改用了liveData
        viewModelScope.launch {
            flow {
                val list=RetrofitClient.articleApi.searchArticles(key)
                emit(list) //发射数据
            }.flowOn(Dispatchers.IO) //更改Flow上下文
                .catch {
                        e->
                    e.printStackTrace() //上游有异常,在保证不打破flow涉及原则的情况下推荐使用catch函数
                }.collect {
                    articles.value=it; //接收数据并给LiveData赋值
                }
            }
        }
    //双flow会造成嵌套写法
    fun searchArticles1(key:String)= flow{

                val list=RetrofitClient.articleApi.searchArticles(key)
                emit(list) //发射数据
            }.flowOn(Dispatchers.IO) //更改Flow上下文
                .catch {
                        e->
                    e.printStackTrace() //上游有异常,在保证不打破flow涉及原则的情况下推荐使用catch函数
                }

}

六.通过页面交互,获取参数请求对应的内容

class ArticleFragment :Fragment() {


    private val viewModel  by viewModels<ArticleViewModel>()


    private val mBinding: FragmentArticleBinding by lazy {
        FragmentArticleBinding.inflate(layoutInflater)
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return mBinding.root
    }


    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        lifecycleScope.launchWhenCreated {
            //这里调了下面的监听   这里用来双flow设计
                mBinding.etSearch.textWatcherFlow().collect {
                viewModel.searchArticles(it)
                    //双Flow写法接收
               /*     viewModel.searchArticles1(it).collect { data->
                        context?.let {
                            val articleAdapter = ArticleAdapter(it)
                            mBinding.recyclerView.adapter= articleAdapter
                            mBinding.recyclerView.layoutManager=LinearLayoutManager(it,LinearLayoutManager.VERTICAL,false)
                            articleAdapter.setData(data)
                        }
                    }*/
                }
        }

        context?.let {
            val articleAdapter = ArticleAdapter(it)
           mBinding.recyclerView.adapter= articleAdapter
            mBinding.recyclerView.layoutManager=LinearLayoutManager(it,LinearLayoutManager.VERTICAL,false)
            viewModel.articles.observe(viewLifecycleOwner,{article->
                articleAdapter.setData(article)

            })
        }

    }


    private fun TextView.textWatcherFlow(): Flow<String> = callbackFlow{
        val textWatcher = object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                offer(s.toString())
            }

        }

        addTextChangedListener(textWatcher)
        //移除监听器
        awaitClose{removeTextChangedListener(textWatcher)}

    }
}

效果演示:

最后

以上就是悲凉冷风为你收集整理的Kotlin协程 - - - Flow+Retrofit 应用一.添加依赖二.创建实体类三.封装Retrofit和编写ArticleApi 四.封装viewHolder并完成adapter五.在ViewModel用Flow请求数据六.通过页面交互,获取参数请求对应的内容的全部内容,希望文章能够帮你解决Kotlin协程 - - - Flow+Retrofit 应用一.添加依赖二.创建实体类三.封装Retrofit和编写ArticleApi 四.封装viewHolder并完成adapter五.在ViewModel用Flow请求数据六.通过页面交互,获取参数请求对应的内容所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部