39

我一直在寻找如何做到这一点的 KISS 示例,虽然它们看起来(而且我已经全部完成了!)很简单,但我仍然无法理解这个概念。我指的是自定义侦听器(不扩展任何东西的侦听器)...特别是为布尔变量创建一个侦听器,以便我可以在其值更改时触发一些方法。

这是我尝试过的一个例子: android how to make listener to a custom variable?

如果有人有时间用简单的英语解释自定义侦听器及其工作原理,那将不胜感激。我希望一旦我确切地了解了监听器是如何被通知更改的,那么我将能够创建自己的并了解该死的东西是如何工作的。这让我头疼......提前谢谢

这是我现在的位置:

public class ChangeListener {
    boolean boo = false;

    public ChangeListener(boolean b){
        boo = b;
    }

    private listener l = null;

    public interface listener{
        public void onChange(boolean b);
    }

    public void setChangeListener(listener mListener){
        l = mListener;
    }

    public void somethingChanged(){
        if(l != null){
            l.onChange(boo);
        }
    }


}

这是我的主要活动的快照:

public class Main extends Activity implements ChangeListener.listener{
    private ChangeListener listener;
    private boolean boo = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        listener = new ChangeListener(boo);
        listener.setChangeListener(this);
        listener.somethingChanged();

    }

    @Override
    public void onChange(boolean b) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "REST = "+b, Toast.LENGTH_SHORT).show();
    }


}

现在,当 Activity 开始时,Toast 会显示 boo 的状态……太棒了。问题是这只发生在 onCreate 中,这是有道理的,因为 .somethingChanged 被放置在那里。我想要的是每次 boo 从 false 更改为 true 以及 true 更改为 false 时生成 Toast,无论它是否在 onCreate 内。IE:

  • 单击一个按钮
  • 导致 boo 从 false 变为 true
  • 侦听器接收更改并运行 onChange 中的任何内容

我知道我可以只使用按钮 actionListener 来做到这一点,但如果可能的话,我想远离这个,目前我开始认为这是不可能的。

任何见解将不胜感激。提前致谢!

4

2 回答 2

40

您将变量包装在自定义类中,这样唯一的访问函数也会触发侦听器。因此,翻转开关的唯一方法是通过切换和调用侦听器的函数。

public class BooVariable {
    private boolean boo = false;
    private ChangeListener listener;

    public boolean isBoo() {
        return boo;
    }

    public void setBoo(boolean boo) {
        this.boo = boo;
        if (listener != null) listener.onChange();
    }

    public ChangeListener getListener() {
        return listener;
    }

    public void setListener(ChangeListener listener) {
        this.listener = listener;
    }

    public interface ChangeListener {
        void onChange();
    }
}

要监视更改,您需要实现 BooVariable.ChangeListener,然后将“this”的副本传递给 BooVariable 类,然后当您更改它调用 onChange 的变量时。

另外,请记住,您可以只内联代码而不是直接扩展:

BooVariable bv = new BooVariable();
bv.setListener(new BooVariable.ChangeListener() {
    @Override
    public void onChange() {
        Toast.makeText(MainActivity.this,"blah", Toast.LENGTH_LONG).show();
     }
});

PS。toast 必须从 UI 线程调用,因此如果要在不同线程中更改变量,则需要切换 Looper。不过,这可能不会出现。

于 2016-08-18T00:41:35.963 回答
27

现在有一个更简单的解决方案。只需将变量包装在LiveData中,特别是 MutableLiveData。

Java版

MutableLiveData<String> listen = new MutableLiveData<>();

listen.setValue("Changed value"); //Initilize with a value

listen.observe(context,new Observer<String>() {
    @Override
    public void onChanged(String changedValue) {
        //Do something with the changed value
    }
});

Kotlin 版本

val listen : MutableLiveData<String> =  MutableLiveData<>()

listen.setValue("Changed value") //Initilize with a value

listen.observe(context, Observer {

    //Do something with the changed value -> it

})
于 2020-02-15T19:57:53.107 回答