c# - How do I use Rx to iterate through a series of strings with pauses and fade ins and outs? -
my requirement take series of strings array starting first , after 5 seconds move next 1 whilst fading out , fading in next string using rx xaml in xamarin. can assume taking place on view model has 'message' property , 'messageopacity' property take text , decimal between 0 , 1 applicably. can assume have background scheduler , uischeduler setup.
i'm new rx become apparent , have got far far:
var messages = new[] { "welcome", "we settings things you", "this may take little while first time" }; observable.interval(timespan.fromseconds(5), scheduler.backgroundscheduler) .selectmany((long arg) => messages) .buffer(1, 1) .subscribeon(scheduler.uischeduler) .subscribe((obj) => { message = obj[0]; });
the above doesn't work, buffer isn't working how expected. instead fires 4 strings in rapid succession every 5 seconds rather stepping through each of strings.
what don't understand how step through each of strings in order every 'x seconds' in correct 'rx' fashion , (as bonus me!) how subsequently trigger observable each new message ramp , ramp down opacity 0 1 on each change.
the aim achieve 'windows 10' style screen when big update occurring or whilst user waiting long operation complete.
you can use zip operator coupled observable.interval give iterative string output want:
[fact] public void shoulditeratethroughstringseveryfiveseconds() { testscheduler scheduler = new testscheduler(); string[] messages = new[] { "welcome", "we settings things you", "this may take little while first time" }; var expected = new[] { reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(0).ticks, "welcome"), reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(5).ticks, "we settings things you"), reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(10).ticks, "this may take little while first time"), reactivetest.oncompleted<string>(reactivetest.subscribed + timespan.fromseconds(15).ticks) }; var actual = scheduler.start( // solution () => observable.zip( messages.toobservable(), observable.interval(timespan.fromseconds(5), scheduler).startwith(0), (text, time) => text), timespan.fromseconds(20).ticks ); assert.equal(expected, actual.messages.toarray()); }
edit: rather second observable opacity combine them this:
[fact] public void shoulditeratethroughstringseveryfivesecondsprovidingstringandopacity() { testscheduler scheduler = new testscheduler(); string[] messages = new[] { "welcome", "we settings things you", "this may take little while first time" }; var expected = new[] { reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(0).ticks, tuple.create("welcome", 0.0)), reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(5).ticks, tuple.create("we settings things you", 0.5)), reactivetest.onnext(reactivetest.subscribed + timespan.fromseconds(10).ticks, tuple.create("this may take little while first time", 1.0)), reactivetest.oncompleted<tuple<string, double>>(reactivetest.subscribed + timespan.fromseconds(15).ticks) }; var actual = scheduler.start( // solution () => observable .zip( messages.toobservable(), observable.interval(timespan.fromseconds(5), scheduler).startwith(0), (text, time) => text) .select((text, index) => tuple.create(text, convert.todouble(index) / convert.todouble(messages.length - 1))), timespan.fromseconds(20).ticks ); assert.equal(expected, actual.messages.toarray()); }
note opacity of first element 0 won't see it. you'll want change math (provide offset) scale opacity non-zero value one.
hope helps :0)
Comments
Post a Comment