我遇到了数据绑定问题。我正在尝试添加XML布局,设置所包含的 tag
的 TextView
。但是,它解析为包含的布局名称以布局为前缀,后缀为_0,即 layout/common_helpinfo_0
在主要布局中我有: -
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
....
<LinearLayout
.....
>
<TextView
.... />
<include layout="@layout/common_helpinfo"
android:id="@+id/hi_tag_world1"
app:tagstr="@{@string/hi_tag_world1}"
>
</include>
</LinearLayout>
....
</LinearLayout>
</layout>
包含的布局common_helpinfo
是: -
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="tagstr" type="String"/>
</data>
<TextView
....
android:tag="@{tagstr}"
''''
android:onClick="clickHelpInfo"
>
</TextView>
</layout>
为了测试这一点,我在MainActivity
中有以下内容: -
public void clickHelpInfo(View v) {
String hicaller = v.getTag().toString();
int vid = v.getId();
Toast.makeText(this,"You Clicked Help from button=" + hicaller + " ID+" + Integer.toString(vid)
, Toast.LENGTH_SHORT).show();
}
在主布局中,我还有一个硬编码等效的包含TextView: -
<TextView
....
android:tag="@string/hi_tag_world1"
''''
android:onClick="clickHelpInfo"
>
</TextView>
这样可以正常工作,Toast显示字符串资源的内容 hi_tag_world1
。
在 ActivitMainBinding
中,成功编译后,我会看到以下内容,显示错误数据的设置位置( 注意我实际上已包含common_helpinfo两次都是相同的 ): -
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = new android.databinding.ViewDataBinding.IncludedLayouts(12);
sIncludes.setIncludes(1,
new String[] {"common_helpinfo"}, <<<<<
new int[] {3},
new int[] {R.layout.common_helpinfo}); <<<<<
sIncludes.setIncludes(2,
new String[] {"common_helpinfo"}, <<<<<
new int[] {4},
new int[] {R.layout.common_helpinfo}); <<<<<
sViewsWithIds = new android.util.SparseIntArray();
sViewsWithIds.put(R.id.vtext01, 5);
sViewsWithIds.put(R.id.vtext02, 6);
sViewsWithIds.put(R.id.vtext03, 7);
sViewsWithIds.put(R.id.tvhi03, 8);
sViewsWithIds.put(R.id.etext01, 9);
sViewsWithIds.put(R.id.actvemail, 10);
sViewsWithIds.put(R.id.lvemail, 11);
}
但是稍后在 ActivityMainBinding
中,我会看到以下内容,以尝试获取正确的数据: -
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
// batch finished
if ((dirtyFlags & 0x4L) != 0) {
// api target 1
this.hiTagWorld1.setTagstr(getRoot().getResources().getString(R.string.hi_tag_world1));
this.hiTagWorld2.setTagstr(getRoot().getResources().getString(R.string.hi_tag_world2));
}
executeBindingsOn(hiTagWorld1);
executeBindingsOn(hiTagWorld2);
}
我查看了How do I use databinding to combine a string from resources with a dynamic variable in XML?
上的代码我已启用DataBinding并将build.gradle设置为: -
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "mjt.testvcsuse"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
dataBinding {
enabled = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
}
答案 0 :(得分:0)
经过一段时间的游戏后,我似乎找到了一个解决方案,即使用dataBindingUtil
的{{1}}方法替换setContentView
方法。
e.g。的 setContentView
强>
即。而不是: -
final ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
使用以下方法进行绑定: -
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
....
}
我通过阅读 Obaro Ogbo 撰写的文章Android Authority - Data Binding in Android找到了这一点。相关的摘录是: -
数据绑定活动
目前,我们有一个支持数据绑定的布局文件。 但是,要利用其数据绑定能力,我们必须将其加载到 不同的方式。
以前,你会加载你的布局:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main); .... }
使用数据绑定,可以从布局自动生成Binding类 文件。默认情况下,使用您的布局文件名命名该类。该 默认名称是通过大写每个字母的第一个字母生成的 下划线后面的单词,删除所有下划线,然后添加 '绑定'到名称。因此,activity_main.xml将导致a 类叫ActivityMainBinding。 要在您的代码中关联此自动生成的绑定类,您 调用DataBindingUtil的setContentView
setContentView(R.layout.activity_main); final Button button1 = (Button)findViewById(R.id.button1); button.setOnClickListener(...);
在上面的代码段中,您会注意到我们可以访问 updateButton Button直接。数据中包含“@ + id”的所有视图 绑定布局自动分配给的最终字段 正确的类型。因此,为布局Button创建了Button updateButton 使用'@ + id / updateButton',并为其创建TextView textView1 id / text_view1 TextView。
它似乎不会干扰现有的视图,例如非数据绑定/硬编码的TextView onClick处理仍然无需其他代码更改。