[Xamarin.Forms] 각 플랫폼별 기능에서 Forms에서 만든 보기 표시

14560 단어 XamarinXamarin.Forms
이 항목은 [학생·초보자씨 환영! ]Xamarin Advent Calendar 2016의 13 일째 기사입니다.

초보자용의 기사라고 하는 것으로 Xamarin 초보자 나름대로 「이런 것은 어떻게 구현하는 것일까」라고 생각한 것에 대해 써 드리겠습니다.

타이틀에 각 플랫폼 고유 기능이 있으나 두개골 골절이라든지 시간이 부족해서
안드로이드뿐입니다. 절각이므로 iOS나 UWP도 다른 기회에 쓰려고는 생각합니다.

이하 기사가 이번 기사를 쓰려고 생각한 동기와 같습니다.
Xamarin.Forms로 알림 보내기 (Android) (Prism.Forms 사용)

또, 이번 기사는 상기 기사와 같이 기본적으로 Prism.Forms를 사용했을 때의 기법으로 기재하겠습니다.

각 플랫폼별 기능에서 Forms에서 만든 View 보기



본제입니다.

Xamrin.Forms에서의 개발에 있어서 공통 부분뿐만 아니라 각 플랫폼 고유의 구현을 위해
네이티브 측을 가리가리 쓰기도 많다고 생각합니다.

그 때, 네이티브측으로부터 Forms측의 화면을 어떻게 부르는 것일까라고 신경이 쓰였으므로 우선 해 보았습니다.

구체적으로는 Android 고유의 기능인 통지 기능을 사용해 Forms측에 있는 View를 부르려고 합니다.

Android 알림 탭의 전환 대상을 Forms View로 설정



두 페이지를 만듭니다.
하나는 시작시 호출되는 페이지에서 알림을 발생시키는 버튼이 있습니다.
다른 하나는 발생한 알림을 탭하여만 전환할 수 있는 숨겨진 페이지라는 위치입니다.

Forms 측 구현



알림을 생성하는 View는 다음과 같은 최소한의 구성을 만듭니다.

NotificationPage.xaml
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
      <Button Text="Notification On"
            Command="{ Binding NotificationOnCommand }"
            />
      <Button Text="Notification Off"
              Command="{Binding NotificationOffCommand}"
              />
    </StackLayout>

해당 ViewModel입니다.

NotificationPageViewModel.cs
public class NotificationPageViewModel : BindableBase
    {
        private readonly INotificationOnAndOff _NotificationOnAndOff;
        public DelegateCommand NotificationOnCommand { get; private set; }
        public DelegateCommand NotificationOffCommand { get; private set; }
        public NotificationPageViewModel(INotificationOnAndOff NotificationOnAndOff)
        {
            _NotificationOnAndOff = NotificationOnAndOff;
            NotificationOnCommand = new DelegateCommand(() => _NotificationOnAndOff.NotificationOn());
            NotificationOffCommand = new DelegateCommand(() => _NotificationOnAndOff.NotificationOff());
        }
    }

각 플랫폼별 기능을 호출하는 인터페이스입니다.

INotificationOnAndOff.cs
public interface INotificationOnAndOff
    {
        void NotificationOn();
        void NotificationOff();
    }

다음이 완성된 화면입니다.
위 버튼으로 알림을 내리고 아래 버튼으로 알림이 사라집니다.



계속해서 숨겨진 페이지입니다만 이쪽도 특히 무엇이든 좋기 때문에 간단하게 라벨만 둡니다.

HidePage.xaml
<Label Text="(´・ω・`){隠しページだよ" 
       FontSize="64"/>

이상으로 Forms측의 설계는 끝입니다.

마지막으로 App.xaml.cs에 잊지 않고 NavigationPage를 등록해 둡시다.

App.xaml.cs
protected override void OnInitialized()
        {
            InitializeComponent();

            NavigationService.NavigateAsync("NavigationPage/NotificationPage/");
        }
protected override void RegisterTypes()
        {
            Container.RegisterTypeForNavigation<NavigationPage>();
            Container.RegisterTypeForNavigation<NotificationPage>();
            // Container.RegisterTypeForNavigation<HidePage>(); いらない
        }

네이티브 측 (Android) 구현



계속해서 중요한 안드로이드 측의 설계를 해 나갑니다.

우선은 핵심의 네이티브측으로부터 Forms측으로 천이하기 위한 구조를 만듭니다.
Android 프로젝트 추가에서 Activity를 선택하고 만듭니다.

ToHidePageActivity.cs
[Activity(Label = "ToHidePageActivity")]
    public class ToHidePageActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            // Formsに遷移させて
            (Xamarin.Forms.Application.Current.MainPage as NavigationPage).PushAsync(new HidePage());
            // このActivityは自害する
            FinishAndRemoveTask();
        }
    }

HidePage로 전환하기 위한 Activity입니다.
알림에서 전환하기 위해서는 Activity와 Service가 필요하고 싶기 때문에 이번에는 Activity를 사용합니다.
(Xamarin.Forms.Application.Current.MainPage as NavigationPage).PushAsync(new HidePage());

조금 알기 어려운 느낌이 되고 있습니다만 이쪽의 코드로 네이티브측으로부터 Forms측의 화면 천이를 실시하고 있습니다.
Android, Activity만으로만 부를 수 있다고 하는 제약도 없는 것 같기 때문에 기본적으로 이쪽의 기술을 행하면 iOS, UWP 불문하고 천이할 수 있을 것이라고 생각합니다.

다음으로 DependencyService나 PlatformInitializer등으로 인젝션하기 위해서
인터페이스를 상속하는 클래스를 만듭니다.
container.RegisterType<INotificationOnAndOff, NotificationOnAndOff_Android>(new ContainerControlledLifetimeManager());

PlatformInitializer를 사용하는 경우 MainActivity.cs의 AndroidInitializer 클래스에 위 코드를 추가하십시오.

NotificationOnAndOff_Android.cs
public sealed class NotificationOnAndOff_Android : INotificationOnAndOff
    {
        const int id = 0;

        public void NotificationOn()
        {
            var context = Forms.Context;

            //Forms画面に遷移するためのインテント
            var intent = new Intent(context, typeof(ToHidePageActivity)); 

            var pendingIntent = PendingIntent.GetActivity(context, 0, intent, 0); 

            var n = new Notification.Builder(context)
                    .SetContentTitle("通知")
                    .SetSmallIcon(Resource.Drawable.icon)
                    .SetContentText("タップで隠しページを表示")
                    .SetOngoing(true) 
                    .SetContentIntent(pendingIntent)
                    .Build();

            var nm = (NotificationManager)context.GetSystemService(Context.NotificationService);
            nm.Notify(id, n);
        }

        public void NotificationOff()
        {
            var context = Forms.Context;
            var nm = (NotificationManager)context.GetSystemService(Context.NotificationService);
            nm.Cancel(id);
        }
    }

통지의 천이처의 Intent에 ToHidePageActivity를 넣는 것으로 의사적으로 통지로부터의 천이를 실시하고 있습니다.



이제 위와 같은 알림을 보낼 수 있으며 이것을 탭하면



Forms 측에서 기술하고 있지만 Forms 측 어디에서나 호출하지 않은 HidePage를 호출할 수 있었습니다.

이상입니다.

좋은 웹페이지 즐겨찾기