Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Normalmente, um Xamarin.Forms aplicativo inclui uma ou mais páginas derivadas de , e essas páginas são compartilhadas por todas as plataformas em um projeto de ContentPagebiblioteca .NET Standard ou Projeto Compartilhado. No entanto, o Native Forms permite que ContentPagepáginas derivadas sejam adicionadas diretamente a aplicativos nativos Xamarin.iOS, Xamarin.Android e UWP. Em comparação com o consumo de páginas derivadas do projeto ContentPagenativo de um projeto de biblioteca do .NET Standard ou de um Projeto Compartilhado, a vantagem de adicionar páginas diretamente a projetos nativos é que as páginas podem ser estendidas com exibições nativas. As exibições nativas podem ser nomeadas em XAML e x:Name referenciadas no code-behind. Para obter mais informações sobre exibições nativas, consulte Exibições nativas.
O processo para consumir uma Xamarin.FormsContentPagepágina derivada em um projeto nativo é o seguinte:
- Adicione o Xamarin.Forms pacote NuGet ao projeto nativo.
- Adicione a página -derivada
ContentPagee quaisquer dependências ao projeto nativo. - Chame o método
Forms.Init. - Construa uma instância da página derivada
ContentPagee converta-a no tipo nativo apropriado usando um dos seguintes métodos de extensão:CreateViewControllerpara iOS,CreateSupportFragmentpara Android ouCreateFrameworkElementpara UWP. - Navegue até a representação de tipo nativo da página derivada
ContentPageusando a API de navegação nativa.
Xamarin.Forms deve ser inicializado chamando o Forms.Init método antes que um projeto nativo possa construir uma ContentPagepágina derivada. A escolha de quando fazer isso depende principalmente de quando é mais conveniente no fluxo do aplicativo – ele pode ser executado na inicialização do aplicativo ou pouco antes da construção da ContentPagepágina derivada. Neste artigo e nos aplicativos de exemplo que o acompanham, o método é chamado na inicialização do Forms.Init aplicativo.
Observação
A solução de aplicativo de exemplo NativeForms não contém nenhum Xamarin.Forms projeto. Em vez disso, ele consiste em um projeto Xamarin.iOS, um projeto Xamarin.Android e um projeto UWP. Cada projeto é um projeto nativo que usa formulários nativos para consumir ContentPagepáginas derivadas. No entanto, não há motivo para que os projetos nativos não possam consumir ContentPagepáginas derivadas de um projeto de biblioteca do .NET Standard ou Projeto Compartilhado.
Ao usar o Native Forms, Xamarin.Forms recursos como DependencyService, MessagingCentere o mecanismo de vinculação de dados ainda funcionam. Porém, a navegação de página deve ser executada usando a API de navegação nativa.
iOS
No iOS, a FinishedLaunching substituição na classe normalmente é o local para executar tarefas relacionadas à inicialização do AppDelegate aplicativo. Ele é chamado depois que o aplicativo é iniciado e geralmente é substituído para configurar a janela principal e o controlador de exibição. O exemplo de código a seguir mostra a AppDelegate classe no aplicativo de exemplo:
[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
public static AppDelegate Instance;
UIWindow _window;
AppNavigationController _navigation;
public static string FolderPath { get; private set; }
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
Forms.Init();
// Create app-level resource dictionary.
Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
Xamarin.Forms.Application.Current.Resources = new MyDictionary();
Instance = this;
_window = new UIWindow(UIScreen.MainScreen.Bounds);
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes
{
TextColor = UIColor.Black
});
FolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
NotesPage notesPage = new NotesPage()
{
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
UIViewController notesPageController = notesPage.CreateViewController();
notesPageController.Title = "Notes";
_navigation = new AppNavigationController(notesPageController);
_window.RootViewController = _navigation;
_window.MakeKeyAndVisible();
notesPage.Parent = null;
return true;
}
// ...
}
Esse métodoFinishedLaunching executa as seguintes tarefas:
- Xamarin.Forms é inicializado chamando o
Forms.Initmétodo. - Um novo
Xamarin.Forms.Applicationobjeto is é criado e seu dicionário de recursos no nível do aplicativo é definido como definidoResourceDictionaryem XAML. - Uma referência à classe é armazenada
AppDelegatenostaticInstancecampo. Isso é para fornecer um mecanismo para que outras classes chamem métodos definidos naAppDelegateclasse. - O
UIWindow, que é o contêiner principal para exibições em aplicativos iOS nativos, é criado. - A
FolderPathpropriedade é inicializada para um caminho no dispositivo em que os dados da nota serão armazenados. - Um
NotesPageobjeto é criado, que é uma Xamarin.FormsContentPagepágina derivada definida em XAML, e seu pai é definido como o objeto criadoXamarin.Forms.Applicationanteriormente. - O
NotesPageobjeto é convertido em umUIViewControllerusando oCreateViewControllermétodo de extensão. - A
Titlepropriedade doUIViewControlleré definida, que será exibida noUINavigationBar. - A
AppNavigationControlleré criado para gerenciar a navegação hierárquica. Essa é uma classe de controlador de navegação personalizada, que deriva deUINavigationController. OAppNavigationControllerobjeto gerencia uma pilha de controladores de exibição e oUIViewControllerpassado para o construtor será apresentado inicialmente quando oAppNavigationControllerfor carregado. - O
AppNavigationControllerobjeto é definido como o nívelUIViewControllersuperior para oUIWindow, e éUIWindowdefinido como a janela de chave para o aplicativo e fica visível. - A
Parentpropriedade do objeto é definida comonull, para evitar um vazamento deNotesPagememória.
Depois que o FinishedLaunching método for executado, a interface do usuário definida na Xamarin.FormsNotesPage classe será exibida, conforme mostrado na captura de tela a seguir:
Importante
Todas as ContentPagepáginas derivadas podem consumir recursos definidos no nível ResourceDictionarydo aplicativo, desde que a Parent propriedade da página seja definida como o Application objeto.
Interagir com a interface do usuário, por exemplo, tocando no + Button, resultará no seguinte manipulador de eventos na execução code-behind NotesPage :
void OnNoteAddedClicked(object sender, EventArgs e)
{
AppDelegate.Instance.NavigateToNoteEntryPage(new Note());
}
O static AppDelegate.Instance campo permite que o AppDelegate.NavigateToNoteEntryPage método seja invocado, o que é mostrado no exemplo de código a seguir:
public void NavigateToNoteEntryPage(Note note)
{
NoteEntryPage noteEntryPage = new NoteEntryPage
{
BindingContext = note,
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
var noteEntryViewController = noteEntryPage.CreateViewController();
noteEntryViewController.Title = "Note Entry";
_navigation.PushViewController(noteEntryViewController, true);
noteEntryPage.Parent = null;
}
O NavigateToNoteEntryPage método converte a página derivada Xamarin.FormsContentPageem um UIViewController com o CreateViewController método de extensão e define a Title propriedade do UIViewController. O UIViewController é então empurrado AppNavigationController PushViewController pelo método. Portanto, a interface do usuário definida na Xamarin.FormsNoteEntryPage classe será exibida, conforme mostrado na captura de tela a seguir:
Quando o for exibido, a NoteEntryPage navegação regressiva exibirá o UIViewController para a NoteEntryPage classe do AppNavigationController, retornando o usuário para o UIViewController para a NotesPage classe. No entanto, remover um UIViewController da pilha de navegação nativa do iOS não descarta automaticamente o UIViewController objeto e anexado Page . Portanto, a AppNavigationController classe substitui o PopViewController método para descartar controladores de exibição na navegação regressiva:
public class AppNavigationController : UINavigationController
{
//...
public override UIViewController PopViewController(bool animated)
{
UIViewController topView = TopViewController;
if (topView != null)
{
// Dispose of ViewController on back navigation.
topView.Dispose();
}
return base.PopViewController(animated);
}
}
A PopViewController substituição chama o Dispose método no UIViewController objeto que foi retirado da pilha de navegação nativa do iOS. Se isso não for feito, o objeto anexado UIViewController Page ficará órfão.
Importante
Objetos órfãos não podem ser coletados como lixo e, portanto, resultam em um vazamento de memória.
Android
No Android, a OnCreate MainActivity substituição na classe normalmente é o local para executar tarefas relacionadas à inicialização do aplicativo. O exemplo de código a seguir mostra a MainActivity classe no aplicativo de exemplo:
public class MainActivity : AppCompatActivity
{
public static string FolderPath { get; private set; }
public static MainActivity Instance;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Forms.Init(this, bundle);
// Create app-level resource dictionary.
Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
Xamarin.Forms.Application.Current.Resources = new MyDictionary();
Instance = this;
SetContentView(Resource.Layout.Main);
var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
SupportActionBar.Title = "Notes";
FolderPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));
NotesPage notesPage = new NotesPage()
{
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
AndroidX.Fragment.App.Fragment notesPageFragment = notesPage.CreateSupportFragment(this);
SupportFragmentManager
.BeginTransaction()
.Replace(Resource.Id.fragment_frame_layout, mainPage)
.Commit();
//...
notesPage.Parent = null;
}
...
}
Esse métodoOnCreate executa as seguintes tarefas:
- Xamarin.Forms é inicializado chamando o
Forms.Initmétodo. - Um novo
Xamarin.Forms.Applicationobjeto is é criado e seu dicionário de recursos no nível do aplicativo é definido como definidoResourceDictionaryem XAML. - Uma referência à classe é armazenada
MainActivitynostaticInstancecampo. Isso é para fornecer um mecanismo para que outras classes chamem métodos definidos naMainActivityclasse. - O
Activityconteúdo é definido a partir de um recurso de layout. No aplicativo de exemplo, o layout consiste em umLinearLayoutque contém umToolbar, e umFrameLayoutpara atuar como um contêiner de fragmento. - O
Toolbaré recuperado e definido como a barra de ação para oActivity, e o título da barra de ação é definido. - A
FolderPathpropriedade é inicializada para um caminho no dispositivo em que os dados da nota serão armazenados. - Um
NotesPageobjeto é criado, que é uma Xamarin.FormsContentPagepágina derivada definida em XAML, e seu pai é definido como o objeto criadoXamarin.Forms.Applicationanteriormente. - O
NotesPageobjeto é convertido em umFragmentusando oCreateSupportFragmentmétodo de extensão. - A
SupportFragmentManagerclasse cria e confirma uma transação que substitui aFrameLayoutinstância peloFragmentpara aNotesPageclasse. - A
Parentpropriedade do objeto é definida comonull, para evitar um vazamento deNotesPagememória.
Para obter mais informações sobre fragmentos, consulte Fragmentos.
Depois que o OnCreate método for executado, a interface do usuário definida na Xamarin.FormsNotesPage classe será exibida, conforme mostrado na captura de tela a seguir:
Importante
Todas as ContentPagepáginas derivadas podem consumir recursos definidos no nível ResourceDictionarydo aplicativo, desde que a Parent propriedade da página seja definida como o Application objeto.
Interagir com a interface do usuário, por exemplo, tocando no + Button, resultará no seguinte manipulador de eventos na execução code-behind NotesPage :
void OnNoteAddedClicked(object sender, EventArgs e)
{
MainActivity.Instance.NavigateToNoteEntryPage(new Note());
}
O static MainActivity.Instance campo permite que o MainActivity.NavigateToNoteEntryPage método seja invocado, o que é mostrado no exemplo de código a seguir:
public void NavigateToNoteEntryPage(Note note)
{
NoteEntryPage noteEntryPage = new NoteEntryPage
{
BindingContext = note,
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
AndroidX.Fragment.App.Fragment noteEntryFragment = noteEntryPage.CreateSupportFragment(this);
SupportFragmentManager
.BeginTransaction()
.AddToBackStack(null)
.Replace(Resource.Id.fragment_frame_layout, noteEntryFragment)
.Commit();
noteEntryPage.Parent = null;
}
O NavigateToNoteEntryPage método converte a página derivada Xamarin.FormsContentPageem um Fragment com o CreateSupportFragment método de extensão e adiciona a Fragment à pilha de retorno do fragmento. Portanto, a interface do usuário definida no Xamarin.FormsNoteEntryPage será exibida, conforme mostrado na captura de tela a seguir:
Quando o NoteEntryPage for exibido, tocar na seta para trás exibirá o Fragment para a NoteEntryPage pilha de retorno do fragmento, retornando o usuário para o Fragment para a NotesPage classe.
Ativar suporte à navegação regressiva
A SupportFragmentManager classe tem um BackStackChanged evento que é acionado sempre que o conteúdo da pilha de retorno do fragmento é alterado. O OnCreate método na MainActivity classe contém um manipulador de eventos anônimo para este evento:
SupportFragmentManager.BackStackChanged += (sender, e) =>
{
bool hasBack = SupportFragmentManager.BackStackEntryCount > 0;
SupportActionBar.SetHomeButtonEnabled(hasBack);
SupportActionBar.SetDisplayHomeAsUpEnabled(hasBack);
SupportActionBar.Title = hasBack ? "Note Entry" : "Notes";
};
Esse manipulador de eventos exibe um botão Voltar na barra de ações, desde que haja uma ou mais Fragment instâncias na pilha de retorno do fragmento. A resposta ao toque no botão Voltar é tratada pela OnOptionsItemSelected substituição:
public override bool OnOptionsItemSelected(Android.Views.IMenuItem item)
{
if (item.ItemId == global::Android.Resource.Id.Home && SupportFragmentManager.BackStackEntryCount > 0)
{
SupportFragmentManager.PopBackStack();
return true;
}
return base.OnOptionsItemSelected(item);
}
A OnOptionsItemSelected substituição é chamada sempre que um item no menu de opções é selecionado. Essa implementação remove o fragmento atual da pilha de retorno do fragmento, desde que o botão Voltar tenha sido selecionado e haja uma ou mais Fragment instâncias na pilha de retorno do fragmento.
Múltiplas atividades
Quando um aplicativo é composto de várias atividades, ContentPageas páginas derivadas de -podem ser incorporadas em cada uma das atividades. Nesse cenário, o Forms.Init método precisa ser chamado apenas na OnCreate substituição do primeiro Activity que incorpora um Xamarin.FormsContentPage. No entanto, isso tem o seguinte impacto:
- O valor de
Xamarin.Forms.Color.Accentserá retirado doActivitychamadoForms.Initmétodo. - O valor de
Xamarin.Forms.Application.Currentserá associado aoActivityque chamou oForms.Initmétodo.
Escolher um arquivo
Ao incorporar uma ContentPagepágina derivada que usa um WebView que precisa suportar um botão HTML "Escolher arquivo", o Activity precisará substituir o OnActivityResult método:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
ActivityResultCallbackRegistry.InvokeCallback(requestCode, resultCode, data);
}
UWP
Na UWP, a classe nativa App normalmente é o local para executar tarefas relacionadas à inicialização do aplicativo. Xamarin.Forms geralmente é inicializado, em Xamarin.Forms aplicativos UWP, na OnLaunched substituição na classe nativa App , para passar o LaunchActivatedEventArgs argumento para o Forms.Init método. Por esse motivo, os aplicativos UWP nativos que consomem uma Xamarin.FormsContentPagepágina derivada podem chamar mais facilmente o Forms.Init método do App.OnLaunched método:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ...
Xamarin.Forms.Forms.Init(e);
// Create app-level resource dictionary.
Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
Xamarin.Forms.Application.Current.Resources = new MyDictionary();
// ...
}
Além disso, o OnLaunched método também pode criar qualquer dicionário de recursos no nível do aplicativo exigido pelo aplicativo.
Por padrão, a classe nativa App inicia a MainPage classe como a primeira página do aplicativo. O exemplo de código a seguir mostra a MainPage classe no aplicativo de exemplo:
public sealed partial class MainPage : Page
{
NotesPage notesPage;
NoteEntryPage noteEntryPage;
public static MainPage Instance;
public static string FolderPath { get; private set; }
public MainPage()
{
this.NavigationCacheMode = NavigationCacheMode.Enabled;
Instance = this;
FolderPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));
notesPage = new Notes.UWP.Views.NotesPage
{
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
this.Content = notesPage.CreateFrameworkElement();
// ...
notesPage.Parent = null;
}
// ...
}
O MainPage construtor executa as seguintes tarefas:
- O cache é habilitado para a página, para que um novo
MainPagenão seja construído quando um usuário navega de volta para a página. - Uma referência à classe é armazenada
MainPagenostaticInstancecampo. Isso é para fornecer um mecanismo para que outras classes chamem métodos definidos naMainPageclasse. - A
FolderPathpropriedade é inicializada para um caminho no dispositivo em que os dados da nota serão armazenados. - Um
NotesPageobjeto é criado, que é uma Xamarin.FormsContentPagepágina derivada definida em XAML, e seu pai é definido como o objeto criadoXamarin.Forms.Applicationanteriormente. - O
NotesPageobjeto é convertido em umFrameworkElementusando oCreateFrameworkElementmétodo de extensão e, em seguida, definido como o conteúdo daMainPageclasse. - A
Parentpropriedade do objeto é definida comonull, para evitar um vazamento deNotesPagememória.
Depois que o MainPage construtor for executado, a interface do usuário definida na Xamarin.FormsNotesPage classe será exibida, conforme mostrado na captura de tela a seguir:
Importante
Todas as ContentPagepáginas derivadas podem consumir recursos definidos no nível ResourceDictionarydo aplicativo, desde que a Parent propriedade da página seja definida como o Application objeto.
Interagir com a interface do usuário, por exemplo, tocando no + Button, resultará no seguinte manipulador de eventos na execução code-behind NotesPage :
void OnNoteAddedClicked(object sender, EventArgs e)
{
MainPage.Instance.NavigateToNoteEntryPage(new Note());
}
O static MainPage.Instance campo permite que o MainPage.NavigateToNoteEntryPage método seja invocado, o que é mostrado no exemplo de código a seguir:
public void NavigateToNoteEntryPage(Note note)
{
noteEntryPage = new Notes.UWP.Views.NoteEntryPage
{
BindingContext = note,
// Set the parent so that the app-level resource dictionary can be located.
Parent = Xamarin.Forms.Application.Current
};
this.Frame.Navigate(noteEntryPage);
noteEntryPage.Parent = null;
}
A navegação na UWP normalmente é executada com o Frame.Navigate método, que usa um Page argumento. Xamarin.Forms Define um Frame.Navigate método de extensão que usa uma ContentPageinstância de página derivada. Portanto, quando o NavigateToNoteEntryPage método for executado, a interface do usuário definida no Xamarin.FormsNoteEntryPage será exibida, conforme mostrado na captura de tela a seguir:
Quando o NoteEntryPage for exibido, tocar na seta para trás exibirá o FrameworkElement para a NoteEntryPage pilha de retorno no aplicativo, retornando o usuário para o FrameworkElement para a NotesPage classe.
Habilitar suporte ao redimensionamento de página
Quando a janela do aplicativo UWP é redimensionada, o Xamarin.Forms conteúdo também deve ser redimensionado. Isso é feito registrando um manipulador de eventos para o Loaded evento, no MainPage construtor:
public MainPage()
{
// ...
this.Loaded += OnMainPageLoaded;
// ...
}
O Loaded evento é acionado quando a página é disposta, renderizada e pronta para interação e executa o OnMainPageLoaded método em resposta:
void OnMainPageLoaded(object sender, RoutedEventArgs e)
{
this.Frame.SizeChanged += (o, args) =>
{
if (noteEntryPage != null)
noteEntryPage.Layout(new Xamarin.Forms.Rectangle(0, 0, args.NewSize.Width, args.NewSize.Height));
else
notesPage.Layout(new Xamarin.Forms.Rectangle(0, 0, args.NewSize.Width, args.NewSize.Height));
};
}
O OnMainPageLoaded método registra um manipulador de eventos anônimo para o Frame.SizeChanged evento, que é gerado quando as propriedades ou ActualHeight as ActualWidth propriedades são alteradas no Frame. Em resposta, o Xamarin.Forms conteúdo da página ativa é redimensionado chamando o Layout método.
Ativar suporte à navegação regressiva
Na UWP, os aplicativos devem habilitar a navegação de volta para todos os botões Voltar de hardware e software, em diferentes fatores forma de dispositivo. Isso pode ser feito registrando um manipulador de eventos para o BackRequested evento, que pode ser executado no MainPage construtor:
public MainPage()
{
// ...
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}
Quando o aplicativo é iniciado, o GetForCurrentView método recupera o SystemNavigationManager objeto associado à exibição atual e, em seguida, registra um manipulador de eventos para o BackRequested evento. O aplicativo só receberá esse evento se for o aplicativo em primeiro plano e, em resposta, chamar o manipulador de OnBackRequested eventos:
void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
noteEntryPage = null;
}
}
O OnBackRequested manipulador de eventos chama o GoBack método no quadro raiz do aplicativo e define a BackRequestedEventArgs.Handled propriedade como true para marcar o evento como manipulado. A falha em marcar o evento como manipulado pode resultar na ignorância do evento.
O aplicativo escolhe se deseja mostrar um botão Voltar na barra de título. Isso é feito definindo a AppViewBackButtonVisibility propriedade como um dos valores de AppViewBackButtonVisibility enumeração, na App classe:
void OnNavigated(object sender, NavigationEventArgs e)
{
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
((Frame)sender).CanGoBack ? AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed;
}
O OnNavigated manipulador de eventos, que é executado em resposta ao acionamento do Navigated evento, atualiza a visibilidade do botão Voltar da barra de título quando ocorre a navegação na página. Isso garante que o botão Voltar da barra de título fique visível se a pilha de retorno no aplicativo não estiver vazia ou removido da barra de título se a pilha de retorno no aplicativo estiver vazia.
Para obter mais informações sobre o suporte à navegação regressiva na UWP, consulte Histórico de navegação e navegação regressiva para aplicativos UWP.





