这实际上是两个问题。
error: cannot find symbol
import com.example.android.aboutme.databinding.ActivityMainBindingImpl;
^
symbol: class ActivityMainBindingImpl
location: package com.example.android.aboutme.databinding
为什么会这样?
主要活动:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
val person = Person("Bob")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.person = person
binding.apply {
btnDone.setOnClickListener { doneClick(it) }
}
}
private fun doneClick(view: View) {
binding.apply {
person?.nickname = etNickname.text.toString()
invalidateAll()
etNickname.visibility = View.GONE
tvNickname.visibility = View.VISIBLE
btnDone.visibility = View.GONE
}
hideKeybord(view)
}
private fun hideKeybord(view: View) {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
}
人员:
class Person(var name: String, var nickname: String? = null)
activity\u main。xml:
<?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">
<data>
<variable
name="person"
type="com.example.android.aboutme.Person" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="@dimen/padding"
android:paddingEnd="@dimen/padding">
<TextView
android:id="@+id/tv_name"
style="@style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={person.name}"
android:textAlignment="center" />
<EditText
android:id="@+id/et_nickname"
style="@style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/what_is_your_nickname"
android:inputType="textPersonName"
android:textAlignment="center" />
<Button
android:id="@+id/btn_done"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/layout_margin"
android:fontFamily="@font/roboto"
android:text="@string/done" />
<TextView
android:id="@+id/tv_nickname"
style="@style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={person.nickname}"
android:textAlignment="center"
android:visibility="gone" />
<ImageView
android:id="@+id/star_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_margin"
android:contentDescription="@string/yellow_star"
app:srcCompat="@android:drawable/btn_star_big_on" />
<ScrollView
android:id="@+id/bio_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/layout_margin">
<TextView
android:id="@+id/bio_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="@dimen/line_spacing_multiplier"
android:text="@string/bio"
android:textAppearance="@style/NameStyle" />
</ScrollView>
</LinearLayout>
</layout>
静态编程语言中的Val和Var
问题1:
我注意到,如果在Person数据类中我将name参数设置为val而不是var,则数据绑定不起作用。
为什么会发生?
因为您正在使用双向数据绑定。
在您的布局中,您有以下内容:
<TextView
android:id="@+id/tv_name"
style="@style/NameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={person.name}"
android:textAlignment="center" />
android:text=“@={person.name}”中的@=
告诉databinding“我想将文本视图
的文本设置为该人的名称
值,并且我想在文本视图
文本更改时更新该人的名称
”。
使用@=数据绑定时,将为正在分配的属性查找setter。在本例中,它正在查找Person类上的name属性的setter。在Kotlin中,这意味着拥有一个名为name的属性,即var。
如果您不打算在TextView
更改时更新该人的name
属性(我假设您不会,您通常会使用EditText
来执行此操作),然后将该行更改为仅@
(android: text="@{person.name}"
)。然后您可以将name
设为val
,因为您只是从其中读取数据。
问题二:
为什么我需要在doneClick()中调用invalidateAll()?
你真的不。。。
留档说它“使所有绑定表达式无效并请求新的重新绑定以刷新UI”。数据绑定的目的不是为了连接数据和视图,以便更新数据立即更新视图吗?
是的,但是:数据绑定不是魔法。如果UI要更新,则必须告诉它这样做,而更改数据并不会神奇地告诉数据绑定它必须更新。必须告诉数据绑定:a)是时候更新了,b)需要更新什么。
因此,您现在使用的是散弹枪方法。您更新了一个昵称字段,然后对数据绑定大喊“嘿,更新所有内容!”,因此,它根据Person的当前状态重新绑定所有视图,其中当然包括“昵称”,以便更新视图。
您要做的是只更新绑定到昵称的字段,因为这是一件发生变化的事情,最好是在昵称发生变化时自动更新。为此,您需要观察昵称字段的状态,并对其变化做出反应。
您可以通过以下几种方式完成此操作:
在这种方法中,您需要绑定的模型字段是对象(val昵称=MutableLiveData
数据绑定设置为使用Live Data,因此您的xml不需要更改。但现在属性是可观察的,当您更新Person上的名称时(
Person?.nickname?.value=“New nickname”
),将自动通知数据绑定,并更新关联视图的状态。
您不必调用
validateAll()
。
这在概念上与#1相同,但这是在引入Live Data之前出现的。现在,您可以考虑不推荐使用这种方法,并使用LiveData方法,但为了完整起见,我会提到它。
同样,您可以将该属性包装在一个可观察的数据结构中(
val昵称=observatestring()
),当值发生更改时,该结构将通知数据绑定,而不是使用类型为字符串的常规属性。同样,设置数据绑定就是为了使用它,所以您不必更改XML。
使用此选项,您可以使您的Person类(或者最好是视图模型)扩展为可观察的,并在字段更改时管理通知数据绑定。如果在更新某些字段时必须有特殊的逻辑,并且简单的“设置并通知”是不够的,那么您可以走这条路线。这个选项要复杂得多,我将把它作为练习留给读者阅读文档,看看这个选项是如何工作的。对于绝大多数情况,您应该能够使用选项#1执行所需操作。
这句话的离别思想:
person?.nickname = etNickname.text.toString()
如果您正确设置了数据绑定,这应该是不必要的。:)如果您设置
etNickname
以使用双向绑定并使person.nickname
正确可观察,person.nickname
属性将在更改时自动更新为etNickname
中的文本值!
这就是数据绑定的美妙之处。
希望有帮助!
如果我没有使用spring构建图形,那么是否可以使用spring框架完全访问我的neo4j图形?我正在尝试一些示例,但它似乎无法正常工作,因为spring创建的某些元数据不存在。 编辑:例如,我有这个错误当我试图通过它的id访问一个节点时,即
2.2.5版 []Linux 使用ETL导入顶点和边时,加载一些顶点和边后会出现超时异常。 -year . CSV:id _ year | year 1 | 2010年2 | 2011年3 | 2012年4 | 2013年5 | 2014年6 | 2015年7 | 2016年8 | 2017年 - 月.csv:id_month |月 |第|季度年 1 || 年 1 月日本金融|2010 2 |2
但现在,有些服务会变成空的。是否有方法在@Runwith注释中同时使用SpringJunit4ClassRunner.class和PowerMockRunner.class
我运行下面的脚本时出错,我不知道如何更正它。本质上,我在mysql中有一个名为gamestbl的表。我希望用户输入一些关于游戏名称或游戏描述的关键词,然后php将正确的游戏显示为下拉列表(理想情况下)甚至信息表。 错误显示: 警告:mysqli_query()至少需要2个参数,其中1个参数在第29行的C:\xampp\htdocs\introductiongphp\Email.php中给出 警告:
我的gradle文件中有以下数据绑定依赖项
请问这是什么原因? 官方文档里的代码复制下来也是错误的