When I try to set the onClick method in my Google's SignInButton:
android:onClick="@{() -> viewModel.onGoogleLoginClick()}"
I always get this error:
Found data binding errors.
****/ data binding error ****msg:Cannot find the proper callback class for android:onClick. Tried android.view.View but it has 0 abstract methods, should have 1 abstract methods.
file:/Users/user/Android/project/app/src/main/res/layout/activity_login.xml loc:53:31 - 53:66 ****\ data binding error ****
Here is my code:
activity_login.xml
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".ui.login.LoginActivity"> <data> <import type="android.view.View" /> <variable name="viewModel" type="com.example.myapp.ui.login.LoginViewModel" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" android:padding="@dimen/default_layout_padding"> <EditText android:id="@+id/login_name_editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/login_username_hint" android:inputType="text" android:text="@{viewModel.mEmail}" /> <EditText android:id="@+id/login_pass_editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/login_name_editText" android:hint="@string/login_password_hint" android:inputType="numberPassword" android:text="@{viewModel.mPassword}" /> <Button android:id="@+id/login_login_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/login_pass_editText" android:onClick="@{() -> viewModel.onServerLoginClick()}" android:text="@string/login_login_button_text" android:textAllCaps="true" /> <com.google.android.gms.common.SignInButton android:id="@+id/login_google_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/login_login_button" android:onClick="@{() -> viewModel.onGoogleLoginClick()}"/> </RelativeLayout> </layout> LoginViewModel.class
public class LoginViewModel extends BaseViewModel<LoginNavigator> implements GoogleApiClient.OnConnectionFailedListener, OnCompleteListener<GoogleSignInAccount>, GoogleApiClient.ConnectionCallbacks { private static final String LOG_TAG = LoginViewModel.class.getSimpleName(); public String mEmail; public String mPassword; public LoginViewModel(DataManager dataHelper, SchedulerProvider schedulerProviderHelper) { super(dataHelper, schedulerProviderHelper); } public void onServerLoginClick() { if (CommonUtils.loginDataIsCorrect(mEmail, mPassword)) { doServerLogin(mEmail, mPassword); } else { getNavigator().handleError(); } } public void onGoogleLoginClick() { getNavigator().googleLogin(); } // Server private void doServerLogin(String name, String pass) { ... } // Google protected void doGoogleLogin(FragmentActivity fragmentActivity, Context context) { ... } ... } LoginActivity.class
public class LoginActivity extends BaseActivity<ActivityLoginBinding, LoginViewModel> implements LoginNavigator { private static final int REQUEST_CODE_REGISTER = 0; private static final int REQUEST_CODE_GOOGLE_SIGN_IN = 1; @BindString(R.string.login_data_missing_message) String mDataMissingMessage; @Inject LoginViewModel mLoginViewModel; private ActivityLoginBinding mActivityLoginBinding; public static Intent newIntent(Context context) { return new Intent(context, LoginActivity.class); } @Override public int getBindingVariable() { return BR.viewModel; } @Override public int getLayoutId() { return R.layout.activity_login; } @Override public LoginViewModel getViewModel() { return mLoginViewModel; } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); mActivityLoginBinding = getViewDataBinding(); mLoginViewModel.setNavigator(this); mActivityLoginBinding.loginGoogleButton.setSize(SignInButton.SIZE_WIDE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CODE_GOOGLE_SIGN_IN: mLoginViewModel.handleGoogleSignInResult(data); break; } super.onActivityResult(requestCode, resultCode, data); } @Override public void googleLogin() { mLoginViewModel.doGoogleLogin(this, this); } @Override public void showGoogleForm(GoogleApiClient googleApiClient) { Intent googleIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient); startActivityForResult(googleIntent, REQUEST_CODE_GOOGLE_SIGN_IN); } ... } And the BaseActivity.class, where I bind view and data for each Activity:
public abstract class BaseActivity<T extends ViewDataBinding, V extends BaseViewModel> extends AppCompatActivity { private T mViewDataBinding; private V mViewModel; public abstract int getBindingVariable(); @LayoutRes public abstract int getLayoutId(); public T getViewDataBinding() { return mViewDataBinding; } public abstract V getViewModel(); public void performDependencyInjection() { AndroidInjection.inject(this); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { performDependencyInjection(); super.onCreate(savedInstanceState); performDataBinding(); } @Override protected void onResume() { super.onResume(); } private void performDataBinding() { mViewDataBinding = DataBindingUtil.setContentView(this, getLayoutId()); this.mViewModel = mViewModel == null ? getViewModel() : mViewModel; mViewDataBinding.setVariable(getBindingVariable(), mViewModel); mViewDataBinding.executePendingBindings(); } } Does anyone know why this error? Because SignInButton implements OnClickListener. I have tried Invalidate Caches / Restart and deleting .gradle and .idea folders but is still not working.