Xamarin.FormsをMAUI移行中にツマった話

こちらの続き。

Visual Studio2022と、.NET 8が正式リリースされました。
ので、Xamarin.Formsアプリを、新規作成したMAUIプロジェクトに移行していく。
そこで修正が必要だったり、詰まったところをまとめていく。

なお、2024年1月時点のお話です。

Device系は置換が必要

これに限らず、ちょこちょこ置換が必要なものは多い。
ので、とりあえず一例。

BeginInvokeOnMainThread関数

Microsoft.Maui.Controls.Application.Current.Dispatcher.Dispatchに置き換えるだけ。

StartTimer関数

Application.Current.Dispatcher.StartTimerに置き換えるだけ。

Device.RuntimePlatform関数

Microsoft.Maui.Devices.DeviceInfo.Platformに置き換えるだけ。
同様にDevice.iOSやDevice.Androidは、DevicePlatform.iOSとDevicePlatform.Androidに置換。

地図系

そこそこ大きいので切り分けました。

レイアウトまわり

AbsoluteLayoutにすべきか、Gridにすべきか

レイアウトが崩れたら、まず怪しむべき原因はこれな気がする。

重要
HorizontalOptions プロパティと VerticalOptions プロパティは、AbsoluteLayout の子には影響しません

https://learn.microsoft.com/ja-jp/dotnet/maui/user-interface/layouts/absolutelayout?view=net-maui-8.0

全部、ちゃんと子要素のサイズも指定するか、Gridに置き換えるかは、ケースバイケースな気がする。

GridはGridで怪しくて、列や行の高さをプログラムから変更するコードを書くと、Debug版では動くのに、Release版ではアプリが吹っ飛んだ。
また、特定の端末ではGridの隙間を0にしているのに微妙に空いてしまったり。
画像を配置して厳密に指定したいなら、AbsoluteLayoutに置き換えましょう。
動的に変えたいなら、例えばOnSizeAllocatedで計算して反映しましょう。

double x, y, itemWidth, itemHeigt;
// 計算は調略
// 例えばbuttonStartの位置を調整
AbsoluteLayout.SetLayoutBounds(buttonStart, new Rect(x, y, itemWidth, itemHeigt));

あと、確証はないけど、OnSizeAllocatedをoverrideして、base.OnSizeAllocatedの呼び出しタイミングは最初よりは諸々処理した後が良さげ?
下記も参照してください。

透明なラベルはGridを跨ぐべからず

タップ用に透明なラベルを配置して、ボタンの画像を正常時・タップ中で切り替えたかった。
が、Gridの行や列を跨いで配置すると、透明ラベルが表示しているテキストの領域に引きづられる = つまりTextが空文字だとラベル領域が消えた。
これが、iOSやAndroid 9では起こらず、手持ちのAndroid 13で、配置したボタンの一部でしか出ない。なんでや。

Aspect=”AspectFill”が効くようになった?

Aspect=”AspectFill”(アスペクト比を固定する)を選択してるのに、Xamarinは効果がなかったっぽい?
MAUIではちゃんと適用されたことがきっかけで、画像サイズがいまいちだったものが見つかった。

ステータスバーの色

XamarinはiOSのステータスバーもホームバーも無視して突き抜けてた。
けど、これが土台のViewの背景色が反映されつつ、突き抜けなくなった。
でも、ステータスバーの色はむしろ突き抜けててほしい。
Community.Toolkit.Maui.CoreをNugetからインストールして、プログラムから変更するようにした。
ただ、横回転もサポートするとダメダメなので、こちらも参照してください。

/// <summary>
/// ステータスバーにアプリ上部の色を適用する
/// </summary>
private void updateStatusBarColor()
{
    // 失敗してもエラーにはしない
    try
    {
        CommunityToolkit.Maui.Core.Platform.StatusBar.SetColor(Color.FromRgb(0x66, 0x66, 0x66));
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Android.App.AlertDialogの色(未解決)

Android.App.AlertDialog.Builderを使ってダイアログを出すとき、今までは背景のみ白を指定して、問題なかった。
それが、Xperia Ace Ⅱだと背景もボタンが白くて見えなくなっちゃった。

じゃあ、指定もメンドイし、Styleの指定をやめて、デフォルトで行こう。
Pixel6で、背景もボタンも黒くて見えない。なんでや。

なので、ボタンは黒を明示的に指定するようStyle.xmlを修正。
こちらを参考にさせてもらいました。
https://qiita.com/hanaaaa/items/dd58ab6946d8ff4a0994

<?xml version="1.0" encoding="utf-8" ?>
<resources>
  <style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
    <item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
    <item name="android:background">@android:color/white</item>
    
  </style>

  <!-- AlertDialogPositiveButtonStyle -->
  <style name="PositiveButtonStyle" parent="Widget.AppCompat.ButtonBar.AlertDialog">
    <item name="android:textColor">@android:color/black</item>
    <item name="backgroundTint">@android:color/white</item>
  </style>

  <!-- AlertDialogrNegativeButtonStyle -->
  <style name="NegativeButtonStyle" parent="Widget.AppCompat.ButtonBar.AlertDialog">
    <item name="android:textColor">@android:color/black</item>
    <item name="android:textColor">@android:color/white</item>
  </style>
</resources>

これで、Xperia Ace Ⅱだと白背景+ボタン文字が緑に、Pixel6だと白背景+ボタン文字が黒に。統一せぇ。
そしてXperia Aceで背景もボタンが白くて見えなくなっちゃった。なんなの…。

Label.FormattedTextを使うと、LabelのTextColorは無視される

なんでだ。
SpanタグにもTextColorをいちいち指定した。

<Label TextColor="White"> <!--これは無視された -->
<Label.FormattedText>
    <FormattedString>
        <Span Text="いちいち" TextColor="White"/>
        <Span Text="{x:Static sys:Environment.NewLine}" />
        <Span Text="白を指定" TextColor="White"/>
    </FormattedString>
</Label.FormattedText>

起動&クラッシュ系

まだ見つかりそうなので、切り分けた。

というか、そもそもTipsが増えてきた。


他にもニッチなIT関連要素をまとめていますので、よければ一覧記事もご覧ください。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)