我在计费过程中显示商品有问题,logcat告诉我E / RecyclerView:未连接适配器;跳过布局
我尝试了几种方法来解决,但从未成功。
所有代码:
科特林阶级
Principal.kt
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.billingclient.api.*
class Principal : AppCompatActivity(), PurchasesUpdatedListener {
private lateinit var billingClient: BillingClient
private lateinit var productsAdapter: ProductsAdapter
private lateinit var mRecyclerView : RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_principal)
setupBillingClient()
}
private fun setupBillingClient() {
billingClient = BillingClient
.newBuilder(this)
.enablePendingPurchases()
.setListener(this)
.build()
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingServiceDisconnected() {
Toast.makeText(this@Principal, "Desconectado", Toast.LENGTH_SHORT).show()
println("BILLING | onBillingServiceDisconnected | DISCONNECTED")
}
override fun onBillingSetupFinished(responseCode: BillingResult) {
if (responseCode.responseCode == BillingClient.BillingResponseCode.OK) {
Toast.makeText(this@Principal, "Conectado", Toast.LENGTH_SHORT).show()
println("BILLING | startConnection | RESULT OK")
clientReady()
} else {
Toast.makeText(this@Principal, "" + responseCode, Toast.LENGTH_SHORT).show()
println("BILLING | startConnection | RESULT: $responseCode")
}
}
})
}
private fun initProductAdapter(skuDetailsList: List<SkuDetails>) {
productsAdapter = ProductsAdapter(skuDetailsList) {
val billingFlowParams = BillingFlowParams
.newBuilder()
.setSkuDetails(it)
.build()
billingClient.launchBillingFlow(this, billingFlowParams)
}
mRecyclerView = findViewById(R.id.products)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = GridLayoutManager(this,2)
mRecyclerView.adapter = productsAdapter
}
private fun clientReady(){
if (billingClient.isReady) {
val params = SkuDetailsParams
.newBuilder()
.setSkusList(skuList) /*listOf("0_50", "1_00") -- skuList*/
.setType(BillingClient.SkuType.INAPP)
.build()
billingClient.querySkuDetailsAsync(params) {responseCode, skuDetailsList ->
if (responseCode.responseCode == BillingClient.BillingResponseCode.OK) {
initProductAdapter(skuDetailsList)
} else {
Toast.makeText(this@Principal, "No se han sincronizado los productos",Toast.LENGTH_SHORT).show()
}
}
} else {
Toast.makeText(this@Principal, "Cliente no preparado",Toast.LENGTH_SHORT).show()
}
}
companion object {
private val skuList = listOf("0_50", "1_00")
}
override fun onPurchasesUpdated(p0: BillingResult?, purchases: MutableList<Purchase>?) {
Toast.makeText(this@Principal, "Comprado "+purchases!!.size,Toast.LENGTH_SHORT).show()
}
}
ProductsAdapter.kt
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.android.billingclient.api.SkuDetails
class ProductsAdapter(
private val list: List<SkuDetails> ,
private val onProductClicked: (SkuDetails) -> Unit
) : RecyclerView.Adapter<ProductsAdapter.ViewHolder>() {
override fun getItemCount(): Int = list.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val textView = LayoutInflater.from(parent.context).inflate(R.layout.product_item, parent, false) as TextView
val viewHolder = ViewHolder(textView)
textView.setOnClickListener { onProductClicked(list[viewHolder.adapterPosition]) }
return viewHolder
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.text = list[position].title
}
class ViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)
}
和xml文件:
activity_principal.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Principal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="472dp"
android:text="Bienvenido"
android:textSize="35sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/products"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
product_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="20sp" />
这是一个经常性的话题,但我看不到正确的答案
谢谢。
在调用initProductAdapter
之前将对设置回收站视图的调用从onCreate
中移到setUpBillingClient
中>
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_principal) mRecyclerView = findViewById(R.id.products) mRecyclerView.setHasFixedSize(true) mRecyclerView.layoutManager = GridLayoutManager(this,2) setupBillingClient() }
这应该可以解决问题。
问题是,每次触发querySkuDetailsAsync
回调时,您都要初始化适配器。因此,您的recyclerview失去了对其适配器的引用,并且不显示任何布局。尝试以这种方式重构代码: