読者です 読者をやめる 読者になる 読者になる

Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

Xamarin.Forms の Opacty と IsVisible の違い?

Xamarin Xamarin.Forms

こんにちは。エクセルソフトの田淵です。

Twitter でちょっと気になるポストがありましたので調べてみました。

Visible は遅すぎて使えない

ふむ? @yu_ka1984 さんの仰っている動作と合ってるかは分かりませんが、以下のようなコードで試してみました。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Xamarin.Forms;

namespace VisibleOpacityPerformance
{
    public class App : Application
    {
        Stopwatch sw = new Stopwatch();
        Grid grid = new ImageGrid(10, 10);

        public App()
        {

            // The root page of your application
            MainPage = new ContentPage
            {

                Content = new StackLayout
                {
                    Padding = new Thickness(5, Device.OnPlatform(20, 0, 0), 5, 0),
                    Children = {
                        new Button {
                            Text = "Change Opacity",
                            Command = new Command(() => ChangeOnOff("Opacity"))
                        },
                        new Button {
                            Text = "Change Visible",
                            Command = new Command(() => ChangeOnOff("Visible"))
                        },
                        grid
                    }
                }

            };
        }

        /// <summary>
        /// Opacity か IsVisible を 10回繰り返す
        /// </summary>
        /// <param name="param">Opacity か Visible</param>
        void ChangeOnOff(string param)
        {
            var ary = new List<double>();
            for (int i = 0; i < 10; i++)
            {
                sw.Reset();
                sw.Start();
                if (param == "Opacity")
                {
                    grid.Opacity = 0;
                }
                else
                {
                    grid.IsVisible = false;
                }
                sw.Stop();
                ary.Add(sw.Elapsed.TotalMilliseconds);
                if (param == "Opacity")
                {
                    grid.Opacity = 100;
                }
                else
                {
                    grid.IsVisible = true;
                }
            }
            Debug.WriteLine("【平均経過時間】{0}: {1}sec\n【最少】{0}: {2}sec\n【最大】{0}: {3}sec",
                param, ary.Average(), ary.Min(), ary.Max());
        }

    }

    public class ImageGrid : Grid
    {
        /// <summary>
        /// イメージを配置する Grid
        /// </summary>
        /// <param name="rows">行数</param>
        /// <param name="columns">列数</param>
        public ImageGrid(int rows, int columns)
        {
            for (var row = 0; row < rows; row++)
                for (var column = 0; column < columns; column++)
                {
                    // Working with Images (http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/images/#Local_Images) を参照
                    var image = new Image
                    {
                        Source = ImageSource.FromFile("xm100.png"),
                        Aspect = Aspect.AspectFit,
                        VerticalOptions = LayoutOptions.CenterAndExpand,
                    };
                    Children.Add(image, row, column);
                }
        }
    }

}

結果

IsVisible の方が 10倍くらい時間が掛かるみたいです。Image も Label も IsVisible だと遅いです。 IsVisible = false にするとコントロールが無くなり StackLayout だと配置も変わりますので、当然といえば当然ですし、この結果が何かの役に立つのかはよく分かりませんが、一応置いておきます。

Android の RelativeLayout みたいに重ねて表示する場合とか、レイアウトを崩さないようにするには Opacity の方が良いのかもしれないですね。

iOS

【平均経過時間】Opacity: 0.1441sec
【最少】Opacity: 0.0637sec
【最大】Opacity: 0.3012sec
【平均経過時間】Opacity: 0.14476sec
【最少】Opacity: 0.0641sec
【最大】Opacity: 0.3066sec
【平均経過時間】Opacity: 0.14406sec
【最少】Opacity: 0.0635sec
【最大】Opacity: 0.3105sec
【平均経過時間】Opacity: 0.1253sec
【最少】Opacity: 0.064sec
【最大】Opacity: 0.3088sec
【平均経過時間】Opacity: 0.14869sec
【最少】Opacity: 0.0646sec
【最大】Opacity: 0.3092sec

