【问题标题】:Android: no view IDs are available inside a ScrollView for ViewBinding. How to access?Android:在 ViewBinding 的 ScrollView 中没有可用的视图 ID。如何访问?
【发布时间】:2021-05-31 19:19:20
【问题描述】:

我正在尝试将具有 findViewByIds 的现有项目转换为 ViewBinding。 ScrollView 之外的所有视图 ID 都可以在 Android Studio 中与“binding.viewId ...”一起使用.” 所以我无法访问位于布局中的 ViewFlipper 中的两个

//Activity
private ActivityEditBinding binding;

protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    binding = ActivityEditBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);

// activity_edit.xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:focusableInTouchMode="true"
    tools:context=".AddorUpdateCardActivity">
 ...
 <RelativeLayout
    android:id="@+id/secondLinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/toolbar"  >

<ScrollView
    android:id="@+id/ScrollView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/secondLinearLayout"
    ...  >        
<LinearLayout
    android:id="@+id/lowerVFRow"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingRight="5dp"
    android:paddingEnd="5dp"
    android:orientation="horizontal"  >

    <ViewFlipper
        android:id="@+id/expandVF"
        android:layout_width="wrap_content"
        android:layout_height="44dp"
        android:layout_marginBottom="5dp"  >

        <include layout="@layout/expand_more_act_edit"
            android:id="@+id/expandMore"  />

        <include layout="@layout/expand_less_act_edit"
            android:id="@+id/expandLess"  />

     </ViewFlipper>

</LinearLayout>
</ScrollView>
</RelativeLayout>

// expand_more_act_edit.xml
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/downArrow"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="sd"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_expand_more"  />

<!-- the down arrow -->

我确认已创建自动生成的 ViewBinding 类。下面是我试图将 ClickListener 附加到 downArrow 但我无法访问 downArrow 引用的地方。我在这里错过了什么?

***Android Studio says "Cannot resolve symbol 'expandMore'***
binding.expandMore.downArrow.setOnClickListener(v -> {
        
    // change the down arrow to the up arrow and show the 1-20 EditText lines.
    expandVF.setDisplayedChild(expandVF.indexOfChild(findViewById(R.id.expandLess)));
    moreViewStub.setVisibility(View.VISIBLE);
});

ViewBinding 不能在 ScrollView 中工作吗?我在这里错过了什么?

【问题讨论】:

  • “我确认已经创建了自动生成的 ViewBinding 类”——你看过它们包含的内容了吗?我已经成功地使用了&lt;include&gt; 的视图绑定,所以我不确定为什么expandMore 不会在你的绑定中。
  • 我查看了类,它包含:“@NonNull public final ExpandMoreActEditBinding expandMore;”和“@NonNull public final ViewFlipper expandVF;”和“this.expandVF = expandVF;”和“this.expandMore = expandMore;”所以看起来不错。
  • @CommonsWare 因此,在 Activity 中,我可以使用“binding.viewID...”访问所有视图 ID,除了 内的 ID。而expandVF 和expandMore 在 内部,也就是在ScrollView 内部。 ScrollView 和 LinearLayout 在自动生成的绑定类中看起​​来是正确的。关于如何解决的任何想法?
  • "除了 内的 ID。expandVF 和 expandMore 在 内,并且在 ScrollView 内"——这似乎与您在your first comment 中写的内容。所以,我不确定要告诉你什么。
  • @CommonsWare 所有视图似乎都在自动生成的绑定类中正确设置。但是,当我尝试在 Activity 中为 ScrollView 中包含的 ID 添加“binding.viewID ...”时,该 ID 文本不会自动出现。那是 Studio 显示“无法解析符号错误”并且 ID 文本显示为红色的时候。

标签: android viewflipper android-viewbinding


【解决方案1】:

