web-dev-qa-db-ja.com

ネストされたレイアウトでAndroid DataBindingを設定する方法

Androidのデータバインディング機能について読んでいたところです。ネストされたレイアウトからビューをバインドしようとしていました。私のアクティビティはAndroidのデフォルトテンプレートであるDrawerMenuActivityであり、content_my_activityレイアウト内にactivity_my_activityレイアウトがネストされています。

自動生成されたバインディングクラスが3つあります。 MyActivityBindingAppBarMyActivityBindingおよびContentMyActivityBinding

以下のように3つのクラスすべてを初期化してみました。

MyActivity.Java

MyActivityBinding activityBinding;
AppBarMyActivityBinding appBarBinding;
ContentMyActivityBinding contentBinding;

protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    activityBinding = DataBindingUtils.setContentView(this, 
                               R.layout.activity_my_activity);
    appBarBinding = DataBindingUtils.setContentView(this, 
                               R.layout.app_bar_my_activity);
    contentBinding = DataBindingUtils.setContentView(this, 
                               R.layout.content_my_activity);

    setName();
}

private void setName(){
    contentBinding.setFirstName("Omkar");
}

ただし、RuntimeExceptionは次のようにスローされます。

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example, PID: 18305
Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.userInterface.activity.MyActivity}: Android.view.InflateException: Binary XML file line #35: Binary XML file line #27: Error inflating class fragment
    at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2426)
    at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2490)
    at Android.app.ActivityThread.access$900(ActivityThread.Java:154)
    at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1354)
    at Android.os.Handler.dispatchMessage(Handler.Java:102)
    at Android.os.Looper.loop(Looper.Java:148)
    at Android.app.ActivityThread.main(ActivityThread.Java:5443)
    at Java.lang.reflect.Method.invoke(Native Method)
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:728)
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618)
 Caused by: Android.view.InflateException: Binary XML file line #35: Binary XML file line #27: Error inflating class fragment
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:539)
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:423)
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:374)
    at Android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.Java:280)
    at Android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.Java:140)
    at Android.databinding.DataBindingUtil.setContentView(DataBindingUtil.Java:276)
    at com.example.userInterface.activity.MyActivity.onCreate(MyActivity.Java:88)
    at Android.app.Activity.performCreate(Activity.Java:6259)
    at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1130)
    at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2379)
    at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2490) 
    at Android.app.ActivityThread.access$900(ActivityThread.Java:154) 
    at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1354) 
    at Android.os.Handler.dispatchMessage(Handler.Java:102) 
    at Android.os.Looper.loop(Looper.Java:148) 
    at Android.app.ActivityThread.main(ActivityThread.Java:5443) 
    at Java.lang.reflect.Method.invoke(Native Method) 
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:728) 
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618) 
 Caused by: Android.view.InflateException: Binary XML file line #27: Error inflating class fragment
    at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:782)
    at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:704)
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:835)
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798)
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:838)
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798)
    at Android.view.LayoutInflater.parseInclude(LayoutInflater.Java:971)
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:831)
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798)
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:515)
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:423) 
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:374) 
    at Android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.Java:280) 
    at Android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.Java:140) 
    at Android.databinding.DataBindingUtil.setContentView(DataBindingUtil.Java:276) 
    at com.example.userInterface.activity.MyActivity.onCreate(MyActivity.Java:88) 
    at Android.app.Activity.performCreate(Activity.Java:6259) 
    at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1130) 
    at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2379) 
    at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2490) 
    at Android.app.ActivityThread.access$900(ActivityThread.Java:154) 
    at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1354) 
    at Android.os.Handler.dispatchMessage(Handler.Java:102) 
    at Android.os.Looper.loop(Looper.Java:148) 
    at Android.app.ActivityThread.main(ActivityThread.Java:5443) 
    at Java.lang.reflect.Method.invoke(Native Method) 
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:728) 
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618) 
 Caused by: Java.lang.IllegalArgumentException: Binary XML file line #27: Duplicate id 0x7f0e0081, tag null, or parent id 0xffffffff with another fragment for com.google.Android.gms.maps.SupportMapFragment
    at Android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.Java:2416)
    at Android.support.v4.app.FragmentController.onCreateView(FragmentController.Java:120)
    at Android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.Java:374)
    at Android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.Java:33)
    at Android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.Java:75)
    at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:754)
    at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:704) 
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:835) 
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798) 
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:838) 
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798) 
    at Android.view.LayoutInflater.parseInclude(LayoutInflater.Java:971) 
    at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:831) 
    at Android.view.LayoutInflater.rInflateChildren(LayoutInflater.Java:798) 
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:515) 
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:423) 
    at Android.view.LayoutInflater.inflate(LayoutInflater.Java:374) 
    at Android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.Java:280) 
    at Android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.Java:140) 
    at Android.databinding.DataBindingUtil.setContentView(DataBindingUtil.Java:276) 
    at com.example.userInterface.activity.MyActivity.onCreate(MyActivity.Java:88) 
    at Android.app.Activity.performCreate(Activity.Java:6259) 
    at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1130) 
    at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2379) 
    at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2490) 
    at Android.app.ActivityThread.access$900(ActivityThread.Java:154) 
    at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1354) 
    at Android.os.Handler.dispatchMessage(Handler.Java:102) 
    at Android.os.Looper.loop(Looper.Java:148) 
    at Android.app.ActivityThread.main(ActivityThread.Java:5443) 
    at Java.lang.reflect.Method.invoke(Native Method) 
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:728) 
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618) 

