在 Android 中使用 Observable

新手上路,请多包涵

我想实现一个 Navigation View ,其中许多片段完全取决于 MainActivity 中定义的值。我知道可以 使用 MainActivity 中定义的方法从其他 Fragments 访问 MainActivity 中的变量以获取 value ,但这里要注意的是 MainActivity 中变量的值可能会 更改(在 AsyncThread 上运行)。现在,我要么更改代码,以便我的片段根据 片段本身中的某些事件 _更新它们的值_,要么使用 SharedPreference 。但我不想使用 SharedPreferences,也不必多次不必要地检查值的变化。

我知道在 RxJS 中,我们使用异步运行并以类似于传送带的方式工作的 Observable 。通过 官方文档进行一些谷歌搜索:Observable 证实了我对 Android 中可用的类似内容的怀疑,但找不到任何适当的教程或关于如何实现它的解释。因此,我正在寻找一个简单的代码片段,它可能会阐明 Observable 在 Android 中的工作方式,以及它是否是异步的,以及它是否基于类似于它的 RxJS 实现。 (不,我不想要 RxJS 实现)

测试用例:

 MainActivity : int a, b (need observable for both variables)
Frag1 : int a1 , b1, a1changed(),b1changed()
Frag2 : int a2 , b2, a2Changed(), b2changed()

MainActivity 包含整数,其值在更改时应反映在 Fragment 中的相应整数中,并在注意到更改时为每个 Fragment 调用单独的函数。

原文由 Kaushik NP 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 992
1 个回答

这是一个简单的例子,有一个 Activity 和一个 Fragment 但它与其他片段相同。

首先,您需要创建一个代表您想要观察的值的类,在您的情况下它是一个简单的 int 所以创建一个包含这个的类 int 并且扩展 Observable (它实现了 Serializable 以简化活动和片段之间的交换):

 ...
import java.util.Observable;

public class ObservableInteger extends Observable implements Serializable {

    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
        this.setChanged();
        this.notifyObservers(value);
    }
}

然后在活动中使用这个可观察的int(活动布局包含一个 Button 和一个 FrameLayout 用于显示 Fragment ):

 public class MainActivity extends Activity {

    private ObservableInteger a;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create observable int
        a = new ObservableInteger();
        // Set a default value to it
        a.setValue(0);

        // Create frag1
        Frag1 frag1 = new Frag1();
        Bundle args = new Bundle();
        // Put observable int (That why ObservableInteger implements Serializable)
        args.putSerializable(Frag1.PARAM, a);
        frag1.setArguments(args);

        // Add frag1 on screen
        getFragmentManager().beginTransaction().add(R.id.container, frag1).commit();

        // Add a button to change value of a dynamically
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Set a new value in a
                a.setValue(a.getValue() + 1);
            }
        });
    }
}

最后,创建一个监听值变化的 Fragment

 ...
import java.util.Observer;

public class Frag1 extends Fragment {
    public static final String PARAM = "param";

    private ObservableInteger a1;
    private Observer a1Changed = new Observer() {
        @Override
        public void update(Observable o, Object newValue) {
            // a1 changed! (aka a changed)
            // newValue is the observable int value (it's the same as a1.getValue())
            Log.d(Frag1.class.getSimpleName(), "a1 has changed, new value:"+ (int) newValue);
        }
    };

    public Frag1() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            // Get ObservableInteger created in activity
            a1 = (ObservableInteger) getArguments().getSerializable(PARAM);
            // Add listener for value change
            a1.addObserver(a1Changed);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
}

我尝试将我的变量命名为与您的相同,希望对您有所帮助。

原文由 Gaëtan Maisse 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题