视图绑定将从您在布局中提供的 id 生成 camelCase id。如果您的视图 id 已经在布局中的 camelCase(expandVF) 中,有时 android studio 将无法识别,因为布局视图 id 和绑定类视图 ID 相同。可能会产生“无法解析符号错误”。

所以不要使用 expandVF、expandMore、expandLess,而是使用 expand_vf、expand_more、expand_less。重建并运行,可能会起作用。

【讨论】:

  • 啊,有趣。我将根据您的反馈进行更改然后重建!
  • 好的。让我知道它是否有效。@AJW
  • 不走运。我将 ID 更改为您的建议并重新构建了项目。当我在 Activity 中并键入“binding.someIDInsideOfTheScrollView”时,我仍然无法访问 ScrollView 中的任何布局 ID。关于如何解决的任何想法?
  • 当我运行您的代码时,一切都按预期工作。所以拆分布局并尝试找到问题,例如首先添加相对布局和滚动视图,然后在活动中检查滚动视图绑定类 ID,然后添加 viewFlipper只有没有包含标签,然后在所有运行你的相对布局(secondLinearLayout)作为根布局之后在活动中找到它。这样你可以找到问题。@AJW
  • 我按照您的建议更改了布局 ID,并删除了所有其他布局视图,只保留了 ScrollView 部分。我删除了以前的自动生成的 java 类。然后我注释掉了所有以前的“...findViewById()”。然后清理并重新构建项目,将项目与 gradle 文件同步,然后使缓存/重新启动无效。瞧!我终于能够访问 ScrollView 和 ViewFlipper 中的 ID。尚未重建整个 xml,但希望有足够的内容继续添加到初始 ScrollView 部分。谢谢,回答赞成并获得赏金。
【解决方案2】:

你需要使用binding.expandVF而不是直接使用expandVF 并使用已包含的布局ID,您需要使用binding.expandLess.ID_YOU_WANT_TO_USE

【讨论】:

  • 设置OnClickListener的代码行报错。 binding.expandVF 或 binding.expandMore 不起作用。
  • 是的,因为您正在尝试直接访问 id ...我认为您只需要在此之前编写绑定...如果您使用 viewBinding
  • 我尝试了 binding.expandVF 并尝试了 binding.expandMore。往上看。两者都没有工作。
  • 如果要使用viewBinding,则需要将设为父级
  • schemas.android.com/apk/res/android" xmlns:app="schemas.android.com/apk/res-auto" xmlns:tools="schemas.android.com/tools"> HERE_YOUR_LAYOUT_SHOULD_BE
【解决方案3】:

在您的情况下,我在代码中看不到问题,所以我猜可能是 Android 构建工具版本太旧了 - ViewBinding 不能很好地工作

尝试在项目的build.gradle 中将构建工具更新到最新版本 4.2.0

dependencies {
   // At least it should be from 4.0.0 
   classpath 'com.android.tools.build:gradle:4.2.0'
}

gradle-wrapper.properties中的distributionUrl

# tools.build 4.2.0 requruired gradle distribution at least 6.7.1+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip

如果与下面的代码不同,请更改 viewBinding 声明:

buildFeatures{
    viewBinding = true
}

然后清理重建您的项目。

查看Compatibility Android Gradle plugin - Release Notes

【讨论】:

  • 感谢您的意见。我有相对较新的构建工具 wrapper.properties 并有 viewBinding 声明。将在以后的帖子中包含这些内容。
【解决方案4】:

通过包装到布局标记中,将您的 activity_edit.xmlexpand_less_act_edit.xmlexpand_more_act_edit.xml 布局转换为数据绑定。

你的activity_edit.xml 看起来像

 <layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:focusableInTouchMode="true"
    tools:context=".AddorUpdateCardActivity">

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <LinearLayout
    android:id="@+id/lowerVFRow"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingRight="5dp"
    android:paddingEnd="5dp"
    android:orientation="horizontal"  >

    <ViewFlipper
    android:id="@+id/expandVF"
    android:layout_width="wrap_content"
    android:layout_height="44dp"
    android:layout_marginBottom="5dp"  >

        <include layout="@layout/expand_more_act_edit"
            android:id="@+id/expandMore"  />

        <include layout="@layout/expand_less_act_edit"
            android:id="@+id/expandLess"  />

    </LinearLayout>
    </ScrollView>
    </RelativeLayout>
    </layout>

