从视图类获取绑定 [英] Get binding from view class

查看:592
本文介绍了从视图类获取绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有数据绑定布局的CustomView类,它接受一个变量。在包含CustomView的布局中,我想将一个属性传递给CustomView,并将该CustomView传递到其自己的布局的绑定中。这是我有的:

  public class CustomView extends LinearLayout 
{
public CustomView(Context inContext,AttributeSet inAttrs)
{
super(inContext,inAttrs);

inflate(inContext,R.layout.custom_view,null);
}



@BindingAdapter({app:variable})
public static void SetVariable(CustomView inCustomView,VariableType inMyVariable)
{
CustomViewBinding binding = DataBindingUtil.getBinding(inCustomView);

binding.setMyVariable(inMyVariable);
}
}

这个尝试从视图中提取绑定会崩溃。这是甚么可能吗?这是堆栈跟踪:

  java.lang.NullPointerException:尝试调用虚方法void void xxx.databinding.CustomViewBinding.setVariableType (xxx.VariableType)'on a null object reference 
at xxx.CustomView.SetDynamicList(CustomView.java:32)
at xxx.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116)
at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350)
在android.databinding.ViewDataBinding $ 6.run(ViewDataBinding.java:167)
在android.databinding.ViewDataBinding $ 7.doFrame(ViewDataBinding。 java:233)
在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:856)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer .java:603)
at android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
在android.app.ActivityThread.main(ActivityThread.java:5417)
在java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller。 run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

如果我更改

  DataBindingUtil.getBinding(inCustomView)

to

  DataBindingUtil。 bind(inCustomView)

然后我得到这个:

  java.lang.IllegalArgumentException:View不是绑定布局
在android.databinding.DataBindingUtil.bind(DataBindingUtil.java:166)
在android.databinding.DataBindingUtil.bind(DataBindingUtil.java:140)
在xxx.CustomView.SetDynamicList(CustomView.java:30 )
- at xxx.databinding.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116)
at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350)
at android.databinding.ViewDataBinding $ 6.run(ViewDataBinding.java:167)
在android.databinding.ViewDataBinding $ 7.doFrame(ViewDataBinding.jav a:233)
在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:856)
在android.view.Choreographer.doCallbacks(Choreographer.java:670)
在android .view.Choreographer.doFrame(Choreographer.java:603)
在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:844)
在android.os.Handler.handleCallback(Handler.java :739)
在android.os.Handler.dispatchMessage(Handler.java:95)
在android.os.Looper.loop(Loope r.java:148)
在android.app.ActivityThread.main(ActivityThread.java:5417)
在java.lang.reflect.Method.invoke(本机方法)
在com。 android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

这可能意味着布局文件未被格式化为数据绑定,但它是。它有布局元素,数据元素与变量和一切。

解决方案

您必须绑定膨胀的视图创建数据捆绑。在您的示例中,您将绑定布局的容器



您可以通过多种方式执行此操作。最简单的方法是将它作为通货膨胀的一部分来绑定:

  public class CustomView extends LinearLayout 
{
CustomViewBinding mBinding;
public CustomView(Context inContext,AttributeSet inAttrs)
{
super(inContext,inAttrs);
LayoutInflater inflater = LayoutInflater.from(inContext);
//我假设你想要膨胀到这个ViewGroup
mBinding = CustomViewBinding.inflate(inflater,this,true);
}

public void setVariable(CustomView inCustomView,VariableType inMyVariable){
mBinding.setVariable(inMyVariable);
}
...
}

