如何修复“ compositeDisposable.addAll(jsonApi.getData()”中未使用表达的“ this :: displayData”?

时间:2019-08-27 16:19:07

标签: android kotlin android-recyclerview retrofit2 rx-java2

我正在尝试从API提取一些数据并使用翻新和RxJava2显示这些数据。我是否正确使用CompositeDisposable.addall?我说.subscribe {this :: displayData})时指的是什么?

因此,我尝试将.subscribe {...}替换为.subscribe {cryptos-> displayData(cryptos)},但遇到了编译时问题。当提到加密货币时,我不知道我指的是什么。我以为只是模型类名加上了“ s”(请不要问我为什么这么想)。我收到.subscribe {this :: displayData}的错误?是 retrocrypto0827 \ MainActivity.kt:(42,25):该表达式未使用。我认为我没有正确引用接口。预先谢谢你

MainActivity.kt

    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import androidx.recyclerview.widget.LinearLayoutManager
    import com.example.retrocrypto0827.Adapter.CryptoAdapter
    import com.example.retrocrypto0827.Model.Crypto
    import com.example.retrocrypto0827.RetrofitClient.IMyApi
    import com.example.retrocrypto0827.RetrofitClient.RetrofitClient
    import io.reactivex.android.schedulers.AndroidSchedulers
    import io.reactivex.disposables.CompositeDisposable
    import io.reactivex.schedulers.Schedulers
    import kotlinx.android.synthetic.main.activity_main.*

    class MainActivity : AppCompatActivity() {


        internal lateinit var jsonApi: IMyApi
        internal var compositeDisposable: CompositeDisposable = 
        CompositeDisposable()


        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            // Init api
            val retrofit = RetrofitClient.instance
            jsonApi = retrofit.create(IMyApi::class.java)

            // View
            recycler_crypto.layoutManager = LinearLayoutManager(this)
            recycler_crypto.setHasFixedSize(true)
            fetchData()


        }

        private fun fetchData() {
            compositeDisposable.addAll(jsonApi.getData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {this::displayData})
        }

        private fun displayData(cryptoList: List<Crypto>) {

            val adapter = CryptoAdapter(this, cryptoList)
            recycler_crypto.adapter = adapter

        }


    }

Crypto.kt

  data class Crypto(val currency: String, val price: String)

RetrofitClient对象类

    import retrofit2.Retrofit
    import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
    import retrofit2.converter.gson.GsonConverterFactory

    object RetrofitClient {

        private var ourInstance: Retrofit?=null


        val instance: Retrofit
        get(){
            if(ourInstance == null){
                ourInstance = Retrofit.Builder()
                    .baseUrl("https://api.nomics.com/v1/")

     .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
            }
            return ourInstance!!
        }


    }

IMyApi界面

    import com.example.retrocrypto0827.Model.Crypto
    import io.reactivex.Observable
    import retrofit2.http.GET

    interface IMyApi {

        @GET("prices?key=yourapikey")
        fun getData(): Observable<List<Crypto>>
    }

CryptoAdapter.kt

    class CryptoAdapter(internal val context: Context, internal val 
    postList: List<Crypto>)
        :RecyclerView.Adapter<CryptoViewHolder>()
    {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
    CryptoViewHolder {
            var itemView = LayoutInflater.from(parent.context)
                .inflate(R.layout.retro_coin_card, parent, false)
            return CryptoViewHolder(itemView)
        }

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

        override fun onBindViewHolder(holder: CryptoViewHolder, position: 
     Int) {
            holder.txtCurrency.text = 
     postList[position].currency.toString()
            holder.txtPrice.text = postList[position].price.toString()
        }
    }

CryptoViewHolder

  class CryptoViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) 
  {

            val txtCurrency = itemView.txtCurrency
            val txtPrice = itemView.txtPrice
        }

我希望它按照我在recyclerview中放入的顺序显示正在使用的API中的数据。只是这些数据的简单显示。

1 个答案:

答案 0 :(得分:1)

这是Consumer界面:

public interface Consumer<T> {
    /**
     * Consume the given value.
     * @param t the value
     * @throws Exception on error
     */
    void accept(T t) throws Exception;
}

.subscribe {this::displayData}等效于:

.subscribe(
    object : Consumer<List<Crypto>> {
        override fun accept(t: List<Crypto>) {
             ::displayData
        }
    }
)

因此,::displayData尚未使用,它是对该函数的引用。

只需致电.subscribe { displayData(it) }

这里有一个很好的post高阶函数。

Aaaand ...作为提示,您可以使用Retrofit

以更简单和惯用的方式将by lazy实例创建为单例。
    object RetrofitClient {

        val instance: Retrofit by lazy {
            Retrofit.Builder()
                .baseUrl("https://api.nomics.com/v1/")

                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }
    }