ぴーさんログ

だいたいXamarin.Formsのブログ

【Xamarin.Forms 2.1.0(プレビュー)】HasUnevenRows dynamic sizing support

ListView.HasUnevenRows = true の場合、Cellのサイズを動的に変更できるようになります。 Androidでは元々動的にサイズ変更されてましたが、今回の変更で Cell.ForceUpdateSize() を呼ぶとサイズが更新される仕様になります。

「プラットフォームによっては処理コストが高い」との事で、実際iOSで使うとサイズ更新への追従が遅いです。

サンプル

確認用のカスタムViewCellを作成、スライダーに連動してBoxViewの高さが変わります。 ルート要素であるStackLayoutのMeasureInvalidatedイベントに合わせて Cell.ForceUpdateSize() を呼ぶことでListViewのCellサイズが更新されます。

public class MyViewCell : ViewCell
{
    public MyViewCell()
    {
        var label = new Label();
        label.SetBinding(Label.TextProperty,
            ".", BindingMode.OneWay);
        
        var slider = new Slider {
            Maximum = 100,
            Minimum = 0,
            Value = 50,
        };

        var boxView = new BoxView {
            Color = Color.Blue,
            BindingContext = slider,
        };
        boxView.SetBinding(BoxView.HeightRequestProperty,
            "Value", BindingMode.OneWay);
            
        var stackLayout = new StackLayout {
            Children = {
                label,
                slider,
                boxView,
            },
        };
        
        // ここでListViewのCellサイズが更新される
        stackLayout.MeasureInvalidated +=
            (sender, e) => ForceUpdateSize();

        View = stackLayout;
    }
}

利用側のソース

// Appクラスのコンストラクタ
MainPage = new ContentPage {
    Content = new ListView {
        HasUnevenRows = true,
        ItemsSource = new [] {1, 2, 3, 4, 5, 6,},
        ItemTemplate = new DataTemplate(typeof(MyViewCell)),
    },
};

結果はこうなります。

f:id:ticktack623:20160125041954g:plain

セパレータの追従が遅くてBoxViewに埋まっていますね。自然に見せるためには一工夫が必要かも。

参考

Xamarin.Forms 2.1.0-pre2 Released - Xamarin Forums