ViewDataBinding getVariable?

时间:2016-06-02 12:01:50

标签: android android-databinding

两个主要问题是:

  • 为什么ViewDataBinding没有类似getVariable("variableName")的方法会查找变量并返回它,如果没有此名称的变量存在则为null。
  • 他们以任何方式/解决方法来实现这种行为吗?

所以更明确一点:如果我不知道我的ViewDataBinding的类型,是他们获取变量的方法还是我必须知道它的类型?

以下是它的实际工作方式:

  1. 我有一个名为 my_layout.xml 的布局:
  2. <layout>
        <data>
            <variable
                android:name="myVaribale"
                android:type="String"/>
            </variable>
        </data>
    
        <RelativeLayout
            android:id="@+id/root_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="@{myVariable}"/>
    
        </RelativeLayout>
    <layout>
    
    1. 我为ViewDataBinding

      的实例充气

      MyLayoutBinding binding = (MyLayoutBinding) DataBindingUtil.inflate(inflater, R.layout.my_layout, root, false);  

    2. 我可以通过调用适当的方法来获取它的变量:

      String myVariable = binding.getMyVariable(); 

    3. 这就是当我们知道ViewDataBinding的类型时如何获取变量。

      我的问题在于:

      让我们假设我有3个名为my_layout_1my_layout_2my_layout_3的布局,这3个布局被<layout>标记包围。 这3个布局也有相同的变量(myVariable)。

      以下是布局:

      my_layout_1

      <layout>
      
          <data>
              <variable
                  android:name="myVariable"
                  android:type="String"/>
              </variable>
          </data>
      
          <RelativeLayout
              android:id="@+id/root_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:text="@{myVariable}"
                  style="@style/my_style_1"/>
      
          </RelativeLayout>
      
      <layout>
      

      my_layout_2

      <layout>
      
          <data>
              <variable
                  android:name="myVariable"
                  android:type="String"/>
              </variable>
          </data>
      
          <RelativeLayout
              android:id="@+id/root_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:text="@{myVariable}"
                  style="@style/my_style_2"/>
      
          </RelativeLayout>
      
      <layout>
      

      my_layout_3

      <layout>
      
          <data>
              <variable
                  android:name="myVariable"
                  android:type="String"/>
              </variable>
          </data>
      
          <RelativeLayout
              android:id="@+id/root_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:text="@{myVariable}"
                  style="@style/my_style_3"/>
      
          </RelativeLayout>
      
      <layout>
      

      因此,不同的布局代表具有不同风格的文本(我知道它可以通过其他方式实现,但目标只是解释为什么我需要这个函数getVariable(variableName)

      现在想象一下,我得到了一个名为my_text_container的布局,它将随机包含3个布局中的一个。

      my_text_container

      <layout>
      
          <FrameLayout
              android:id="@+id/container"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
      
      <layout>
      

      所以我会通过做这样的事情来添加文本(再次,它只是为了演示目的):

      MyTextContainerBinding textContainerBinding = (MyTextContainerBinding) DataBindingUtil.inflate(inflater, R.layout.my_text_container, root, false);
      int textLayoutRes;
      int randomNumber = generateNumberBetween0and2();
      switch(randomNumber) {
          case 0: textLayoutRes = R.layout.my_layout_1;
              break;
          case 1: textLayoutRes = R.layout.my_layout_2;
              break;
          case 2: textLayoutRes = R.layout.my_layout_3;
              break;
      }
      textContainerBinding.getRoot().addView(DataBindingUtil.inflate(inflater, textLayoutRes, root, false));
      

      最后我想要检索myVariable,但我不知道它是否是布局1,2或3.基本上现在可以做的是使用instanceof运算符来检查它是否是输入MyLayoutBinding1MyLayoutBinding2MylayoutBinding3。但正如我所说,这个用例仅用于演示目的,我可以有999种不同的布局。

      所以我想做的是:

      ViewDataBinding myLayout = DataBindingUtil.getBinding(textContainerBinding.getRoot().getChildAt(0));
      String myVariable = myLayout.getVariable("myVariable");
      
      if(myVariable != null)
          Log.d(TAG, "myLayout was MylayoutBinding1 or myLayoutBinding2 or myLayoutBinding3");
      else
          Log.d(TAG, "mylayout was not one of the 3 layouts"); 
      

      对于这个(非常)长的帖子感到抱歉,但感谢您阅读它以及将来的任何答案!

2 个答案:

答案 0 :(得分:1)

我不确定我是否得到它,但我所做的是在布局中声明一个变量,如下所示:

<data>
    <variable
        name="variableName"
        type="bla.bla.VariableType"/>
</data>

然后首先在onCreate中获得布局绑定:

binding = DataBindingUtil.inflate(inflater, R.layout.your_layout, container, false);

然后你应该在代码中将变量发送到布局,如:

binding.setVariableName(yourVariable);

然后你可以检索它:

binding.getVariableName();

答案 1 :(得分:0)

  1. 为什么ViewDataBinding没有getMethodVariable?

    考虑没有绑定的正常场景。你有一个文本容器布局。如何在正常活动中包含其中的另一个布局。

  2. my_text_container.xml :(正常活动)

    使用R.layout.my_text_container将此布局扩展到您的java文件,您不会将每个布局扩展到不同的视图以访问其中的textview。只需一次充气就可以了。

    因此,在DataBinding中也遵循相同的过程,当您使用include标记时,相应的字段将位于MyTextContainerLayoutBinding中。 您不必使用MyLayout1Binding,MyLayout2Binding这样的活动名称一次又一次地对它进行充气。这就是为什么变量名在这里变得不必要了。

    我认为在Binding中添加可变性对于您只想显示数据的地方会更有帮助。来自多个包含布局的一个模型的数据,对Listviews,Recyclerviews(布局使用模型中的数据)更有帮助。

    如果要将一个布局包含在另一个布局中,则不能为不同的布局提供不同的类型。(请记住,这会将布局绑定到单个名称(在容器容器中为parent_activity))。

    例如:

    <强> UserProfileModel:

    public class UserProfileModel {
    
        String firstname;
        String lastname;
    
        public String getLastname() {
            return lastname;
        }
    
        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
    
        public String getFirstname() {
            return firstname;
        }
    
        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }
    

    }

    <强> my_layout_1.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="user"
                 type="com.hourglass.lingaraj.bindingusingvariables.UserProfileModel" />
        </data>
        <LinearLayout
            android:orientation="vertical"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
    <TextView
        android:visibility="visible"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.firstname}"
        style="@style/mystyle_1"/>
    
    
            <include layout ="@layout/my_layout_2"
                app:user="@{user}" />
    </LinearLayout>
    </layout>
    

    <强> my_layout_2.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <layout  xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
            <variable
                name="user"
                type="com.hourglass.lingaraj.bindingusingvariables.UserProfileModel"/>
        </data>
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:visibility="visible"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.lastname}"
                style="@style/mystyle_2"/>
    
        </RelativeLayout>
    </layout>
    

    <强> MainActivity.java:

    public class MainActivity extends AppCompatActivity {
    
        MyLayout1Binding layout_binding;
        UserProfileModel data_model;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.my_layout_1);
            data_model  = new UserProfileModel();
            data_model.setFirstname("Lingaraj");
            data_model.setLastname("Sankaravelu");
    
            layout_binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.my_layout_1,null,false);
            layout_binding = DataBindingUtil.setContentView(this,R.layout.my_layout_1);
            layout_binding.setUser(data_model);
            }
    }
    

    如您所见,我们只使用一个模型在包含的布局中填充数据。因此,无需获取变量名称来验证加载哪个模型,因为它已绑定到单个布局。

    1. 没有解决方法来实现这一点,我尝试过这些。
    2. 所以我的答案是否是你不能从绑定中获取变量名

      <强>参考。

      No More findViewById

      Android Data Binding: That Thing

      Android Data Binding: Adding some variability

      Android Data Binding: Express Yourself