ViewStub 元素找不到 BindingAdapter

如何解决ViewStub 元素找不到 BindingAdapter

我有一个带有 ViewStub 的 XML 布局。我创建了一个绑定适配器 setLayout 来设置 ViewStub 将膨胀的布局。

<?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">
    <data>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="com.smellydogcoding.westvirginiaelectronicfieldguidedistrict.ui.codeDetail.CodeDetailViewModel" />
    </data>

    <ScrollView
        android:id="@+id/codeDetailsScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ViewStub
                android:id="@+id/retailfood_viewStub"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible"
                app:setLayout="@{viewModel.searchRuleset}"
                app:viewModel="@{viewModel}"/>
        </LinearLayout>
    </ScrollView>
</layout>

绑定适配器

// set the layout for code details ViewStub
@BindingAdapter("setLayout")
fun ViewStub.setLayout(rule: String) {
    layoutResource = when (rule) {
        "retailfood" -> R.layout.stub_code_details_retail_food
        "general" -> R.layout.stub_code_details_general
        "recwater" -> R.layout.stub_code_details_recwater
        "citations" -> R.layout.stub_code_details_citations
        else -> R.layout.stub_code_details_other
    }
}

我在生成的绑定文件中不断收到错误:

cannot find symbol variable setLayout

if (this.retailfoodViewStub.isInflated()) this.retailfoodViewStub.getBinding().setVariable(BR.setLayout,viewModelSearchRulesetGetValue);
                                                                                              ^
  symbol:   variable setLayout
  location: class BR

好像 XML 布局找不到绑定适配器

编辑

这是绑定适配器所在的文件。绑定适配器不在伴随对象或其他命名对象中。

package com.smellydogcoding.westvirginiaelectronicfieldguidedistrict.ui

import android.app.Application
import android.view.ViewStub
import android.webkit.WebView
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat.getColor
import androidx.databinding.BindingAdapter
import com.smellydogcoding.westvirginiaelectronicfieldguidedistrict.R
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

// sets the background image for the program grid view recyclerview
@BindingAdapter("backgroundResource")
fun bindImageResource(imageView: ImageView,imagePath: String) {
    imageView.setImageResource(when (imagePath) {
        "code" -> R.drawable.code
        "restaurant" -> R.drawable.restaurant
        "hotelroom" -> R.drawable.hotelroom
        "well" -> R.drawable.well
        "septic" -> R.drawable.septic
        "pool" -> R.drawable.pool
        "tattoo" -> R.drawable.tattoo
        "mobilehomepark" -> R.drawable.mobilehomepark
        "daycare" -> R.drawable.daycare
        "raccoon" -> R.drawable.raccoon
        "tornado" -> R.drawable.tornado
        else -> R.drawable.code
    })
}

// sets the content for the code details WebViews
@BindingAdapter("webViewData")
fun WebView.webViewData(url: String?) {
    url?.let {
        settings.textZoom = 110
        loadDataWithBaseURL(null,url,"text/html","base64",null)
    }
}

// changes the font color for code details TextViews
@BindingAdapter("changeTextColor")
fun TextView.changeTextColor(text: String?) {
    text?.let {
        when (text) {
            "Priority","Yes" -> setTextColor(getColor(context,R.color.error)
            )
            "Priority Foundation","Potential" -> setTextColor(getColor(context,R.color.warning)
            )
        }
    }
}

// set the layout for code details ViewStub
@BindingAdapter("setLayout")
fun ViewStub.setLayout(rule: String) {
    layoutResource = when (rule) {
        "retailfood" -> R.layout.stub_code_details_retail_food
        "general" -> R.layout.stub_code_details_general
        "recwater" -> R.layout.stub_code_details_recwater
        "citations" -> R.layout.stub_code_details_citations
        else -> R.layout.stub_code_details_other
    }
}

// load JSON assets to use with a recyclerview
object JsonAsset {
    lateinit var application: Application
    inline fun <reified T: Any> getJson (name: String): List<T>? {

        val moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
        val json = application.assets.open(name).bufferedReader().use{ it.readText() }
        val listType = Types.newParameterizedType(List::class.java,T::class.java)
        val adapter: JsonAdapter<List<T>> = moshi.adapter(listType)

        return adapter.fromJson(json)
    }
}

解决方法

所以这个问题有点重复This Stack Overflow Question

但有一些区别。

tl;dr;你不能。

您不能将绑定适配器与 ViewStub 一起使用,因为当编译器创建绑定文件时,它将为 ViewStub 正在膨胀的视图寻找适配器,而不是为 ViewStub 本身寻找适配器。因此它永远不会找到适配器,并抛出错误。恕我直言,这个设计没有意义。如果我想将绑定适配器应用于我正在膨胀的视图,我会制作它们。

上面的 SO 问题确实提到了一种创建方法。不幸的是,它只允许您在 ViewStub 布局通过 onInflateListener 膨胀后应用它,而且我必须在 ViewStub 膨胀之前设置布局。

通过从 ViewStub XML 布局中删除 android:visibility="visible" and app:setLayout="@{viewModel.searchRuleset}" 并以编程方式设置相应片段中存根的布局,我找到了一个解决方案:

// set the layout for the ViewStub and inflate
val viewStubProxy : ViewStubProxy = binding.codeDetailsViewStub
viewStubProxy.viewStub?.layoutResource = when (viewModel.searchRuleset.value) {
    "retailfood" -> R.layout.stub_code_details_retail_food
    "general" -> R.layout.stub_code_details_general
    "recwater" -> R.layout.stub_code_details_recwater
    "citations" -> R.layout.stub_code_details_citations
    else -> R.layout.stub_code_details_other
}
viewStubProxy.viewStub?.inflate()

如果您使用数据绑定,则必须定位 ViewStubProxy 而不是 ViewStub 本身。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-