Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用数据绑定onClick表达式时未生成片段的BindingImpl类_Android_Gradle_Data Binding - Fatal编程技术网

Android 使用数据绑定onClick表达式时未生成片段的BindingImpl类

Android 使用数据绑定onClick表达式时未生成片段的BindingImpl类,android,gradle,data-binding,Android,Gradle,Data Binding,在片段布局中,我有一个按钮,它使用XMLOnClick表达式调用相应ViewModel中的方法 问题是,在构建项目时,编译器会抛出以下错误: error: cannot find symbol import com.aresid.myapp.databinding.FragmentLoginBindingImpl; ^ symbol: class FragmentLoginBindingImpl location: pa

在片段布局中,我有一个按钮,它使用XMLOnClick表达式调用相应ViewModel中的方法

问题是,在构建项目时,编译器会抛出以下错误:

error: cannot find symbol
import com.aresid.myapp.databinding.FragmentLoginBindingImpl;
                                    ^
symbol:   class FragmentLoginBindingImpl
location: package com.aresid.myapp.databinding
问题是,当我从XML中的函数签名和函数调用中删除参数时,应用程序的构建不会出现问题

我的期望是,当我单击login按钮时,将调用ViewModel中的方法,记录emailField.text和passwordField.text

布局文件:

以及创建视图的片段:

试试这个:

用于您的电子邮件和密码。这样,用户在UI中更改ViewModel字段后,这些字段将自动更改:

android:text=@={viewmodel.password}

您的函数onLoginButtonClicked现在可以在没有参数的情况下声明。这些值现在作为ViewModel的字段保存,以便您可以在函数中自由获取它们

在xml中,还要更改onClick:

android:onClick=@{->loginViewModel.onLoginButtonClicked}


谢谢你的回答。不幸的是,它对我不起作用。我按照你上面写的那样做了,并使用了双向数据绑定。我还尝试了你链接中的BaseObservable功能。实际上,你可以使用当前的LiveData而不是Observable,但可能会将私有改为公共,数据绑定可以很好地使用它。你说它不起作用是什么意思?您仍然有相同的生成错误吗?你们可以阅读有关LiveData的官方文件中的第一篇文章有点过时了。哦,天哪。将LiveData从私有更改为公共确实解决了这个问题。在那之前,是的,我得到了同样的构建错误。无论如何,非常感谢你的帮助。
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    >

    <data>

        <variable
            name="loginViewModel"
            type="com.aresid.myapp.login.LoginViewModel"
            />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="@dimen/fragmentPaddingMedium"
        tools:context=".login.LoginFragment"
        >

        <ImageView
            android:id="@+id/app_logo"
            android:layout_width="@dimen/imageViewAppLogoSize"
            android:layout_height="@dimen/imageViewAppLogoSize"
            android:layout_marginTop="4dp"
            android:contentDescription="@string/my_app_logo"
            android:src="@drawable/my_app_logo_144"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/email_field_layout"
            style="@style/Widget.MyApp.TextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:errorEnabled="true"
            app:layout_constraintTop_toBottomOf="@+id/app_logo"
            >

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/email_field"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/email"
                android:inputType="textEmailAddress"
                android:maxLines="1"
                android:singleLine="true"
                />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/password_field_layout"
            style="@style/Widget.MyApp.TextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:errorEnabled="true"
            app:layout_constraintTop_toBottomOf="@+id/email_field_layout"
            app:passwordToggleEnabled="true"
            >

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/password_field"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/password"
                android:imeActionId="6"
                android:imeActionLabel="@string/common_signin_button_text"
                android:imeOptions="actionUnspecified"
                android:inputType="textPassword"
                android:maxLines="1"
                android:singleLine="true"
                />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.button.MaterialButton
            android:id="@+id/login_button"
            style="@style/Widget.MyApp.ContainedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/log_in"
            android:onClick="@{() -> loginViewModel.onLoginButtonClicked(emailField.text, passwordField.text)}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/password_field_layout"
            />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="13dp"
            android:text="@string/sign_up_using_these_colon"
            android:textAlignment="center"
            app:layout_constraintBottom_toTopOf="@+id/signup_button_container"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            />

        <LinearLayout
            android:id="@+id/signup_button_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="13dp"
            android:gravity="center"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            >

            <androidx.appcompat.widget.AppCompatImageButton
                android:id="@+id/email_signup_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="6.5dp"
                android:background="@drawable/round_button_background"
                android:src="@drawable/ic_email_24dp"
                />

            <androidx.appcompat.widget.AppCompatImageButton
                android:id="@+id/google_signup_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="6.5dp"
                android:background="@drawable/round_button_background"
                android:src="@drawable/ic_google_favicon_24dp"
                />
        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
package com.aresid.myapp.login

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import timber.log.Timber

/**
 * Created on: 27/04/2020
 * For Project: MyApp
 * Author: René Spies
 * Copyright: © 2020 ARES ID
 */

class LoginViewModel: ViewModel() {

    // LiveData for the login email
    private val _email = MutableLiveData<String>()
    val email: LiveData<String>
        get() = _email

    // LiveData for the login password
    private val _password = MutableLiveData<String>()
    val password: LiveData<String>
        get() = _password

    // LiveData for the login button
    private val _wantLogin = MutableLiveData<Boolean>()
    val wantLogin: LiveData<Boolean>
        get() = _wantLogin

    init {

        Timber.d("init: called")

        // TODO:  init: init objects here

        // Init email LiveData
        _email.value = ""

        // Init password LiveData
        _password.value = ""

        // Init wantLogin LiveData
        _wantLogin.value = false

    }

    fun onLoginButtonClicked(email: String, password: String) {

        Timber.d("onLoginButtonClicked: called")
        Timber.d("email = $email\npassword = $password")
        // TODO:  onLoginButtonClicked: log in user

    }

}
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        Timber.d("onCreateView: called")

        // Define LoginViewModel
        loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java)

        // Define FragmentLoginBinding and inflate the layout
        binding = FragmentLoginBinding.inflate(inflater, container, false)

        // TODO:  onCreateView: code goes here

        // Let the data binder know about the LoginViewModel
        binding.loginViewModel = loginViewModel

        // Return the inflated layout
        return binding.root

    }