ViewPager2 | View.ClickListener未被调用

13

我使用新的 Android 小部件 ViewPager2 版本 1.0.0-alpha03,当我在其上设置点击监听器时,onClick() 方法不会被调用。

我的 Activity 类:

class MainActivity : AppCompatActivity() {

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

        supportFragmentManager.beginTransaction()
            .add(R.id.fragmentContent, SecondFragment.newInstance(), SecondFragment.TAG)
            .addToBackStack(SecondFragment.TAG)
            .commit()
    }
}

我的碎片:

class SecondFragment : Fragment() {

    companion object {
        val TAG = SecondFragment::class.java.canonicalName

        fun newInstance(): SecondFragment = SecondFragment()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewPager2.setOnClickListener {
            Log.d("logi", "click : ")
        }
    }
}

我的布局xml文件:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

有什么假设或解决方法吗?


我脑海中有两个想法:1)尝试分配背景颜色,以查看元素是否实际上按照您认为的方式进行布局。2)尝试设置android:clickable=true属性。 - LWChris
@LWChris 不工作。 - kovac777
3个回答

13

我找到了解决方法! ViewPager2 包含一个 RecyclerView,我们需要把它当作 RecyclerView 来处理。我创建了 RecyclerView.Adapter 并在 RecyclerView.ViewHolder 的构造函数中设置了 itemView 上的 ClickListener,然后就可以使用了!

在 Fragment 中:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewPager2.adapter = ViewPager2Adapter {
            Log.d("logi", "clicked at : $it")
        }
    }

RecyclerView适配器:

class ViewPager2Adapter(private val itemClickListener: (Int) -> (Unit)) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    val items = mutableListOf<Any>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
        ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false))

    override fun getItemCount(): Int = items.size 

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        // bind your items
    }

    private inner class ItemViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {

        init {
            itemView.setOnClickListener {
                Log.d("logi", "Click!") // WORKS!!!
                itemClickListener(adapterPosition)
            }
        }
    }
}

0

另一种方法可以像下面这样:

class MyAdapter(
    private val items: List<Any>,
    private val onItemClickListener: OnItemClickListener
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = parent.inflate(R.layout.item_details_view_pager)
        return MyViewHolder(itemView)
    }

    override fun getItemCount(): Int = items.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.imageView.apply {
            setOnClickListener {
                onItemClickListener.onItemClick(position)
            }
            ...
        }
    }

    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.some_image_view)
    }
}

构造函数参数onItemClickListener也可以是lambda表达式,但对我来说它只是一个简单的接口:

interface OnItemClickListener {
    fun onItemClick(position: Int)
}

0
不需要进入RecyclerView或适配器。只需在片段布局上设置setOnClickListener即可。我就是用这种方法。
 @Nullable
 @Override
 public View onCreateView(@NonNull LayoutInflater inflater, @NullableViewGroup container, @Nullable Bundle savedInstanceState) {  
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_config, container, false);

    LinearLayout layout = view.findViewById(R.id.fragment_config_layout);
    layout.setOnClickListener(c -> do_what_you_want());

    return view;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接