Payment Method Selection UI Component
The Payment Method Selection UI Component displays the available payment methods and provides functionality to select one of them.
Basic implementation
This code sample demonstrates a basic implementation of Payment Method Selection UI Component.
Implementation
Layout
public class PaymentMethodSelectionUiComponentFragment extends Fragment implements PaymentMethodSelectionUiComponent {
    private PaymentMethodSelectionUiComponentFragmentBinding binding;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        binding = PaymentMethodSelectionUiComponentFragmentBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }
    @Override
    public void onUiComponentCreated(@NonNull PaymentMethodSelectionUiComponentInteraction interaction) {
        // this method will be called after onViewCreated() and before onStart(),
        // it provides the link to the UI Component interaction, use it to initialize your UI,
        // use interaction to get available payment methods
        PaymentMethod[] paymentMethods = interaction.getPaymentMethods();
        PaymentMethodAdapter adapter = new PaymentMethodAdapter(
                paymentMethods,
                // use interaction to select payment method
                position -> interaction.onPaymentMethodSelected(paymentMethods[position])
        );
        binding.paymentMethodRecyclerView.setAdapter(adapter);
    }
    private static class PaymentMethodAdapter extends RecyclerView.Adapter<PaymentMethodAdapter.ViewHolder> {
        @FunctionalInterface
        interface OnItemClickListener {
            void onItemClick(int position);
        }
        static class ViewHolder extends RecyclerView.ViewHolder {
            private final PaymentMethodItemBinding binding;
            public ViewHolder(@NonNull PaymentMethodItemBinding binding,
                              @NonNull OnItemClickListener listener) {
                super(binding.getRoot());
                this.binding = binding;
                binding.getRoot().setOnClickListener(view -> {
                    int position = getAbsoluteAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        listener.onItemClick(position);
                    }
                });
            }
        }
        private final PaymentMethod[] paymentMethods;
        private final OnItemClickListener listener;
        public PaymentMethodAdapter(@NonNull PaymentMethod[] paymentMethods,
                                    @NonNull OnItemClickListener listener) {
            this.paymentMethods = paymentMethods;
            this.listener = listener;
        }
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
                                             int viewType) {
            PaymentMethodItemBinding binding = PaymentMethodItemBinding.inflate(
                    LayoutInflater.from(parent.getContext()), parent, false);
            return new ViewHolder(binding, listener);
        }
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder,
                                     int position) {
            PaymentMethod paymentMethod = paymentMethods[position];
            holder.binding.paymentMethodName.setText(paymentMethod.getDisplayableName());
        }
        @Override
        public int getItemCount() {
            return paymentMethods.length;
        }
    }
}
class PaymentMethodSelectionUiComponentFragment : Fragment(), PaymentMethodSelectionUiComponent {
    private var _binding: PaymentMethodSelectionUiComponentFragmentBinding? = null
    private val binding get() = _binding!!
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = PaymentMethodSelectionUiComponentFragmentBinding.inflate(
            inflater, container, false)
        return binding.root
    }
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
    override fun onUiComponentCreated(interaction: PaymentMethodSelectionUiComponentInteraction) {
        // this method will be called after onViewCreated() and before onStart(),
        // it provides the link to the UI Component interaction, use it to initialize your UI,
        // use interaction to get available payment methods.
        val paymentMethods = interaction.paymentMethods
        val adapter = PaymentMethodAdapter(paymentMethods) {
            // use interaction to select payment method
            position -> interaction.onPaymentMethodSelected(paymentMethods[position])
        }
        binding.paymentMethodRecyclerView.adapter = adapter
    }
    class PaymentMethodAdapter(private val paymentMethods: Array,
                               private val listener: OnItemClickListener) :
        RecyclerView.Adapter() {
        fun interface OnItemClickListener {
            fun onItemClick(position: Int)
        }
        class ViewHolder(val binding: PaymentMethodListItemBinding, listener: OnItemClickListener) :
            RecyclerView.ViewHolder(binding.root) {
            init {
                itemView.setOnClickListener {
                    val position = adapterPosition
                    if (position != RecyclerView.NO_POSITION) listener.onItemClick(position)
                }
            }
        }
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val binding = PaymentMethodListItemBinding.inflate(
                LayoutInflater.from(parent.context), parent, false)
            return ViewHolder(binding, listener)
        }
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.binding.paymentMethodName.text = paymentMethods[position].displayableName
        }
        override fun getItemCount() = paymentMethods.size
    }
}
  <?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/payment_method_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/payment_method_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>