LoginSignup
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-02-17

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;
}

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5