Xamarin.Forms实例旅行日志 - (1)入门
项目结构及运行呈现效果如下:
1. 创建模型类 Models\TripLogEntry.cs
1 using System; 2 3 namespace TripLog.Models 4 { 5 public class TripLogEntry 6 { 7 public string Title { get; set; } 8 public double Latitude { get; set; } 9 public double Longitude { get; set; } 10 public DateTime Date { get; set; } 11 public int Rating { get; set; } 12 public string Notes { get; set; } 13 } 14 }
2. 创建首页日志列表页 Views\MainPage.axml 及 Views\MainPage.axml.cs 代码如下:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 xmlns:d="http://xamarin.com/schemas/2014/forms/design" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 x:Class="TripLog.Views.MainPage" 8 Title="TripLog"> 9 <ContentPage.ToolbarItems> 10 <ToolbarItem Text="New" Clicked="New_Clicked"/> 11 </ContentPage.ToolbarItems> 12 <ContentPage.Content> 13 <CollectionView x:Name="trips" SelectionMode="Single" SelectionChanged="Trips_SelectionChanged"> 14 <CollectionView.ItemTemplate> 15 <DataTemplate> 16 <Grid Padding="10"> 17 <Grid.ColumnDefinitions> 18 <ColumnDefinition Width="1*"/> 19 <ColumnDefinition Width="3*"/> 20 </Grid.ColumnDefinitions> 21 <Grid.RowDefinitions> 22 <RowDefinition Height="Auto"/> 23 <RowDefinition Height="Auto"/> 24 </Grid.RowDefinitions> 25 <Label Grid.RowSpan="2" 26 Text="{Binding Date,StringFormat='{0:MM d}'}"/> 27 <Label Grid.Column="1" 28 Text="{Binding Title}" 29 FontAttributes="Bold"/> 30 31 <Label Grid.Column="1" 32 Grid.Row="1" 33 Text="{Binding Notes}"/> 34 35 </Grid> 36 </DataTemplate> 37 </CollectionView.ItemTemplate> 38 </CollectionView> 39 </ContentPage.Content> 40 </ContentPage>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using TripLog.Models; 7 using Xamarin.Forms; 8 using Xamarin.Forms.Xaml; 9 10 namespace TripLog.Views 11 { 12 [XamlCompilation(XamlCompilationOptions.Compile)] 13 public partial class MainPage : ContentPage 14 { 15 public MainPage() 16 { 17 InitializeComponent(); 18 19 var items = new List<TripLogEntry> 20 { 21 new TripLogEntry 22 { 23 Title = "Washington Monument", 24 Notes = "Amazing!", 25 Rating = 3, 26 Date = new DateTime(2019,2,5), 27 Latitude = 38.8895, 28 Longitude = -77.0352 29 }, 30 new TripLogEntry 31 { 32 Title = "Statue of Liberty", 33 Notes = "Inspiring", 34 Rating = 4, 35 Date = new DateTime(2019,4,13), 36 Latitude = 40.6892, 37 Longitude = -74.0444 38 }, 39 new TripLogEntry 40 { 41 Title = "Golden Gate Bridge", 42 Notes = "Foggy, but beautiful", 43 Rating = 5, 44 Date = new DateTime(2019,4,26), 45 Latitude = 37.8268, 46 Longitude = -122.4798 47 } 48 }; 49 50 trips.ItemsSource = items; 51 } 52 53 private void New_Clicked(object sender, EventArgs e) 54 { 55 Navigation.PushAsync(new NewEntryPage()); 56 } 57 58 private async void Trips_SelectionChanged(object sender, SelectionChangedEventArgs e) 59 { 60 var trip = (TripLogEntry) e.CurrentSelection.FirstOrDefault(); 61 62 if (trip != null) 63 { 64 await Navigation.PushAsync(new DetailPage(trip)); 65 } 66 67 //clear selection 68 trips.SelectedItem = null; 69 } 70 } 71 }
3. 新增日志条目页 Views\NewEntryPage.axml 及 Views\NewEntryPage.axml.cs
1 <?xml version="1.0" encoding="utf-8" ?> 2 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 xmlns:d="http://xamarin.com/schemas/2014/forms/design" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 x:Class="TripLog.Views.NewEntryPage" 8 Title="New Entry"> 9 <ContentPage.ToolbarItems> 10 <ToolbarItem Text="Save"/> 11 </ContentPage.ToolbarItems> 12 <ContentPage.Content> 13 <TableView Intent="Form"> 14 <TableView.Root> 15 <TableSection> 16 <EntryCell Label="Title"/> 17 <EntryCell Label="Latitude" 18 Keyboard="Numeric"/> 19 <EntryCell Label="Longitude" 20 Keyboard="Numeric"/> 21 <EntryCell Label="Date"/> 22 <EntryCell Label="Rating" 23 Keyboard="Numeric"/> 24 <EntryCell Label="Notes"/> 25 26 </TableSection> 27 </TableView.Root> 28 </TableView> 29 </ContentPage.Content> 30 </ContentPage>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using Xamarin.Forms; 8 using Xamarin.Forms.Xaml; 9 10 namespace TripLog.Views 11 { 12 [XamlCompilation(XamlCompilationOptions.Compile)] 13 public partial class NewEntryPage : ContentPage 14 { 15 public NewEntryPage() 16 {
// 以后用MVVM模式时再编写保存代码 17 InitializeComponent(); 18 } 19 } 20 }
4. 查看日志详细信息页 Views\DetailPage.axml 及 Views\DetailPage.axml.cs
需要引入nuget 包 : Xamarin.Forms.Map , 使用的是 google地图 因为被和谐,所以显示不出
1 <?xml version="1.0" encoding="utf-8" ?> 2 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 xmlns:d="http://xamarin.com/schemas/2014/forms/design" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps" 7 mc:Ignorable="d" 8 x:Class="TripLog.Views.DetailPage"> 9 <ContentPage.Content> 10 <Grid> 11 <Grid.RowDefinitions> 12 <RowDefinition Height="4*"/> 13 <RowDefinition Height="Auto"/> 14 <RowDefinition Height="1*"/> 15 </Grid.RowDefinitions> 16 <maps:Map x:Name="map" Grid.RowSpan="3"/> 17 <BoxView Grid.Row="1" BackgroundColor="White" Opacity=".8"/> 18 19 <StackLayout Padding="10" Grid.Row="1"> 20 <Label x:Name="Title" HorizontalOptions="Center"/> 21 <Label x:Name="date" HorizontalOptions="Center"/> 22 <Label x:Name="rating" HorizontalOptions="Center"/> 23 <Label x:Name="notes" HorizontalOptions="Center"/> 24 </StackLayout> 25 </Grid> 26 </ContentPage.Content> 27 </ContentPage>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net.Http.Headers; 5 using System.Text; 6 using System.Threading.Tasks; 7 using TripLog.Models; 8 using Xamarin.Forms; 9 using Xamarin.Forms.Maps; 10 using Xamarin.Forms.Xaml; 11 12 namespace TripLog.Views 13 { 14 [XamlCompilation(XamlCompilationOptions.Compile)] 15 public partial class DetailPage : ContentPage 16 { 17 public DetailPage(TripLogEntry entry) 18 { 19 InitializeComponent(); 20 21 map.MoveToRegion(MapSpan.FromCenterAndRadius( 22 new Position(entry.Latitude, entry.Longitude), 23 Distance.FromMiles(.5) 24 )); 25 26 map.Pins.Add( 27 new Pin 28 { 29 Type = PinType.Place, 30 Label = entry.Title, 31 Position = new Position(entry.Latitude,entry.Longitude) 32 } 33 ); 34 35 Title.Text = entry.Title; 36 date.Text = entry.Date.ToString("M"); 37 rating.Text = $"{entry.Rating} star rating."; 38 notes.Text = entry.Notes; 39 } 40 } 41 }
5. 修改主项目中的 App.axml.cs 文件:
1 using System; 2 using TripLog.Views; 3 using Xamarin.Forms; 4 using Xamarin.Forms.Xaml; 5 6 namespace TripLog 7 { 8 public partial class App : Application 9 { 10 public App() 11 { 12 InitializeComponent(); 13 14 MainPage = new NavigationPage(new MainPage()); 15 } 16 17 protected override void OnStart() 18 { 19 } 20 21 protected override void OnSleep() 22 { 23 } 24 25 protected override void OnResume() 26 { 27 } 28 } 29 }
6. 修改 android项目下的 MainActivity.cs ,代码如下:
1 using System; 2 3 using Android.App; 4 using Android.Content.PM; 5 using Android.Runtime; 6 using Android.Views; 7 using Android.Widget; 8 using Android.OS; 9 10 namespace TripLog.Droid 11 { 12 [Activity(Label = "TripLog", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 13 public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 14 { 15 protected override void OnCreate(Bundle savedInstanceState) 16 { 17 TabLayoutResource = Resource.Layout.Tabbar; 18 ToolbarResource = Resource.Layout.Toolbar; 19 20 base.OnCreate(savedInstanceState); 21 22 Xamarin.Essentials.Platform.Init(this, savedInstanceState); 23 global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 24 Xamarin.FormsMaps.Init(this,savedInstanceState); 25 LoadApplication(new App()); 26 } 27 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) 28 { 29 Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); 30 31 base.OnRequestPermissionsResult(requestCode, permissions, grantResults); 32 } 33 } 34 }
7. 在android 项目中添加google 地图的 apikey, 打开 Properties\Mainifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.triplog"> 3 <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" /> 4 <application android:label="TripLog.Android"> 5 <meta-data android:name="com.google.android.maps.v2.API_KEY" 6 android:value="AIzaSyB9vd34fe343ffQhoBYk-UX1xeB8Xw97AGH0"/> 7 8 </application> 9 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 10 </manifest>
8. 修改 iOS 项目下的 AppDelegate.cs 文件,代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 5 using Foundation; 6 using UIKit; 7 8 namespace TripLog.iOS 9 { 10 // The UIApplicationDelegate for the application. This class is responsible for launching the 11 // User Interface of the application, as well as listening (and optionally responding) to 12 // application events from iOS. 13 [Register("AppDelegate")] 14 public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 15 { 16 // 17 // This method is invoked when the application has loaded and is ready to run. In this 18 // method you should instantiate the window, load the UI into it and then make the window 19 // visible. 20 // 21 // You have 17 seconds to return from this method, or iOS will terminate your application. 22 // 23 public override bool FinishedLaunching(UIApplication app, NSDictionary options) 24 { 25 global::Xamarin.Forms.Forms.Init(); 26 Xamarin.FormsMaps.Init(); 27 LoadApplication(new App()); 28 29 return base.FinishedLaunching(app, options); 30 } 31 } 32 }
至此全部代码就完成了,编译调试即可! 这个实例只是简单入门学些, 以后在进一步改良为 MVVM 模式。