在Android中使用kotlin进行自定义视图的类DSL的OnClick监听器

我正在尝试创建一个类似DSL的OnClick监听器(在kotlin中),用于在我正在使用的Android项目中使用多个位置的自定义视图。 该视图具有ImageView,主要textview和辅助textview。 我正在试图创建一个监听器帮手,它允许你只覆盖一个接口的特定方法,而不是所有的( 本文的启发)。 但是我无法得到它的工作。 实际上它甚至不能使用普通的OnClick监听器。

这是我的ErrorMessageView:

class ErrorMessageView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0, defStyleRes: Int = 0 ) : FrameLayout(context, attrs, defStyle, defStyleRes) { private var mOnClickListener: OnErrorMessageViewClickListener? = null init { LayoutInflater.from(context).inflate( R.layout.custom_errorview, this, true) ButterKnife.bind(this) } interface OnErrorMessageViewClickListener { fun onImageClick() fun onPrimaryTextClick() fun onSecondaryTextClick() } ... left out for brevity ... fun setOnErrorMessageViewClickListener( onViewClickListener: OnErrorMessageViewClickListener?) { this.mOnClickListener = onViewClickListener } fun setOnErrorMessageViewClickListener(init: ErrorMessageViewClickListenerHelper.() -> Unit) { val listener = ErrorMessageViewClickListenerHelper() listener.init() mOnClickListener = listener } @OnClick(R.id.image_container) internal fun onImageViewClick() { Timber.d("Clicked image view") mOnClickListener?.onImageClick() } @OnClick(R.id.primary_text_container) internal fun onPrimaryTextViewClick() { Timber.d("Clicked primary textview") mOnClickListener?.onPrimaryTextClick() } @OnClick(R.id.secondary_text_container) internal fun onSecondaryTextViewClick() { Timber.d("Clicked secondary textview") mOnClickListener?.onSecondaryTextClick() } } 

这是我的助手类:

 private typealias ErrorViewClickListener = () -> Unit open class ErrorMessageViewClickListenerHelper : ErrorMessageView.OnErrorMessageViewClickListener { private var mImageClick: ErrorViewClickListener? = null fun onImageClick(onImageClick: ErrorViewClickListener?) { mImageClick = onImageClick } override fun onImageClick() { mImageClick?..invoke() } private var mPrimaryTextClick: ErrorViewClickListener? = null fun onPrimaryTextClick(onPrimaryTextClick: ErrorViewClickListener?) { mPrimaryTextClick = onPrimaryTextClick } override fun onPrimaryTextClick() { mPrimaryTextClick?.invoke() } private var mSecondaryTextClick: ErrorViewClickListener? = null fun onSecondaryTextClick(onSecondaryTextClick: ErrorViewClickListener?) { mSecondaryTextClick = onSecondaryTextClick } override fun onSecondaryTextClick() { mSecondaryTextClick?.invoke() } } 

我的布局:

       

我在这样的代码中使用助手,但没有记录(这几乎就像没有clicklistener可以连接):

 override fun setWorklistNotEnabledMessage(showMessage: Boolean) { if (showMessage) { mView?.dialog_worklist_recyclerview?.visibility = View.GONE mView?.dialog_worklist_errorview?.apply { visibility = View.VISIBLE setSecondaryTextClickListener(View.OnClickListener { Timber.d("Test secondary click") }) setErrorDrawable(R.drawable.ic_worklist_disabled_black_24dp) setPrimaryText(R.string.global_worklist_disabled_error) setSecondaryText(R.string.dialog_worklist_worklist_disabled_error_secondary_text) setOnErrorMessageViewClickListener { onSecondaryTextClick { Timber.d("Test secondary click") } onPrimaryTextClick { Timber.d("Test primary click") } onImageClick { Timber.d("Test image click") } // . this@WorklistDialog } } } else { mView?.dialog_worklist_errorview?.apply { visibility = View.GONE setErrorDrawable(null) setPrimaryText("") setSecondaryText("") setOnErrorMessageViewClickListener(null) } } } 

有没有人有我的代码有什么问题的建议?

顺便说一句。 上面的代码在DialogFragment中使用 – 这就是为什么你可能会注意到mView ?. 有点尴尬。 但是,这是在对话框中处理视图的方法。

当我终于find解决方案 – OMG时,我正要开始哭泣。

问题是dialogfragment的布局文件中的SwipeRefreshLayout,可以在这里看到:

          

SwipeRefreshLayout阻止自定义的ErrorMessageView被点击。

在我的DialogFragment中添加mView?.dialog_worklist_swiperefreshlayout?.isEnabled = false ,一切开始工作:

 override fun setWorklistNotEnabledMessage(showMessage: Boolean) { if (showMessage) { mView?.dialog_worklist_recyclerview?.visibility = View.GONE mView?.dialog_worklist_swiperefreshlayout?.isEnabled = false mView?.dialog_worklist_errorview?.apply { visibility = View.VISIBLE setErrorDrawable(R.drawable.ic_worklist_disabled_black_24dp) setPrimaryText(R.string.global_worklist_disabled_error) setSecondaryText(R.string.dialog_worklist_worklist_disabled_error_secondary_text) setOnErrorMessageViewClickListener { onSecondaryTextClick { Timber.d("Test secondary click") } onPrimaryTextClick { Timber.d("Test primary click") } onImageClick { Timber.d("Test image click") } } } } else { mView?.dialog_worklist_errorview?.apply { visibility = View.GONE setErrorDrawable(null) setPrimaryText("") setSecondaryText("") setOnErrorMessageViewClickListener(null) } } }