如何克服实施字符串资源数据绑定的问题

如何克服实施字符串资源数据绑定的问题

问题描述:

我遇到了数据绑定问题。我试图包含一个XML布局设置包括的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> 

而这按预期工作,与吐司显示的字符串资源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?

我已经通过Data Binding Library

阅读我打开数据绑定和拥有的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' 
} 

在玩了一段时间后,我似乎找到了一个解决方案,那就是用dataBindingUtilsetContentView方法来代替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); 
     .... 
    } 

的使用绑定的工作: -

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     final ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main); 
     .... 
    } 

我发现这个通过阅读这篇文章Android Authority - Data Binding in Android,通过Obaro Ogbo写的。有关提取物的存在: -

数据绑定活动

目前,我们有一个数据绑定能够在布局文件。 但是,要利用其数据绑定功能,我们必须以不同的方式加载它。

以前,你会加载您的布局是这样的:

setContentView(R.layout.activity_main); 
final Button button1 = (Button)findViewById(R.id.button1); 
button.setOnClickListener(...); 

随着数据绑定,绑定类是布局 文件自动生成。该类默认使用布局文件名进行命名。 默认名称是通过在下划线之后大写每个 字的首字母,删除所有下划线,并将 '绑定'添加到名称来生成的。因此,activity_main.xml将产生一个名为ActivityMainBinding的 类。 要在你的代码生成绑定类此自动关联,则 调用DataBindingUtil的的setContentView

final ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(
    this, R.layout.activity_main); 
activityMainBinding.updateButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     activityMainBinding.textView1.setText(R.string.text1b); 
    } 
}); 

在代码段中,你会发现,我们可以直接访问 updateButton按钮。数据 绑定布局中带有'@ + id'的所有视图都会自动分配到正确类型的最终字段 。因此按钮updateButton是为布局Button 使用'@ + id/updateButton'创建的,TextView textView1是为 id/text_view1 TextView创建的。

它似乎不会干扰现有视图,例如,非数据绑定/硬编码的TextView onClick处理仍然可以在没有其他代码更改的情况下运行。