MyActivity.Javaクラスのcontent_my_activityからビューをバインドするにはどうすればよいですか?助けていただければ幸いです。

ありがとう。

10
Omkar

DataBindingUtils.setContentView()は、名前のとおりに実行します。現在のビューを指定されたパラメーターに設定します。全体像としてAppBarが必要だとは思いませんか?

それにもかかわらず、私はあなたがあなたのlayout_activity_main.xmlであなたのレイアウトをincludeすると仮定します。 George Mountは、この機能について ブログ全体 の投稿を書いています。コード例はこの投稿からのものです。

最初の例は、layout_activity_main.xml(または名前を付けたもの)で、AppBarContentなどを含めます。

hello_world.xml
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:orientation="vertical">

        <TextView
                Android:id="@+id/hello"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"/>
        <include
                Android:id="@+id/world1"
                layout="@layout/included_layout"/>
        <include
                Android:id="@+id/world2"
                layout="@layout/included_layout"/>
    </LinearLayout>
</layout>


included_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:id="@+id/world"/>
</layout>

使用するレイアウトが明確になったので、ActivityMainにジャンプし、DataBindingを初期化して、フィールドにアクセスする必要があります。

//This works if you have used a variable in your <data> tag and you have built your project afterwards, if you don't have an activity
HelloWorldBinding binding = HelloWorldBinding.inflate(getLayoutInflater());

 //if you have an activity, you can use setContentView from the DataBindingUtils. Don't forget to delete the generic setContentView
HelloWorldBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_my_activity);


//Once you have accomplished the above, you can access your data-bound fields like this:
binding.hello.setText(“Hello”);
binding.world1.world.setText(“First World”);
binding.world2.world.setText(“Second World”);

Idsに正しくアクセスするにはActivity<include>タグに設定することが重要です。

18
yennsarah

オブジェクトをXMLで渡すことができます...xmlns:bind名前空間が必要です(xmlns:appと同様)。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:bind="http://schemas.Android.com/apk/res-auto">

   <data>
       <variable name="user" type="com.example.User"/>
   </data>

   <LinearLayout
       Android:orientation="vertical"
       Android:layout_width="match_parent"
       Android:layout_height="match_parent">

       <include
           layout="@layout/name"
           bind:user="@{user}"/>

       <include
           layout="@layout/contact"
           bind:user="@{user}"/>

   </LinearLayout>

</layout>

例のソース: レイアウトとバインディング式

7
Martin Zeitler