【平均経過時間】Visible: 1.0165sec
【最少】Visible: 0.8757sec
【最大】Visible: 1.8445sec
【平均経過時間】Visible: 0.98524sec
【最少】Visible: 0.8705sec
【最大】Visible: 1.7394sec
【平均経過時間】Visible: 1.02521sec
【最少】Visible: 0.8153sec
【最大】Visible: 1.8sec
【平均経過時間】Visible: 0.98873sec
【最少】Visible: 0.8508sec
【最大】Visible: 1.6056sec
【平均経過時間】Visible: 0.98661sec
【最少】Visible: 0.8845sec
【最大】Visible: 1.7147sec

Android

【平均経過時間】Opacity: 0.21865sec
【最少】Opacity: 0.1756sec
【最大】Opacity: 0.385sec
【平均経過時間】Opacity: 0.30555sec
【最少】Opacity: 0.1906sec
【最大】Opacity: 0.8458sec
【平均経過時間】Opacity: 0.20988sec
【最少】Opacity: 0.191sec
【最大】Opacity: 0.3166sec
【平均経過時間】Opacity: 0.20839sec
【最少】Opacity: 0.1918sec
【最大】Opacity: 0.3195sec
【平均経過時間】Opacity: 0.46071sec
【最少】Opacity: 0.1188sec
【最大】Opacity: 2.5516sec

【平均経過時間】Visible: 0.79982sec
【最少】Visible: 0.5779sec
【最大】Visible: 1.7771sec
【平均経過時間】Visible: 0.74314sec
【最少】Visible: 0.6141sec
【最大】Visible: 1.1079sec
【平均経過時間】Visible: 0.7045sec
【最少】Visible: 0.5965sec
【最大】Visible: 1.0974sec
【平均経過時間】Visible: 0.83888sec
【最少】Visible: 0.5947sec
【最大】Visible: 2.4157sec
【平均経過時間】Visible: 0.68957sec
【最少】Visible: 0.5745sec
【最大】Visible: 1.1125sec

I/Choreographer(18532): Skipped 36 frames! The application may be doing too much work on its main thread.
I/art (18532): Explicit concurrent mark sweep GC freed 10362(469KB) AllocSpace objects, 1(12KB) LOS objects, 23% free, 51MB/67MB, paused 1.194ms total 16.337ms
D/Mono (18532): GC_OLD_BRIDGE num-objects 10 num_hash_entries 11 sccs size 11 init 0.00ms df1 0.11ms sort 0.03ms dfs2 0.22ms setup-cb 0.01ms free-data 0.04ms links 1/1/1/1 dfs passes 22/12
D/Mono (18532): GC_MINOR: (Nursery full) pause 7.64ms, total 7.75ms, bridge 19.92ms promoted 832K major 1088K los 8K

何か IsVisible の方だけ Mono の GC が動いてそうな感じでしょうか?気になりますね。

Windows Phone

【平均経過時間】Opacity: 0.26425sec
【最少】Opacity: 0.2093sec
【最大】Opacity: 0.4739sec
【平均経過時間】Opacity: 0.24085sec
【最少】Opacity: 0.2052sec
【最大】Opacity: 0.4616sec
【平均経過時間】Opacity: 0.23747sec
【最少】Opacity: 0.1993sec
【最大】Opacity: 0.4932sec
【平均経過時間】Opacity: 0.22001sec
【最少】Opacity: 0.1906sec
【最大】Opacity: 0.4125sec

【平均経過時間】Visible: 2.26874sec
【最少】Visible: 1.0278sec
【最大】Visible: 12.9919sec
【平均経過時間】Visible: 2.4345sec
【最少】Visible: 1.0837sec
【最大】Visible: 13.9283sec
【平均経過時間】Visible: 2.13072sec
【最少】Visible: 1.0212sec
【最大】Visible: 11.346sec
【平均経過時間】Visible: 2.16796sec
【最少】Visible: 1.0325sec
【最大】Visible: 11.3203sec
【平均経過時間】Visible: 2.32509sec
【最少】Visible: 1.0274sec
【最大】Visible: 12.9515sec

スレッド 0x1574 はコード 259 (0x103) で終了しました。

Opacity でスレッドのエラーが出ました。動作はしますが。こちらも気になりますね。

Xamarin 気になった方は

是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

以上です。