2017-07-02 68 views
1

我遇到了數據綁定問題。我試圖包含一個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' 
} 

回答

0

在玩了一段時間後,我似乎找到了一個解決方案,那就是用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處理仍然可以在沒有其他代碼更改的情況下運行。