使用 kotlin-android-extensions 从子模块导入视图时未解析的引用

Posted

技术标签:

【中文标题】使用 kotlin-android-extensions 从子模块导入视图时未解析的引用【英文标题】:Unresolved reference when importing views from a submodule using kotlin-android-extensions 【发布时间】:2019-02-24 17:56:15 【问题描述】:

当我尝试在多模块应用程序中使用 kotlin-android-extendions 的视图注入时,从 android.library 子模块注入视图时出错:

Unresolved reference: component_xyz_user_name

我们有一个主 app 模块和一个 android.library 子模块 subm。应用模块引用 subm。这两个模块都使用数据绑定、kapt 和 android-extensions。

在这两个模块中,gradle 文件都包含:

apply plugin: 'com.android.library' //or com.android.application
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android 
    [...]

    dataBinding.enabled = true
    androidExtensions.experimental = true

在 subm 库中,我们定义 component_user_info.xml 视图,定义如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">

    <data> [...] </data>

    <android.support.constraint.ConstraintLayout
        android:layout_
        android:layout_
        android:orientation="vertical">

        <TextView
            android:id="@+id/component_xyz_user_name"
            android:layout_
            android:layout_ />

    </android.support.constraint.ConstraintLayout>
</layout>

其中component_xyz_user_name 是我们将在下一步中注入的视图。

在主应用程序中,我们定义一个 fragment_main.xml 视图,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>[...]</data>

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/news_details_coordinator_layout"
        android:layout_
        android:layout_
        android:fitsSystemWindows="true">

        <include layout="@layout/component_user_info"
            />

    </android.support.design.widget.CoordinatorLayout>
</layout>

使用以下方式定义的 ViewModel MainFragmentViewModel

import kotlinx.android.synthetic.main.component_user_info.*

class MainFragment : Fragment() 

    fun updateUserInfo() 
        component_xyz_user_name.text = "ABCDEF"
    

编译失败并出现以下错误:

e: /Users/user/repos/project/app/src/main/java/com/company/users/MainFragment.kt: (108, 9): Unresolved reference: component_xyz_user_name
e: /Users/user/repos/project/app/src/main/java/com/company/users/MainFragment.kt: (109, 9): Unresolved reference: component_xyz_user_name

为什么我得到未解决的参考:component_xyz_user_name。有什么解决方法吗?

编辑:

作为临时解决方法,我为 Activity & Fragment 编写了以下扩展函数:

/**
 * Find view in an activity
 */
fun <T : View> Activity.v(@IdRes resId: Int): T = findViewById(resId)

/**
 * Find view in a fragment
 */
fun <T : View> Fragment.v(@IdRes resId: Int): T = activity.findViewById(resId)

这样我可以:

fun updateUserInfo() 
    v<TextView>(R.id.component_xyz_user_name).text = "ABCDEF"

【问题讨论】:

Kotlin Android Extension layouts from library module cannot be resolved的可能重复 您是否尝试过遍历层次结构。通常,当您有一个包含时,您必须通过点符号访问它。 mainFragBinding.childLayout.txtBox。我知道合成导入应该可以工作,但它只会为您节省几个点走,所以我会尝试不使用合成导入以确保那里没有问题。此外,您可能需要为您的 include 提供一个 ID 才能按名称访问它。 感谢 kotlin 扩展中的问题,如果使用 findViewById,它可以工作并且可以看到模块之间的视图。 【参考方案1】:

我遇到了类似的问题 - 我使用 git 添加了一个子模块,但无法在 kotlin 文件中访问它,所以我必须在 build.gradle 中添加这部分:

sourceSets 

    main 
        java 
            srcDir 'src/main/java/module_folder'
        
    

这必须在主要的 android 对象中

【讨论】:

以上是关于使用 kotlin-android-extensions 从子模块导入视图时未解析的引用的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)