我从一个API中获取类别,我想通过传递类别名称来启动一个新片段,以便在单击按钮时进行改进。我想在UI中使用getText()
在单击的按钮上执行此操作,并启动API调用,该调用将在新片段上显示结果。我使用的API是https://fakestoreapi.com/
据我所知,我必须在UI部件(Fragment的代码)中处理click事件。
下面的代码在我的FakeApiService.kt中
@GET("categories")
suspend fun getCategories(): List<String>
@GET("categories/{product}")
suspend fun getProduct(@Path(value = "product", encoded = true) productType: String): List<Product>
然而,我在向按钮添加clickListener
时遇到了麻烦。
下面是recycleView
适配器的代码
class MyCategoryRecyclerViewAdapter(
private val values: ArrayList<String>
) : RecyclerView.Adapter<MyCategoryRecyclerViewAdapter.MyCategoryRecyclerViewHolder>() {
inner class MyCategoryRecyclerViewHolder :
RecyclerView.ViewHolder(binding.root) {
fun bind(category: String) {
binding.category = category
binding.btnCategoryName.setOnClickListener {
Log.d("Debug On", "Button clicked ${binding.btnCategoryName.text}")
}
}
}
private lateinit var binding: CategoryItemBinding
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): MyCategoryRecyclerViewHolder {
binding = CategoryItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MyCategoryRecyclerViewHolder()
}
override fun onBindViewHolder(holder: MyCategoryRecyclerViewHolder, position: Int) {
holder.bind(values[position])
}
fun updateData(values: ArrayList<String>) {
this.values.clear()
this.values.addAll(values)
}
override fun getItemCount() = values.size
}
类别片段的我的ViewModel
。
enum class FakeApiStatus { LOADING, ERROR, DONE }
class CategoryViewModel : ViewModel() {
// The internal MutableLiveData that stores the status of the most recent request
private val _status = MutableLiveData<FakeApiStatus>()
val status: LiveData<FakeApiStatus> = _status
val categories: ArrayList<String> = ArrayList()
/**
* Call getCategories() on init so we can display status immediately.
*/
init {
Log.d("Debug", "view model created")
getCategories()
}
private fun getCategories() {
viewModelScope.launch(Dispatchers.IO) {
_status.postValue(FakeApiStatus.LOADING)
try {
categories.clear()
categories.addAll(FakeApi.retrofitService.getCategories())
_status.postValue(FakeApiStatus.DONE)
} catch (e: Exception) {
_status.postValue(FakeApiStatus.ERROR)
}
}
}
}
片段的代码。
class CategoryFragment : Fragment() {
private lateinit var binding: FragmentCategoryBinding
private val adapter = MyCategoryRecyclerViewAdapter(ArrayList())
private val viewModel: CategoryViewModel by lazy {
ViewModelProvider(this)[CategoryViewModel::class.java]
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentCategoryBinding.inflate(inflater)
binding.rvCategoryList.adapter = adapter
viewModel.status.observe(viewLifecycleOwner) {
when (it) {
FakeApiStatus.DONE -> binding.animationRotation.visibility = View.GONE
FakeApiStatus.ERROR -> Toast.makeText(
context,
"No Internet!",
Toast.LENGTH_LONG
).show()
else -> {}
}
observeCategories()
}
return binding.root
}
private fun observeCategories(){
adapter.updateData(viewModel.categories)
adapter.notifyDataSetChanged()
}
}
这是我的item
布局
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="category"
type="String" />
</data>
<Button
android:id="@+id/btn_category_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{category.toUpperCase()}"
tools:text="Test"
android:onClick="TODO"
android:layout_margin="@dimen/cardview_default_elevation"
android:textAppearance="?attr/textAppearanceListItem" />
</layout>
而布局为Fragment(RecycleView)
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_category_list"
android:name="com.example.task.categories.CategoryFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:context=".categories.CategoryFragment"
tools:listitem="@layout/category_item" />
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/animation_rotation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
1条答案
按热度按时间2ic8powd1#
在您的fragment / activity中,在类的下面创建一个新的类来处理点击
当您在片段/活动中初始化viewModelAdapter时,您还可以返回回调
您的适配器类:
更改为:传递回调
在视图保持器中,您可以获得单击的位置,如下所示
最后,在你的视图中,你可以通过创建数据变量来访问回调和域对象。2在你的布局标签中,添加数据标签。3在数据标签中添加一个带有名称和对象路径的变量。4(如果你已经创建了域对象的话)。
提示,这可以在xml布局中完成,xml布局将卡片或视图保存到回收器视图中。
您可以使用数据绑定在xml中分配回调。
我所说的域对象是指域模型,它是一个简单的类,你可以示例化它来保存一些数据。
下面是一个用户的简单数据类的示例。