2016-08-30 1 views
8

Yigit Boyar und George Mount Mitglieder des Android UI Toolkit-Team gab eine talk on databinding. In dem Video um 13:41 George Mount sagt diesDatenbindung: Einzelne Methode aus Listener mit mehreren Methoden binden

Sie können auch einige der seltsamen Listener, wie onTextChanged. TextWatcher hat drei Methoden, aber alle interessieren sich nur für onTextChanged, oder? Sie können tatsächlich nur eine von ihnen zugreifen, wenn Sie wollen, oder alle von ihnen. "

<Button android:onTextChanged="@{handlers.textChanged}" …/> 

Er schien zu sagen, dass anstelle der üblichen addTextChangedListener Verfahren zur Verwendung, die wir

<EditText 
    android:onTextChanged="@{handlers::onTextChanged}" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

Handlers Klasse dieses so etwas wie dieses

editText.addTextChangedListener(new TextWatcher() { 
    @Override 
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} 

    @Override 
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
     //Do something 
    } 

    @Override 
    public void afterTextChanged(Editable editable) {} 
}); 

sieht einfach tun könnte

public class Handlers{ 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     //Do something 
    } 
} 

Der Code funktioniert in dieser Instanz, aber es scheint nicht in anderen Fällen zu funktionieren, wo der Listener mehrere Methoden wie ViewPager addOnPageChangeListener Methode hat. Zum Beispiel funktioniert das nicht

<android.support.v4.view.ViewPager 
    android:OnPageSelected="@{handlers::onPageSelected}" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

und die Handlers Klasse

public class Handlers{ 
    public void onPageSelected(int position) { 
     //Do something 
    } 
} 

Das Projekt diese Fehler ausspuckt, wenn

Error:Execution failed for task ':app:compileDebugJavaWithJavac'. 
> java.lang.RuntimeException: Found data binding errors. 
****/ data binding error ****msg:Could not resolve handlers::onPageSelected as a listener. 

****\ data binding error **** 

Ich bin ein wenig verwirrt jetzt zu bauen versucht, weil Es stellt sich heraus, dass EditText tatsächlich eine vererbte onTextChanged Methode hat, die die Datenbindungsbibliothek auch an android:onTextChanged="@{handlers::onTextChanged}" binden kann.

Also meine Frage ist, dass es tatsächlich möglich ist, an eine einzelne Listener-Methode zu binden und mir fehlt etwas, oder hat George Mount in seinem Vortrag einen Fehler gemacht?

Antwort

9

Hoffnung Lassen Sie uns, dass es nicht ein Fehler in dem Vortrag :-)

war es sieht aus wie wir es nicht umgesetzt haben für ViewPager. Die Implementierung ist nicht zu schwierig. Es gibt einen Trick - Sie müssen für jede passende Methode eine einzige Schnittstelle deklarieren.

public interface OnPageScrollStateChanged { 
    void onPageScrollStateChanged(int state); 
} 
public interface OnPageScrolled { 
    void onPageScrolled(int position, float offset, int offsetPixels); 
} 
public interface OnPageSelected { 
    void onPageSelected(int position); 
} 

Dann sollte die Bindung Adapter für die Ereignisse erstellt werden:

@BindingAdapter(value = {"android:onPageScrollStateChanged", 
         "android:onPageScrolled", 
         "android:onPageSelected"}, requireAll=false) 
public static void setViewPagerListeners(ViewPager view, 
     final OnPageScrollStateChanged scrollStateChanged, 
     final OnPageScrolled scrolled, 
     final OnPageSelected selected) { 
    OnPageChangeListener newListener = null; 
    if (scrollStateChanged != null || scrolled != null || selected != null) { 
     newListener = new OnPageChangeListener() { 
      @Override 
      public void onPageScrollStateChanged(int state) { 
       if (scrollStateChanged != null) { 
        scrollStateChanged.onPageScrollStateChanged(state); 
       } 
      } 
      // similar with the other two methods ... 
     }; 
    } 

    OnPageChangeListener oldListener = ListenerUtil.trackListener(view, 
     newListener, R.id.viewPagerListener); 
    if (oldListener != null) { 
     view.removeOnPageChangeListener(oldListener); 
    } 
    if (newListener != null) { 
     view.addOnPageChangeListener(newListener); 
    } 
} 
+0

Awesome! Antwort direkt aus dem Maul des Pferdes :) – Olumide

Verwandte Themen