当前位置: 首页 > 面试题库 >

屏幕旋转后恢复可流动的转换为实时数据

荀博
2023-03-14
问题内容

假设我有这样的活动:

public class TestActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final TextView countdown = new TextView(this);
        setContentView(countdown);

        ViewModelProviders.of(this)
                .get(TestViewModel.class)
                .getCountdown()
                .observe(this, countdown::setText);
    }
}

视图模型为:

class TestViewModel extends ViewModel {
    private final LiveData<String> countdown =
            LiveDataReactiveStreams.fromPublisher(
                    Flowable.concat(
                            Flowable.just("Falcon Heavy rocket will launch in..."),
                            Flowable.intervalRange(0, 10, 3, 1, TimeUnit.SECONDS)
                                    .map(x -> String.valueOf(10 - x)),
                            Flowable.timer(1, TimeUnit.SECONDS)
                                    .map(ignored -> "Lift off!")
                    )
            );

    LiveData<String> getCountdown() {
        return countdown;
    }
}

我想正确处理旋转,因此,如果用户在倒数计时为5时旋转设备,我希望旋转后的下一个值为5(如果第二个已经过去,则为4),只要在倒数应该实际出现的任何地方取。

如果火箭已经升空,我希望它在旋转后保持这种状态,我不希望倒计时再次开始。

此刻,LiveDataReactiveStreams暂停时取消订阅,恢复时进行新订阅,因此倒计时重新开始。

我猜想我应该在代码的RxJava部分中进行一些更改才能使其正常工作。有什么想法要改变吗?


问题答案:

由于斯维亚托斯Lebeckiy了在Android的美国时差通道谁指出,BehaviorSubjectBehaviorProcessor我,提出了关于如何解决此问题的想法。

我将视图模型更改为:

class TestViewModel extends ViewModel {

    private LiveData<String> countdown;

    LiveData<String> getCountdown() {
        if (countdown == null) {
            countdown = LiveDataReactiveStreams.fromPublisher(startCountdown());
        }
        return countdown;
    }

    private static Flowable<String> startCountdown() {
        final BehaviorProcessor<String> processor = BehaviorProcessor.create();
        Flowable.concat(
                Flowable.just("Falcon Heavy rocket will launch in..."),
                Flowable.intervalRange(0, 10, 3, 1, TimeUnit.SECONDS)
                        .map(x -> String.valueOf(10 - x)),
                Flowable.timer(1, TimeUnit.SECONDS)
                        .map(ignored -> "Lift off!")
        ).subscribe(processor);
        return processor;
    }
}

这样,我只能倒数一次开始计时,getCountdown并且BehaviorProcessor创建时startCountdown负责将最后一个随后发出的值传递给其订户(LiveData在这种情况下)。

由于LiveDataReactiveStreams需要a Flowable,因此使用a
BehaviorProcessor代替BehaviorSubject此处很方便。



 类似资料:
  • 在屏幕旋转后,虽然我在super.onCreate(null);,中传递null,但我得到了object返回的nullPointerException异常。我知道在传递savedInstanceState=null的同时必须销毁并重新创建活动,这意味着活动应该在旋转后开始,因为它是第一次开始,为什么在旋转后会出现此异常? onCreate()代码段,其中名为historyText的对象 Logca

  • 实现在竖屏的NavigationController中push一个横屏的UIViewController,模拟器测试兼容5.0、6.0系统。实现程序中手动旋转屏幕的效果。 [Code4App.com]

  • 本文向大家介绍Flutter 控制屏幕旋转的实现,包括了Flutter 控制屏幕旋转的实现的使用技巧和注意事项,需要的朋友参考一下 最近需要做个平板的项目,然后需要直接横屏,有2种实现方式。 1, 随着屏幕旋转,布局自动调整。做横竖屏适配 2,强制屏幕横屏,不随着屏幕去调整 第一种方式这里就不做说明了。代码做适配就可以。 下面说一下第二种实现方式 Flutter 自带方式 flutter 为我们提

  • 我制作了一个recyclerview网格,一旦用户按下按钮,它就会被api中的数据填满。旋转屏幕后,滚动位置会短暂恢复,然后再向上滚动到网格顶部。我使用本教程来保留我的滚动位置: 我还在本教程中尝试保存布局状态。 我的舱单条目是:

  • 我有一个应用程序小部件,当它更新时,获取具有与小部件匹配的维度的图像,并将该图像放入(通过)。它工作得很好。 但是对于支持主屏幕旋转的设备(我不是说基于设备方向的

  • 我想在模拟器上测试手机的旋转,我看到我们必须使用CtrlF11的所有地方,但它只旋转模拟器的图像,不会启动配置更改事件或重新绘制活动。 下面是我用CtrlF11得到的: 那么,我必须用什么来模拟真实的旋转呢?