栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Kotlin协程 - - - Flow+Retrofit 应用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Kotlin协程 - - - Flow+Retrofit 应用

添加依赖

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.recyclerview:recyclerview:1.2.1'

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

创建实体类Article

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

}
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)
    }
}

封装 Retrofit

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


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

    fun setData(data:List){
        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
    }
}

RecyclerView适配器

class ArticleViewModel(application: Application) : AndroidViewModel(application) {
    val articles=MutableLiveData ()

    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函数
                }

}

ViewModel类

class ArticleFragment :Fragment() {


    private val viewModel  by viewModels()


    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写法接收
               
                }
        }

        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 = 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)}

    }
}

效果演示:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/749960.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号