在自定义android组件中将视图模型中的方法作为表达式传递

在自定义android组件中将视图模型中的方法作为表达式传递,android,xml,xml-parsing,android-databinding,Android,Xml,Xml Parsing,Android Databinding,我有一个自定义组件,它将状态更改侦听器作为输入,在OnClick方法中触发onChecked和onUnchecked事件。现在我想将此组件迁移到数据绑定,并尝试将onClick方法分离为以下两种方法: <declare-styleable name="CustomView"> <attr name="onChecked" format="string" /> <attr name="onUnc

我有一个自定义组件,它将状态更改侦听器作为输入,在OnClick方法中触发onChecked和onUnchecked事件。现在我想将此组件迁移到数据绑定,并尝试将onClick方法分离为以下两种方法:

<declare-styleable name="CustomView">
 <attr name="onChecked" format="string" />
 <attr name="onUnchecked" format="string" />
<declare-styleable name="ToggleImageView">
private interface OnStateChangedListener {
    fun onChecked(v: View)
    fun onUnchecked(v: View) {}
}

class DeclaredOnStateChangedListener(
    private val mHostView: View,
    private val checkedMethodName: String,
    private val uncheckedMethodName: String
) :
    OnStateChangedListener {
    private var mResolvedMethod: Method? = null
    private var mResolvedContext: Context? = null

    private fun resolveMethod(contextInput: Context?, mMethodName: String) {
        var context = contextInput
        while (context != null) {
            try {
                if (!context.isRestricted) {
                    val method = context.javaClass.getMethod(
                        mMethodName,
                        View::class.java
                    )
                    mResolvedMethod = method
                    mResolvedContext = context
                    return
                }
            } catch (e: NoSuchMethodException) {
                // Failed to find method, keep searching up the hierarchy.
            }
            context = if (context is ContextWrapper) {
                context.baseContext
            } else {
                // Can't search up the hierarchy, null out and fail.
                null
            }
        }
        val id = mHostView.id
        val idText =
            if (id == View.NO_ID) "" else " with id '" + mHostView.context.resources.getResourceEntryName(
                id
            ) + "'"
        throw IllegalStateException(
            "Could not find method " + mMethodName
                    + "(View) in a parent or ancestor Context for android:onClick "
                    + "attribute defined on view " + mHostView.javaClass + idText
        )
    }

    private fun doExecuteMathod(mMethodName: String, v: View) {
        if (mResolvedMethod == null) {
            resolveMethod(mHostView.context, mMethodName)
        }
        try {
            mResolvedMethod!!.invoke(mResolvedContext, v)
        } catch (e: IllegalAccessException) {
            throw IllegalStateException(
                "Could not execute non-public method for app:${mMethodName}", e
            )
        } catch (e: InvocationTargetException) {
            throw IllegalStateException(
                "Could not execute method for app:${mMethodName}", e
            )
        }
    }

    override fun onChecked(v: View) {
        if (checkedMethodName.isNotEmpty())
            doExecuteMathod(checkedMethodName, v)

    }

    override fun onUnchecked(v: View) {
        if (uncheckedMethodName.isNotEmpty())
            doExecuteMathod(uncheckedMethodName, v)

    }
}
其中DeclaredInstalledListener的实现方式如下:

<declare-styleable name="CustomView">
 <attr name="onChecked" format="string" />
 <attr name="onUnchecked" format="string" />
<declare-styleable name="ToggleImageView">
private interface OnStateChangedListener {
    fun onChecked(v: View)
    fun onUnchecked(v: View) {}
}

class DeclaredOnStateChangedListener(
    private val mHostView: View,
    private val checkedMethodName: String,
    private val uncheckedMethodName: String
) :
    OnStateChangedListener {
    private var mResolvedMethod: Method? = null
    private var mResolvedContext: Context? = null

    private fun resolveMethod(contextInput: Context?, mMethodName: String) {
        var context = contextInput
        while (context != null) {
            try {
                if (!context.isRestricted) {
                    val method = context.javaClass.getMethod(
                        mMethodName,
                        View::class.java
                    )
                    mResolvedMethod = method
                    mResolvedContext = context
                    return
                }
            } catch (e: NoSuchMethodException) {
                // Failed to find method, keep searching up the hierarchy.
            }
            context = if (context is ContextWrapper) {
                context.baseContext
            } else {
                // Can't search up the hierarchy, null out and fail.
                null
            }
        }
        val id = mHostView.id
        val idText =
            if (id == View.NO_ID) "" else " with id '" + mHostView.context.resources.getResourceEntryName(
                id
            ) + "'"
        throw IllegalStateException(
            "Could not find method " + mMethodName
                    + "(View) in a parent or ancestor Context for android:onClick "
                    + "attribute defined on view " + mHostView.javaClass + idText
        )
    }

    private fun doExecuteMathod(mMethodName: String, v: View) {
        if (mResolvedMethod == null) {
            resolveMethod(mHostView.context, mMethodName)
        }
        try {
            mResolvedMethod!!.invoke(mResolvedContext, v)
        } catch (e: IllegalAccessException) {
            throw IllegalStateException(
                "Could not execute non-public method for app:${mMethodName}", e
            )
        } catch (e: InvocationTargetException) {
            throw IllegalStateException(
                "Could not execute method for app:${mMethodName}", e
            )
        }
    }

    override fun onChecked(v: View) {
        if (checkedMethodName.isNotEmpty())
            doExecuteMathod(checkedMethodName, v)

    }

    override fun onUnchecked(v: View) {
        if (uncheckedMethodName.isNotEmpty())
            doExecuteMathod(uncheckedMethodName, v)

    }
}
我的问题当我想这样使用它时:我在绑定方面遇到了问题,并且项目没有构建

   <CustomView
                ....
                    app:onChecked="@{()->viewModel.doNavigate()}"
                    app:onUnchecked="@{()-> viewModel.removeFromFavorite()}"
                   .... />

你知道如何在Android视图中使用onClick属性吗