如何访问 ViewPager 中的 ImageButton

How to access an ImageButton inside a ViewPager

这是我的第一个问题,希望我没有弄错或写错细节。 我最近开始使用 Android Studio,目前我正在做一个简单的测验。我按照教程使用了一个视图寻呼机,并创建了一个 ViewPagerAdapter Kotlin 文件。视图寻呼机有一个 ImageButton,id 为“R.id.currentLvl”。现在,每当我尝试通过 findviewbyid 在 MainActivity 中访问此 id 时,应用程序在启动时崩溃并给出空指针错误。这是 MainActivity 的代码:

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

    val images = listOf(
        R.drawable.coffee_placeholder,
        R.drawable.coffee_placeholder,
        R.drawable.coffee_placeholder
    )
    val adapter = ViewPagerAdapter(images)
    findViewById<ViewPager2>(R.id.viewPager).adapter = adapter
    findViewById<ImageButton>(R.id.currentLvl).setOnClickListener{
        Toast.makeText(applicationContext, "hi", Toast.LENGTH_SHORT).show()
    }
}

}

这是适配器:

class ViewPagerAdapter(
val images: List<Int>

) : RecyclerView.Adapter() { 内部 class ViewPagerViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewPagerViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.viewpager_quizlvls, parent, false)
    return ViewPagerViewHolder(view)
}

override fun onBindViewHolder(holder: ViewPagerViewHolder, position: Int) {
    val currentImage = images[position]
    holder.itemView.findViewById<ImageButton>(R.id.currentLvl).setImageResource(currentImage)
}

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

}

如果我的问题措辞有误,简而言之是如何听这个ImageButton?我是否在适配器或主 activity 中有它的侦听器?

您应该在 ViewHolder class 中处理它。例如,假设您的 ViewHolder 是 ViewPagerViewHolder。在 init 中执行此操作很重要,因此您不会在每个绑定中设置 OnClickListener。

应该这样定义:


class ViewPagerViewHolder(
    private val itemView: View,
    private val onImageButtonClicked: () -> Unit
) : RecyclerView.ViewHolder(itemView) {

    val image = itemView.findViewById<ImageButton>(R.id.currentLvl)


    init {
        // Depending on what you want click on (can be itemView or image, choose regarding our needs)
        image.setOnClickListener { onImageButtonClicked.invoke() }
    }

    fun bind(resource: Int) {
        image.setImageResource(resource)
    }
}

现在您必须更新适配器以传递点击事件:


class ViewPagerAdapter(
    val images: List<Int>,
    val onImageButtonClicked: () -> Unit 
) : RecyclerView.Adapter<ViewPagerAdapter.ViewPagerViewHolder>() {

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewPagerViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.viewpager_quizlvls, parent, false)
    return ViewPagerViewHolder(view) {
         onImageButtonClicked.invoke()
    }
  }

  override fun onBindViewHolder(holder: ViewPagerViewHolder, position: Int) {
    val currentImage = images[position]
    holder.itemView.findViewById<ImageButton>(R.id.currentLvl).setImageResource(currentImage)
  }

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

最后在您的 MainActivity 中,您应该执行如下操作:


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

    val images = listOf(
        R.drawable.coffee_placeholder,
        R.drawable.coffee_placeholder,
        R.drawable.coffee_placeholder
    )
    val adapter = ViewPagerAdapter(images, ::onImageButtonClicked)
    findViewById<ViewPager2>(R.id.viewPager).adapter = adapter
  }

  private fun onImageButtonClicked() {
    Toast.makeText(applicationContext, "hi", Toast.LENGTH_SHORT).show()
  }

}