kamulog

xamarin.formsのネタなど

CollectionView という Xamarin.Forms 向けの 縦以外のレイアウトに対応した ListView を公開しました。

以前 WrapLayout というカスタムレイアウトを含む AiForms.Layouts というライブラリを作成しました。これは、要素を水平方向に配置していき端まできたら折り返すというだけのものでした。そして現在は、FlexLayoutの登場によりその役割をほぼ終えています。

AiForms.Layouts では繰り返し要素を配置するコントロールとして、FlexLayoutやStackLayoutをItemTemplateに対応させたものもあります。

しかし、これらは実直に要素を物理的に生成して配置していくだけなので、要素が増えるとパフォーマンスが激しく低下するという問題がありました。

本来多くの要素を配置する場合は UICollectionView / RecyclerView を使用するべきで、そうなるとPlatform側でちゃんと対応させねばならないと思っていました。

SettingsView というものを作った時に UICollectionView / RecyclerView の実装方法を少しだけ覚えたので、それを生かしてちびちび作成したものが出来上がったので、この度nugetで公開しました。

前述の問題を解決した WrapLayout のListView対応版という風な捉え方で問題ないと思います。ただ現在のところ固定サイズのセルのみ対応です。 1種類だとあれなので、おまけとして水平方向ListView的なものも用意しています。

作成したもの

GitHub

github.com

nuget

www.nuget.org

概要

グリッド状に配置するListViewとしてGridCollectionView、水平方向のListViewとしてHCollectionViewを利用できます。

それぞれセルのネイティブのリサイクル機能とFormsのリサイクル機能(RecycleElement / RetainElement)に対応しています。

現在はプレリリース版です。

CollectionView 共通でできること

  • グループ化対応
  • Tap / LongTap Command指定可能
  • Touchしたときのフィードバックの色変更可能
  • Xamlでレイアウト可能

GridCollectionView でできること

  • 指定した幅で水平方向に並べていき、行幅を超えたら折り返し、アイテム間の余白を自動調整する (WrapLayoutのような挙動)
  • 指定した幅と指定した余白で水平方向に並べていき、行幅を超えたら折り返し行全体の中央に配置する (FlexLayoutのJustifyContent:Centerのような挙動)
  • 親要素幅を指定した個数で割ったサイズできっちり並べる (Gridのような挙動)
  • PullToRefresh対応 / アイコンカラー変更可能

HCollectionView (HolizontalCollectionView) でできること

  • 循環スクロール対応

できないこと

  • 可変サイズなアイテム
  • ColSpan的なやつ

Demo

youtu.be

画像の取り扱い

ListViewと同様に、これ自体には画像を上手に取り扱う機能はないため、FFImageLoading 等のライブラリを併用することを強く推奨します。

使い方

GitHubの ReadMe に詳しく書いていますので、そちらを参照してください。

https://github.com/muak/AiForms.CollectionView/blob/master/README-ja.md

今後の予定

  • 終端検知 – 続きを読む的なやつに対応できるように
  • ColSpan的なやつ
  • 成り行きサイズ対応

(ポエム)技術的なこと

SettingsView と同じく中身はそれぞれ以下の組み合わせで

  • iOS - UICollectionView / UICollectionViewFlowLayout
  • Android - RecyclerView / GridLayoutManager / LinearLayoutManager

それをFormsのListViewのサブクラスにくっつけてるだけのものです。

最大の問題は、iOSのViewCellに使われているNativeのコンテナがUITableViewCellで、 これがUICollectionViewでは使えないので、ViewCellをそのまま利用できないということでした。 最初はダミーのUITableViewを保持してリサイクルはそれにやらせてUITableViewCellのContentViewをUICollectionViewのContentViewに配置する という実装にしてたんですが、あまりにダサすぎるのでViewCell相当をContentCellというクラスに別途実装することにしました。 ただ、実装が進むとViewCellのプラットフォーム実装は縦向きListViewのために高さを内部でいじっていたりすることが判明して、それが結局邪魔するので どのみち個別実装するしかなかったと思います。

最近のFormsの進化は早めなので、きっとそのうち公式でもListViewの UICollectionView / RecyclerView 対応とレイアウト多様化も実装されるような気がします。 そうなったらまたこれも産廃になってしまいますが、それまでの間、もしよかったらご利用ください。