Data binding “error: cannot find symbol class Models”

冷暖自知 提交于 2019-12-13 03:06:18

问题


First, I need to acknowledge the clearly very similar but not duplicate issue here. None of the proposed solutions in that thread work.

My application file structure is as follows:

app
  java
    [mydomain].[myapplication]
      Models
        DataModel.java
      MainActivity.java
  res
    layout
      activity_main.xml
      content_main.xml
      my_inner_layout.xml

My app build.gradle contains

dataBinding {
    enabled = true
}

In MainActivity.java I have

import [mydomain].[myapplication].Models.DataModel;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemsSelectedListener {

    DataModel dataModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ... <other layout creation template code> ...

        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        dataModel = new DataModel();
        binding.setValues(dataModel);
    }

    <navigation and auto-generated methods>
}

My my_inner_layout.xml contains

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="values"
            type="[mydomain].[myapplication].Models.DataModel" />
    </data>
    <android.support.constraint.ConstraintLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"
        >

        <TextView
            android:id="@+id/intro_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:text="@{values.valueOne}"/>

        <TextView
            android:id="@+id/buying_recommendation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/intro_text"
            app:layout_constraintTop_toBottomOf="@id/intro_text"
            android:text="@{values.valueTwo}"/>
    </android.support.constraint.ConstraintLayout>
</layout>

I am passing bind:values="@{values}" through from activity_main to its included app_bar_main to its content_main to its my_inner_layout with that same <data> value in each. Android Studio is telling me "namespace 'bind' is not bound".

If I try to run this, I get "Compilation failed; see the compiler error output for details." Looking in the build output, I see:

In text, the errors are variously error: cannot find symbol class Models and error: package Models does not exist

If I move DataModel.java out of the Models package and directly in to [mydomain].[myapplication], then I get a different result. It does build and run in the emulator, but with much of the layout information failing to appear. No hamburger menu in the top left, no title text in the header, and no settings button in the top right values previously automatically included by the autogenerated code in Android Studio. I am unable to set the title in code using setTitle, either.

Swiping from the left does bring in the navigation drawer however.

I have tried invalidating caches and restarting, cleaning, rebuilding both with the model file in Models and separately.

What I want, chiefly, is to be able to use the project structure I want. To put my models classes in a models sub-package. Once that is complete, I want to make sure the full layout information comes through, including the hamburger menu icon, settings icon, and title. How can I achieve this?


回答1:


Okay, I realised where the "class Models does not exist" thing comes from. I don't know whether to blame my own stupidity or the stupidly nitpicky way this binding is implemented on Android. The package needed to be called models with a lower case "m", not Models. The binding auto-name-conversion thing must have thought Models was a class, not a package.

To fix the layout, the onCreate method had to be changed to

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    dataModel = new DataModel();
    cycleInformationBinding.setRecommendation(dataModel);

    // set toolbar
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Drawer layout setting
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

Specifically, things had to happen in the order:

  1. setContentView to the main activity
  2. Set up the data model binding
  3. Layout concerns like drawer and toolbar.

Any other order would cause either the model binding to fail or the toolbar to not display correctly.




回答2:


In your XML file you have to add full path of Model Class as below,

<data>
    <variable
        name="values"
        type="[mydomain].[myapplication].Models.DataModel" />
</data>

Issue: you have not mentioned full path of model in XML. Forgot to write .Model




回答3:


First try to remove redurant setContentView(R.layout.activity_main);

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

Second add to end of "onCreate" function

binding.included.setValues(dataModel);
binding.executePendingBindings();

if you use include than you may add to your include id for example

<include
    android:id="@+id/included"
    layout="@layout/content_main"
    app:values="@{DataModel}"/>

and use

binding.included.setValues(dataModel);

research about using databinding with included layouts




回答4:


Just convert your existing layouts to data binding layouts (Don't forget to add variable in your xml with your activity mentioned in type)

Example:

<variable name="navdrawer" type="com.example.sampleapp.HomeScreenActivity" />

This will generate a data binding class for NavigationHeaderView in this format(May differ) NavHeaderYourActivityName.

When you bind your parent activity, you will use that binding instance to get DrawerLayout and your NavigationView, respectively.

A sample code to reduce the boilerplate for initializing views in your code:

NavHeaderHomeScreenBinding navHeaderHomeScreenBinding = 
DataBindingUtil.setContentView(this, R.layout.nav_header_home_screen);
AppBarHomeScreenBinding appBarHomeScreenBinding = 
DataBindingUtil.setContentView(this, R.layout.app_bar_home_screen);
ActionBarDrawerToggle toggle = 
new ActionBarDrawerToggle(this, binding.drawerLayout, appBarHomeScreenBinding.toolbar, 
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
binding.drawerLayout.addDrawerListener(toggle);
toggle.syncState();
binding.navView.setNavigationItemSelectedListener(this);

I hope this helps someone! Thank you!



来源:https://stackoverflow.com/questions/53319443/data-binding-error-cannot-find-symbol-class-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!