putStr, putStrLnなどをすぐコンソールに出力したいなら
hFlush stdout する。
具体的には
putStr "こんな感じ"
hFlush stdout
開発中は結構 ghci でやってるので気づかないことが多いのだけれど、
いざコンパイルして動作確認するとあれ?となるようだ
<$>が最近使えるようになってきた。
yesodでhtmlエスケープをoffにする
用途は画像を埋め込んだりとか?
hamletの変数展開に手を加える
let text = "<img src=\"http~\"" alt=\"~\"/>" #{preEscapedToMarkup text}
hatenaでコードを埋め込む書き方を毎回ググってるなぁ
macでhaskell-giをHello, world
公式手順にはstackを使ったものは記載が無いようだったので補足的な
macOS Mojave
10.14.2
・gtk install
brew install gobject-introspection gtk+ gtk+3
・PKG_CONFIG_PATH
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/Cellar/libffi/3.2.1/lib/pkgconfig
・packeage.yaml
dependencies: - base >= 4.7 && < 5 - haskell-gi-base - gi-gtk
・stack.yaml
resolver: nightly-2019-07-21
※ 現状の最新である、lts-13.29 だとコンパイルエラーが発生したため
修正済みのバージョンを引き込むためにnightlyを使用
これでHello, Worldは通った
TabLayoutのタブ画像を通信して取得する
画面に表示されている範囲だけ画像を取ってきたい。
また、タブのスクロールに合わせて、適宜画像を取得する。
1. 画面に表示されている範囲のタブだけ画像を取ってくるメソッドを定義する
private void loadTabImage() { // mScrollBoundsはメンバ変数 this.getHitRect(mScrollBounds); for (int i = 0; i < getTabCount(); i++) { final Tab t = getTabAt(i); // setCustomViewを事前に行う必要がある final View view = t.getCustomView(); // タグの有無で画像ロード済みのタブかどうか判断している if (t.getTag() != null) { continue; } if(!view.getLocalVisibleRect(mScrollBounds)) { continue; } // 画像とってくる処理をここに書く } }
2. TabLayoutを継承したカスタムTabLayoutを作り、computeScrollをoverrideして、1のメソッドを呼ぶ
@Override public void computeScroll() { super.computeScroll(); loadTabImage(); }
一通りのOSで確認したが、これで動いているように見える。
200個ほどタブを定義しても平気だった。
targetSdkVersion28が必須へ
先年に実施された、AndroidのtargetSdkVersion26以上必須化ですが、
次はいつなんだ・・とそわそわしていたら、Android Developers Blogに記事が上がりました。
android-developers.googleblog.com
新規アプリは2019/08から、更新アプリは2019/11からみたいですね。
毎年この月って感じになるのかなー。
しかし去年、今年と続けてこの対応が大変だった・・・。
targetSdkVersionを10から26に!?できらぁ!・・え?FCMへの移行も同時に?・・・
率直に言って胃に穴があきそうでした。
こういうのはちゃんと計画してきちんと追随していきましょうねって教訓ですね。
まぁ僕がコントロールできる範囲ではないのですが。言っていくことは出来る。
flutterでWeb画面のタイトルタグの中身をjavascript経由で取得する
class WebViewScreen extends StatefulWidget { final String url; const WebViewScreen({Key key, this.url}) : super(key: key); @override _WebViewScreenState createState() => _WebViewScreenState(); } class _WebViewScreenState extends State<WebViewScreen> { FlutterWebviewPlugin _plugin = FlutterWebviewPlugin(); StreamSubscription _onStateChanged; String _title = ""; @override void initState() { super.initState(); _plugin.close(); _onStateChanged = _plugin.onStateChanged.listen((WebViewStateChanged state) async { if (state.type == WebViewState.finishLoad) { if (!mounted) { return; } // ココで取得している _title = await _plugin.evalJavascript("document.title"); setState(() { print(_title); }); } }); } @override void dispose() { _onStateChanged.cancel(); _plugin.close(); super.dispose(); } @override Widget build(BuildContext context) { return WebviewScaffold( url: widget.url, withJavascript: true, appBar: AppBar(title: Text(_title)), ); } }