Flutter: архитектура BLOC

Основная идея данной архитектуры — отделить отрисовку от логики. Побочная возможность — еще один способ изменения данных виджета из другого виджета, без использования StreamController (ну на самом деле он таки используется но «внутри») и передергивания SetState

Итак, для использования нужно в pubspec.yaml добавить:

» Читать далее

Raspberri PI: прием и передача сигналов на частоте 433mhz

На даче у меня управление батареями построено на реле Sonoff R3 DIY, которые включаются-выключаются при помощи WiFi. Это было моей ошибкой — управление получилось не очень стабильным. Реле имеют свойство периодически «отваливаться», из-за того что сигнал от роутера слабоват и весь дом покрывает с трудом. Решил освоить управление реле при помощи приёмопередатчиков 433mhz. Приём-передача по слухам гораздо стабильнее. Да и пультики-брелки можно будет прикрутить таким образом для управления уличным освещением. Приятно будет — подъезжаешь вечером на машине и шарахаться в темноте не нужно — с пульта включил свет. Плюс бонусом хочу на первый этаж поставить arduino с приёмником, и часть функционала с raspberry перекинуть на неё, т.к. тупо пинов уже не хватает к малинке.

» Читать далее

Dart: секунды в строку вида hh:mm:ss

Задача: преобразовать и отобразить секунды в строку часы-минуты-секунды

Решение:

  String TimeLeft(diff){
    var timestamp = diff.floor();
    var hours = (timestamp / 60 / 60).floor();
    var minutes = ((timestamp / 60) - (hours * 60)).floor();
    var seconds = timestamp % 60;
    if (seconds<0){
      seconds=0;hours=0;minutes=0;
    }
    String hs=hours.toString();
    hs=hs.length>1?hs:"0"+hs;
    String ms=minutes.toString();
    ms=ms.length>1?ms:"0"+hs;
    String ss=seconds.toString();
    ss=ss.length>1?ss:"0"+ss;
    return "$hs:$ms:$ss";
  }

Бонусом тоже самое на javascript:

function TimeLeft(diff){    
    var timestamp = Math.floor(diff);
    var hours = Math.floor(timestamp / 60 / 60);
    var minutes = Math.floor(timestamp / 60) - (hours * 60);
    var seconds = timestamp % 60;        
    if (seconds<0){seconds=0;hours=0;minutes=0;} 
    h=("0"+hours).slice(-2);
    m=("0"+minutes).slice(-2);
    s=("0"+seconds).slice(-2);
};

Flutter: использование радиокнопок

Обычно радиокнопки во Flutter обертываю виджетом ListTile. Однако в этом случае получаются слишком большие отступы между кнопками, которые обычными средствами не убираются. В моем варианте, кнопки размещаются просто в Row строке:

enum ChangingTime {t30a,t30,t60,t90,t120,t150,t180}
...
ChangingTime? _chtime = ChangingTime.t30a;
...
Container RadioLine(String title,ChangingTime rvalue){
    return
    Container(
      padding: const EdgeInsets.only(bottom: 0,left: 0,right: 0,top: 0),
      height: 20,
      child:
        Row(
          children: [
            Expanded(
                child: Padding(
                  padding: const EdgeInsets.only(bottom: 0,left: 8,right: 8,top: 0),
                  child: Text(title),
                )
            ),
            Radio<ChangingTime>(
              value: rvalue,
              groupValue: _chtime,
              onChanged: (ChangingTime? value) {
                setState(() {
                  _chtime = value;
                  print(value);
                });
              },
            ),
          ],
        )
      );
  }
...
...
RadioLine("30 минут с автопродлением",ChangingTime.t30a),
new Divider(),
RadioLine("30 минут",ChangingTime.t30),
new Divider(),
RadioLine("1 час",ChangingTime.t60),

Получается вполне приемлимое:

Одно но. В таком случае выбор кнопки будет только по щелчку по переключателю, а не по тексту. Как вариант можно попробовать RadioListTile, но с ним отступы до желаемого минимума мне убрать не удалось.

 RadioListTile RadioLine2(String title,ChangingTime rvalue){
    return
      RadioListTile<ChangingTime>(
        title:Text(
            title,
        ),
        dense: true,
        value: rvalue,
        groupValue: _chtime,
        visualDensity: VisualDensity(
          horizontal: VisualDensity.minimumDensity,
          vertical: VisualDensity.minimumDensity,
        ),
        controlAffinity: ListTileControlAffinity.trailing,
        onChanged: (ChangingTime? value) {
            setState(() {
                _chtime = value;
                print(value);
            });
        },
      );
  }
1 50 51 52 53 54 300