2015-09-04 8 views
14

Sto tentando di associare un evento a una visualizzazione personalizzata con la nuova libreria di associazione dei dati Android, ma ho riscontrato un problema.Associazioni dati con listener personalizzati in visualizzazione personalizzata

Ecco la parte rilevante della mia vista personalizzata:

public class SuperCustomView extends FrameLayout { 
    private OnToggleListener mToggleListener; 

    public interface OnToggleListener { 
     void onToggle(boolean switchPosition); 
    } 

    public void setOnToggleListener(OnToggleListener listener) { 
     mToggleListener = listener; 
    } 
    .../... 
} 

Sto cercando di utilizzare questa visualizzazione personalizzata e legare l'evento onToggle con il seguente:

<data> 
    <variable 
     name="controller" 
     type="com.xxx.BlopController"/> 
</data> 

<com.company.views.SuperCustomView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:onToggle="@{controller.toggleStrokeLimitation}" 
     app:custom_title="Blah" 
     app:custom_summary="Bloh" 
     app:custom_widget="toggle"/> 

Dove toggleStrokeLimitation è un metodo sul controller:

public void toggleStrokeLimitation(boolean switchPosition) { 
    maxStrokeEnabled.set(switchPosition); 
} 

Ho questo errore o quando si compila:

> java.lang.RuntimeException: Found data binding errors. 
****/ data binding error ****msg:Cannot find the setter for attribute 'app:onToggle' with parameter type java.lang.Object. file:/path/to/androidapp/app/src/main/res/layout/fragment_stroke.xml loc:36:35 - 36:67 ****\ data binding error **** 

ho provato ad usare android:onToggle invece di app:onToggle ma ottenere lo stesso errore.

Durante la lettura dello binding events section of the doc, mi sembra di poter collegare qualsiasi metodo dal controller all'evento onToggle.

Il framework avvolge i metodi controller.toggleStrokeLimitation in un SuperCustomView.OnToggleListener? Qualche suggerimento sul tipo di magia che si cela dietro lo esistente onClick fornito dal framework?

+0

Prova ad implementare setter personalizzato per l'attributo onToggle http://developer.android.com/tools/data-binding/guide.html#custom_setters e assicurati che controller.toggleStrokeLimitation sia di tipo OnToggleListener –

+0

Qual è il tipo di 'controller. toggleStrokeLimitation'?. Sembra che sia un 'Object' e il tuo setter si aspetta un' OnToggleListener' – yigit

+0

Hai ragione, potrei farlo ma voglio mappare l'evento ad un metodo personalizzato. Come spiegato in https://developer.android.com/tools/data-binding/guide.html#binding_events, modificherò la domanda con il mio ragionamento. – fstephany

risposta

17
@BindingMethods(@BindingMethod(type = SuperCustomView.class, attribute = "app:onToggle", method = "setOnToggleListener")) 
public class SuperCustomView extends FrameLayout { 
    private OnToggleListener mToggleListener; 

    public interface OnToggleListener { 
     void onToggle(boolean switchPosition); 
    } 

    public void setOnToggleListener(OnToggleListener listener) { 
     mToggleListener = listener; 
    } 
    .../... 
} 

mio trucco per testare codice era:

public void setOnToggleListener(final OnToggleListener listener) { 
    this.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      toggle = !toggle; 
      listener.onToggle(toggle); 
     } 
    }); 
} 

E sul mio oggetto controller:

public class MyController { 

    private Context context; 

    public MyController(Context context) { 
     this.context = context; 
    } 

    public void toggleStrokeLimitation(boolean switchPosition) { 
     Toast.makeText(context, "Toggle" + switchPosition, Toast.LENGTH_SHORT).show(); 
    } 
} 

Yeah !! ha funzionato

In alternativa è possibile utilizzare XML come:

<com.androidbolts.databindingsample.model.SuperCustomView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:onToggleListener="@{controller.toggleStrokeLimitation}" /> 

Ora non c'è bisogno di aggiungere @BindingMethods annotazione.

documentazione dice: "Some attributes have setters that don't match by name. For these methods, an attribute may be associated with the setter through BindingMethods annotation. This must be associated with a class and contains BindingMethod annotations, one for each renamed method. "

+0

Esattamente quello che stavo cercando :) – Shirane85

0

È non essere necessarioBindingMethods per ascoltare ascoltatori visualizzazione personalizzata se si definisce nome del metodo seguire formato bean Java correttamente. Ecco un esempio

classe CustomView

public class CustomView extends LinearLayout { 
    ... 
    private OnCustomViewListener onCustomViewListener; 

    ... 
    public void setOnCustomViewListener(OnCustomViewListener onCustomViewListener) { 
     this.onCustomViewListener = onCustomViewListener; 
    } 


    .... 
    public interface OnCustomViewListener { 
     void onCustomViewListenerMethod(int aNumber); 
    } 
} 

XML

<...CustomView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:onCustomViewListener="@{viewModel.viewModelListenerMethod}" // or use can use app:onCustomViewListener="@{viewModel::viewModelListenerMethod}" 
    /> 

ViewModel

public class ViewModel extends BaseObservable{ 

    public void viewModelListenerMethod(int aNumber){ 
     // handle listener here 
    } 
} 
Problemi correlati