2016-03-16 13 views
6

Ich habe eine CustomView-Klasse mit einem datengebundenen Layout, das eine Variable verwendet. In dem Layout, das das CustomView enthält, möchte ich ein Attribut in dem CustomView übergeben und CustomView dieses Attribut in seiner eigenen Bindung des Layouts übergeben. Hier ist, was ich habe:Erhalten Sie Bindung von Ansichtsklasse

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); 
} 
} 

Dieser stürzt versuchte die Bindung aus der Sicht zu extrahieren. Ist das überhaupt möglich? Hier ist der 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) 

Und wenn ich

DataBindingUtil.getBinding(inCustomView) 

zu

DataBindingUtil.bind(inCustomView) 

ändern dann bekomme ich diese:

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) 

Dies könnte bedeuten, dass das Layout Datei ist nicht für Datenbindung formatiert, b wie es ist. Es hat das Layoutelement und das Datenelement mit Variablen und allem.

+0

Können Sie Ihre Stack-Trace veröffentlichen? – Submersed

+0

Bereitgestellt, zusammen mit ein wenig mehr Info – KairisCharm

Antwort

15

Sie müssen die aufgeblähte Ansicht binden, um die Datenbindung zu erstellen. In Ihrem Beispiel binden Sie den Container des Layouts ein.

Sie können dies auf verschiedene Arten tun. Am einfachsten ist es im Rahmen der Inflation zu binden:

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); 
    } 
    ... 
} 

Sie wirklich kein bindendes Adapter benötigen, wenn Sie die Setter als Teil Ihrer benutzerdefinierten Ansicht nicht wollen. In diesem Fall müssen Sie noch eine Möglichkeit, die Bindung zu bekommen, so dass Sie so etwas wie dies hinzufügen müssen:

public CustomViewBinding getBinding() { return mBinding; } 

, so dass Ihre Bindung Adapter funktionieren.

Wenn Sie wissen, dass die Inhalte Linearlayout alle aus der aufgeblasenen Ansicht sein werden, können Sie ein verbindliches Adapter wie folgt verwenden:

@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); 
} 

Wenn Ihre benutzerdefinierte Ansicht nicht sehr üblich ist, können Sie einfach direkt umfasst Ihr Layout:

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

Sie wäre natürlich, hat das Linearlayout in die custom_view.xml zu bewegen.

+0

Hey @George können Sie beschreiben, wie CustomViewBinding-Klasse generiert? – Ajay

+0

Angenommen, ich habe CustomViewPager-Klasse, also sollte ich ein XML schreiben müssen, um auch CustomViewPagerBinding-Klasse zu generieren? – Ajay

+0

Ignoriere diese Nachricht Ich habe dieses Problem gelöst, indem ich extra XML für CustomViewPager gemacht habe danke :). – Ajay