你的expand_more_act_edit.xml 看起来像

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ImageView  
    android:id="@+id/downArrow"
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:contentDescription="sd"
    android:clickable="true"
    android:focusable="true"
    android:src="@drawable/ic_expand_more"  />
</layout>

您访问ImageView 的主类将是。

private ActivityEditBinding binding;

protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
binding= DataBindingUtil.setContentView(this, R.layout.activity_edit);
//binding.expandMore.downArrow this is how you will gonna access the view. now do what ever you want with this.
    
}

【讨论】:

  • 嗨,我对使用数据绑定不感兴趣。我专门使用了 ViewBinding。
  • 然后只需从所有 xml 中删除布局标签。休息会是一样的。而不是使用 util 使用 ActivityEditBinding 类来膨胀视图并保存绑定实例。
  • 我的 xmls 中没有布局标签。
  • 是的,我知道。我在谈论我为您的问题提供的解决方案。剩下的很简单,跟着java代码就行了。
【解决方案5】:

您似乎错过了 ViewFlipper 结束标记,并且 xml 中还有其他布局问题。检查是否是问题所在。

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:focusableInTouchMode="true"
tools:context=".AddorUpdateCardActivity">
<RelativeLayout
    android:id="@+id/secondLinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/toolbar"  >

    <ScrollView
        android:id="@+id/ScrollView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/secondLinearLayout">
    <LinearLayout
        android:id="@+id/lowerVFRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingRight="5dp"
        android:paddingEnd="5dp"
        android:orientation="horizontal"  >

        <ViewFlipper
            android:id="@+id/expandVF"
            android:layout_width="wrap_content"
            android:layout_height="44dp"
            android:layout_marginBottom="5dp"  >

        <include layout="@layout/expand_more_act_edit"
            android:id="@+id/expandMore"  />

        <include layout="@layout/expand_less_act_edit"
            android:id="@+id/expandLess"  />
        </ViewFlipper>

    </LinearLayout>
</ScrollView>

我已经纠正了一些但不确定,因为我不知道整个布局。由于您提供的布局中有一些省略号。除此之外,ViewBindingScrollView AFAIK 没有任何问题。

【讨论】:

    【解决方案6】:

    用于数据绑定

    activity.java

    private ActivityEditBinding binding;
    
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    binding= DataBindingUtil.setContentView(this, R.layout.activity_edit);
        
    }
    

    activity_edit.xml

    <layout  xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FFFFFF"
        android:focusableInTouchMode="true"
        tools:context=".AddorUpdateCardActivity">//...
    <ScrollView
    <LinearLayout
        android:id="@+id/lowerVFRow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingRight="5dp"
        android:paddingEnd="5dp"
        android:orientation="horizontal"  >
    
        <ViewFlipper
            android:id="@+id/expandVF"
            android:layout_width="wrap_content"
            android:layout_height="44dp"
            android:layout_marginBottom="5dp"  >
    
            <include layout="@layout/expand_more_act_edit"
                android:id="@+id/expandMore"  />
    
            <include layout="@layout/expand_less_act_edit"
                android:id="@+id/expandLess"  />
    
    </LinearLayout>
    </ScrollView>
    </RelativeLayout>
    </layout>
    

    现在

    binding.expandMore.downArrow.setOnClickListener(v -> {
            
    });
    

    对于 ViewBinding here

    【讨论】:

    • 嗨,我对使用数据绑定不感兴趣。我专门使用了 ViewBinding。
    猜你喜欢
    • 1970-01-01
    • 2022-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多