【问题标题】:Databinding: Bind single method from listener with multiple methods数据绑定:将来自侦听器的单个方法与多个方法绑定
【发布时间】:2017-01-06 16:17:26
【问题描述】:

Android UI Toolkit 团队的 Yigit Boyar 和 George Mount 成员提供了talk on databinding。在 13:41 的视频中,George Mount 这么说

你也可以做一些奇怪的监听器,比如 onTextChanged。 TextWatcher上面有3个方法,但大家只关心 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"/>

和 Handlers 类

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}" 绑定到该方法。

所以我的问题是,实际上是否可以绑定到单个侦听器方法而我遗漏了一些东西,或者 George Mount 在他的演讲中犯了错误?

【问题讨论】:

    标签: android data-binding android-databinding


    【解决方案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);
        }
    }
    

    【讨论】:

    • 太棒了!直接从马的嘴里回答:)
    • 什么是 R.id.viewPagerListener?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    相关资源
    最近更新 更多