C#
Xamarin.Forms

Xamarin.Forms(Android)ScrollViewの中にあるListViewをスクロールさせる

More than 3 years have passed since last update.


NestedScrollingEnabledを使います

ScrollViewの中にListViewを入れた場合

既定の動作ではListViewのスクロールが効かないようです

参考 stackoverflow:ListView inside ScrollView is not scrolling on Android

解決策としてNestedScrollingEnabledをtrueにすれば良いと書いてありました。

実際にtrueにしたらスクロールしてくれましたのでメモとして残しておきます。

以下のようなカスタムレンダラーを作成します。


C#

using Xamarin.Forms.Platform.Android;

using MyProject.Droid.Renderer;

[assembly: Xamarin.Forms.ExportRenderer(typeof(Xamarin.Forms.ListView), typeof(CustomListViewRenderer))]
namespace MyProject.Droid.Renderer
{
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);

this.Control.NestedScrollingEnabled = true;
}
}
}



おまけ:そもそもスクロールしないで全ての行を一覧表示したい場合

通常ListViewを使う場合はListViewがページの唯一のコンテンツになる場合がほとんどだと思います。

そのため、あえてスクロールをしないという選択肢は通常考えられないと思いますが、

上記の例のようにScrollViewの中にあるListViewなどの場合は違います。

ListViewのように要素を繰り返して表示したいが、

スクロールしないで一覧表示する場合はどうするのかというと、

ListViewを使うのをやめましょう。

ListViewはスクロール前提のビューです。

このような用途に使うべきではないと私は考えます。

ASP.NETのRepeaterコントロールみたいなものは無いかと調べていたら、

XLabsでそのまんまのビューがありました。

XLabs/Xamarin-Forms-Labs RepeaterView

使い方はListViewと同じです。


  • ItemTemplateにテンプレートを定義する。

  • ItemsSourceにコレクションをバインドする。

それでも無理やりListViewでやる方法もありますが多少工夫(※)が必要です。

やり方は全行数が表示できる高さをListViewのHeightRequestに設定するだけです。

例として1行の高さが30の場合のコードは下記のようになります。


C#

private ListView listView;

private List<object> listViewItems;
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
listView.HeightRequest = listViewItems.Count * 30;
}

※例えばヘッダーやフッターの高さなども考慮しないと表示しきれないです。