Android: no view IDs are available inside a ScrollView for ViewBinding. How to access?

1k Views Asked by At

I am trying to convert an existing project with findViewByIds over to ViewBinding. All of the view IDs outside of the ScrollView are available in Android Studio for use with "binding.viewId..." The problem is none of the views with IDs that are within the ScrollView are available for use with "binding.viewID..." So I am not able to access ImageViews that are within two <include layouts that are within a ViewFlipper in the layout. The simple ViewFlipper toggles between an up arrow ImageView and a down arrow ImageView. The ViewFlipper has an <include layout for the up ImageView and a second <include layout for the down ImageView. The ViewFlipper is inside a LinearLayout and the LinearLayout is inside the ScrollView.

//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 -->

I confirmed that the autogenerated ViewBinding classes have been created. Below is where I am trying to attach a ClickListener to the downArrow but I can't access the downArrow reference. What am I missing here?

***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);
});

Does ViewBinding not work within a ScrollView? What am I missing here?

6

There are 6 best solutions below

13
Kamal Nayan On

You need to use binding.expandVF instead of directly using expandVF and to use id of layout which have been included, you need to use binding.expandLess.ID_YOU_WANT_TO_USE

5
androidLearner On

View binding will generate camelCase id from id that you have provided in your layout.If your view id is already in camelCase(expandVF) in your layout,sometimes android studio won't recognize that because layout view id and binding class view id are same.that may produce 'Cannot resolve symbol error'.

so instead of expandVF,expandMore,expandLess use expand_vf,expand_more,expand_less.Rebuild and run,may work.

1
Elango On

for databinding

in activity.java

private ActivityEditBinding binding;

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

in 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>

now

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

for ViewBinding here

1
Wilson Tran On

In your case, I don't see the problem in the code so I'm guessing maybe the Android build tool version is quite old - ViewBinding doesn't work very well

Try to update the build tools to the latest version 4.2.0 in build.gradle of project

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

And distributionUrl in gradle-wrapper.properties

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

Change the viewBinding declaration if it is different from the code below:

buildFeatures{
    viewBinding = true
}

Then Clean-Rebuild your project.

Check out Compatibility Android Gradle plugin - Release Notes

4
Muhammad Ali On

convert your activity_edit.xml, expand_less_act_edit.xml, and expand_more_act_edit.xml layout into data binding by wrapping into layout tag.

your activity_edit.xml will look like

 <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>

your expand_more_act_edit.xml will look like

<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>

your main class to access the ImageView will be.

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.
    
}
0
Saikrishna Rajaraman On

It looks like you have missed ViewFlipper closing tag and there are other layout issues in xml. Check if that is the issue.

<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>

I've corrected some but not sure since I don't know the whole layout. Since there are some ellipses in the layout you have provided. Other than that ViewBinding has no issues with ScrollView AFAIK.