Привязка данных: привязать один метод от слушателя к нескольким методам

Члены группы Android UI Toolkit Йигит Бояр и Джордж Маунт рассказали о привязке данных< /а>. В видео на 13:41 Джордж Маунт говорит об этом

Вы также можете использовать некоторые странные слушатели, такие как onTextChanged. У TextWatcher есть три метода, но всех волнует только onTextChanged, верно? Вы можете получить доступ только к одному из них, если хотите, или ко всем сразу."

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

Он как будто говорил, что вместо обычного addTextChangedListener, который выглядит примерно так

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

мы могли бы просто сделать это

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

Класс обработчиков

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

Код работает в этом случае, но, похоже, он не работает в других случаях, когда у слушателя есть несколько методов, таких как ViewPager addOnPageChangeListener. Например это не работает

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

и класс обработчиков

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

Проект выдает эту ошибку при попытке построить

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 ****

Теперь я немного запутался, потому что оказалось, что EditText на самом деле имеет унаследованный onTextChanged, к которому библиотека привязки данных также может привязать android:onTextChanged="@{handlers::onTextChanged}".

Итак, мой вопрос в том, что на самом деле возможно привязываться к одному методу прослушивания, и я что-то упускаю, или Джордж Маунт сделал ошибку в своем выступлении?


person Olumide    schedule 30.08.2016    source источник


Ответы (1)


Будем надеяться, что это не было ошибкой в ​​разговоре :-)

Похоже, мы не реализовали это для ViewPager. Реализация не слишком сложная. Есть хитрость — вы должны объявить один интерфейс для каждого метода сопоставления.

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

Затем необходимо создать адаптер привязки для событий:

@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);
    }
}
person George Mount    schedule 30.08.2016
comment
Потрясающий! Ответ прямо из первых уст :) - person Olumide; 31.08.2016
comment
Что такое R.id.viewPagerListener? - person makovkastar; 29.06.2018