我有一个带有数据绑定布局的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: 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)
如果我改变了
DataBindingUtil.getBinding(inCustomView)
至
DataBindingUtil.bind(inCustomView)
然后我明白了:
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)
解决方法
您必须绑定膨胀视图以创建数据绑定.在您的示例中,您将绑定布局的容器.
您可以通过多种方式完成此操作.最容易的是将其作为通胀的一部分来约束:
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); } ... }
除非您不希望将setter作为自定义视图的一部分,否则您实际上不需要绑定适配器.在这种情况下,你仍然需要一种方法来获得绑定,所以你需要添加这样的东西:
public CustomViewBinding getBinding() { return mBinding; }
以便您的绑定适配器工作.
如果您知道LinearLayout内容全部来自膨胀视图,您可以使用如下的绑定适配器:
@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); }
<include layout="@layout/custom_view" app:variable="@{myVariableValue}"/>
当然,您必须将LinearLayout移动到custom_view.xml中.