2016-03-16 25 views
6

Ho una classe CustomView con un layout di database che accetta una variabile. Nel layout che contiene CustomView, voglio passare un attributo a CustomView e fare in modo che CustomView passi tale attributo nel binding del proprio layout. Ecco cosa ho:Ottieni binding dalla classe di visualizzazione

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

Questo si blocca cercando di estrarre il legame dalla vista. È possibile? Ecco l'analisi dello stack:

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) 

E se cambio

DataBindingUtil.getBinding(inCustomView) 

a

DataBindingUtil.bind(inCustomView) 

allora ottengo questo:

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) 

Questo potrebbe implicare che il layout il file non è formattato per il databinding, b è così. Ha l'elemento di layout e l'elemento di dati con variabili e tutto.

+0

Puoi pubblicare la traccia dello stack? – Submersed

+0

Fornito, insieme ad altre informazioni – KairisCharm

risposta

15

È necessario associare la vista ingrandita per creare l'associazione dati. Nel tuo esempio, stai vincolando il contenitore del layout.

È possibile farlo in diversi modi. Il metodo più semplice è quello di legare come parte di inflazione:

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

Non avete davvero bisogno di un adattatore vincolante a meno che non si desidera che il setter come parte della vostra visualizzazione personalizzata. In tal caso, sarà ancora bisogno di un modo per ottenere il legame, quindi avrete bisogno di aggiungere qualcosa di simile:

public CustomViewBinding getBinding() { return mBinding; } 

in modo che i lavori di adattamento vincolanti.

Se si sa che il contenuto LinearLayout sono tutti andando essere dal punto di vista gonfiato, è possibile utilizzare un adattatore vincolante come questo:

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

Se la visualizzazione personalizzata non è molto personalizzato, si può semplicemente includere il layout direttamente:

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

Si potrebbe, ovviamente, deve spostare il LinearLayout nella custom_view.xml.

+0

Ehi @George puoi descrivere come viene generata la classe CustomViewBinding? – Ajay

+0

Supponiamo di avere una classe di CustomViewPager quindi dovrei scrivere un xml per questo anche per generare la classe CustomViewPagerBinding? – Ajay

+0

ignora questo messaggio Ho risolto questo problema rendendo extra xml per CustomViewPager grazie :). – Ajay