你不真的需要一个绑定适配器,除非你不希望设置器作为自定义视图的一部分。在这种情况下,您仍然需要一种方式来获取绑定,因此您需要添加如下内容:

  public CustomViewBinding getBinding(){return mBinding; 

以便您的绑定适配器工作。



如果您知道LinearLayout内容将全部来自充气视图,您可以使用如下所示的绑定适配器:

  @BindingAdapter({app:variable})
public static void setVariable(CustomView inCustomView,VariableType inMyVariable)
{
if(inCustomView.getChildCount()== 0){
返回;
}
查看boundView = inCustomView.getChildAt(0);
CustomViewBinding binding = DataBindingUtil.getBinding(boundView);

binding.setMyVariable(inMyVariable);
}

如果您的自定义视图不是很自定义,您可以简单地包含布局直接:

 < include layout =@ layout / custom_viewapp:variable =@ {myVariableValue}/> 

当然,您必须将LinearLayout移动到custom_view.xml中。


I have a CustomView class with a databound layout that takes a variable. In the layout that contains the CustomView, I want to pass an attribute into the CustomView, and have that CustomView pass that attribute into its own layout's binding. Here's what I have:

public class CustomView extends LinearLayout
{
public CustomView(Context inContext, AttributeSet inAttrs)
{
    super(inContext, inAttrs);

    inflate(inContext, R.layout.custom_view, null);
}



@BindingAdapter({"app:variable"})
public static void SetVariable(CustomView inCustomView, VariableType inMyVariable)
{
    CustomViewBinding binding = DataBindingUtil.getBinding(inCustomView);

    binding.setMyVariable(inMyVariable);
}
}

This crashes trying to extract the binding from the view. Is this even possible? Here is the stack trace:

java.lang.NullPointerException: Attempt to invoke virtual method 'void xxx.databinding.CustomViewBinding.setVariableType(xxx.VariableType)' on a null object reference
                                                                            at xxx.CustomView.SetDynamicList(CustomView.java:32)
                                                                            at xxx.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116)
                                                                            at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350)
                                                                            at android.databinding.ViewDataBinding$6.run(ViewDataBinding.java:167)
                                                                            at android.databinding.ViewDataBinding$7.doFrame(ViewDataBinding.java:233)
                                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856)
                                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                                            at android.view.Choreographer.doFrame(Choreographer.java:603)
                                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                                            at android.os.Handler.handleCallback(Handler.java:739)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

And if I change

DataBindingUtil.getBinding(inCustomView)

to

DataBindingUtil.bind(inCustomView)

then I get this:

java.lang.IllegalArgumentException: View is not a binding layout
                                                                            at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:166)
                                                                            at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:140)
                                                                            at xxx.CustomView.SetDynamicList(CustomView.java:30)
                    -                                                        at xxx.databinding.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116)
                                                                            at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350)
                                                                            at android.databinding.ViewDataBinding$6.run(ViewDataBinding.java:167)
                                                                            at android.databinding.ViewDataBinding$7.doFrame(ViewDataBinding.java:233)
                                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856)
                                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                                            at android.view.Choreographer.doFrame(Choreographer.java:603)
                                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                                            at android.os.Handler.handleCallback(Handler.java:739)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

This might imply that the layout file is not formatted for databinding, but it is. It has the layout element, and the data element with variables and everything.

解决方案

You must bind the inflated view to create the data binding. In your example, you're binding the container of the layout.

You can do this in several ways. The easiest is to bind it as part of inflation:

public class CustomView extends LinearLayout
{
  CustomViewBinding mBinding;
  public CustomView(Context inContext, AttributeSet inAttrs)
  {
    super(inContext, inAttrs);
    LayoutInflater inflater = LayoutInflater.from(inContext);
    // I assume you want it inflated into this ViewGroup
    mBinding = CustomViewBinding.inflate(inflater, this, true);
  }

  public void setVariable(CustomView inCustomView, VariableType inMyVariable) {
    mBinding.setVariable(inMyVariable);
  }
  ...
}

You don't really need a binding adapter unless you don't want the setter as part of your custom view. In that case, you'll still need a way to get the binding, so you'll need to add something like this:

public CustomViewBinding getBinding() { return mBinding; }

so that your binding adapter works.

If you know that the LinearLayout contents are all going to be from the inflated view, you can use a binding adapter like this:

@BindingAdapter({"app:variable"})
public static void setVariable(CustomView inCustomView, VariableType inMyVariable)
{
    if (inCustomView.getChildCount() == 0) {
      return;
    }
    View boundView = inCustomView.getChildAt(0);
    CustomViewBinding binding = DataBindingUtil.getBinding(boundView);

    binding.setMyVariable(inMyVariable);
}

If your custom view isn't very custom, you can simply include your layout directly:

<include layout="@layout/custom_view" app:variable="@{myVariableValue}"/>

You would, of course, have to move the LinearLayout into the custom_view.xml.

这篇关于从视图类获取绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