Xamarin.Android和UWP之MVVM的简单使用(二)
2016-05-25 14:51
435 查看
0x01 前言
前面一篇,Xamarin.Android和UWP之MVVM的简单使用(一),主要讲了MvvmLight的简单使用这篇主要讲讲MvvmCross的简单使用,例子的话,还是和上篇的一样。直接进正题吧,不废话了。
0x02 简单的MVVM(mvvmcross) Demo
新建一个类库项目:Catcher.MVVMDemo.Day01CrossCore添加一个ViewModels文件夹,同时添加一个MainViewModel
using MvvmCross.Core.ViewModels; namespace Catcher.MVVMDemo.Day01CrossCore.ViewModels { public class MainViewModel : MvxViewModel { public MainViewModel() { } private string _input; public string Input { get { return _input; } set { _input = value; RaisePropertyChanged(() => Input); } } } }
这里的ViewModel继承的是MvxViewModel。
在项目根路径添加一个App.cs
using Catcher.MVVMDemo.Day01CrossCore.ViewModels; using MvvmCross.Core.ViewModels; namespace Catcher.MVVMDemo.Day01CrossCore { public class App : MvxApplication { public override void Initialize() { RegisterAppStart<MainViewModel>(); } } }
注册MainViewModel为启动的第一个视图模型
到这里,Xamarin.Android和UWP的公共部分已经完成了。
第一个例子(Xamarin.Android):
新建一个Android项目:Catcher.MVVMDemo.Day01DroidByMvvmCross
在根目录添加一个Setup.cs
using Android.Content; using MvvmCross.Core.ViewModels; using MvvmCross.Droid.Platform; using Catcher.MVVMDemo.Day01CrossCore; namespace Catcher.MVVMDemo.Day01DroidByMvvmCross { public class Setup : MvxAndroidSetup { public Setup(Context applicationContext) : base(applicationContext) { } protected override IMvxApplication CreateApp() { return new App(); } } }
在Setup中,主要是返回了我们在Core里面编写的App.cs
然后修改我们的Main.axml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Text Input" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Text Input" /> </LinearLayout>
通过local:MvxBind来实现绑定。
新建一个文件夹Activities,同时添加一个MainActivity
using Android.App; using MvvmCross.Droid.Views; namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Activities { [Activity(Label = "MvvmCross", MainLauncher = true)] public class MainActivity : MvxActivity { protected override void OnViewModelSet() { SetContentView(Resource.Layout.Main); } } }
Activity的代码很简单,就是指定视图。
到这里已经可以成功运行了,效果如下:
第二个例子(UWP):
步骤基本与Xamarin.Android一致!
新建一个UWP项目:Catcher.MVVMDemo.Day01UWPByMvvmCross
添加一个Setup.cs
using MvvmCross.Core.ViewModels; using MvvmCross.WindowsUWP.Platform; using Windows.UI.Xaml.Controls; namespace Catcher.MVVMDemo.Day01UWPByMvvmCross { public class Setup : MvxWindowsSetup { public Setup(Frame rootFrame) : base(rootFrame) { } protected override IMvxApplication CreateApp() { return new Day01CrossCore.App(); } } }
注意与Android的区别!!
修改App.xaml.cs,将设置启动页注释掉,换成我们刚才的Setup.cs,具体如下:
if (e.PrelaunchActivated == false) { if (rootFrame.Content == null) { //rootFrame.Navigate(typeof(MainPage), e.Arguments); var setup = new Setup(rootFrame); setup.Initialize(); var start = Mvx.Resolve<IMvxAppStart>(); start.Start(); } Window.Current.Activate(); }
把新建项目生成的MainPage干掉,同时在根目录添加一个Views文件夹,用来存放我们的Page
新建一个MainPage.xaml,修改布局如下:
<views:MvxWindowsPage x:Class="Catcher.MVVMDemo.Day01UWPByMvvmCross.Views.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Catcher.MVVMDemo.Day01UWPByMvvmCross.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:views="using:MvvmCross.WindowsUWP.Views" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin="20"> <TextBlock FontSize="14" HorizontalAlignment="Center" Text="MvvmCross UWP Demo" /> <TextBox x:Name="txtInput" /> <TextBlock Text="{Binding ElementName=txtInput,Path=Text}" /> </StackPanel> </Grid> </views:MvxWindowsPage>
要注意的是,用的是MvvmCross的布局MvxWindosPage
并且,MainPage.xaml.cs也要修改!!
using MvvmCross.WindowsUWP.Views; namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Views { public sealed partial class MainPage : MvxWindowsPage { public MainPage() { this.InitializeComponent(); } } }
都是用MvvmCross自己的东西!如果忘记修改,运行效果是一片黑。
到这里已经OK了,效果如下
0x03 MVVM(mvvmcross) 登陆Demo
登陆失败时要有个对话框提示,我们要先新建一个IDialogServicenamespace Catcher.MVVMDemo.Day01CrossCore { public interface IDialogService { void Alert(string message, string title, string okbtnText); } }
在刚才的类库项目中添加一个LoginViewModel
using MvvmCross.Core.ViewModels; namespace Catcher.MVVMDemo.Day01CrossCore.ViewModels { public class LoginViewModel : MvxViewModel { private readonly IDialogService _dialogService; public LoginViewModel(IDialogService dialogService) { _dialogService = dialogService; } private string _Name; public string Name { get { return _Name; } set { _Name = value; RaisePropertyChanged(()=>Name); } } private string _password; public string Password { get { return _password; } set { _password = value; RaisePropertyChanged(()=>Password); } } private IMvxCommand _loginCommand; public virtual IMvxCommand LoginCommand { get { _loginCommand = _loginCommand ?? new MvxCommand(Login); return _loginCommand; } } private void Login() { if (Name=="catcher"&&Password=="123") { ShowViewModel<MainViewModel>(); } else { _dialogService.Alert("check your name and password", "Infomation", "OK"); } } } }
登陆的逻辑处理还是和上一篇一样。
修改我们的App.cs
using Catcher.MVVMDemo.Day01CrossCore.ViewModels; using MvvmCross.Core.ViewModels; using MvvmCross.Platform; using MvvmCross.Platform.IoC; namespace Catcher.MVVMDemo.Day01CrossCore { public class App : MvxApplication { public override void Initialize() { CreatableTypes() .EndingWith("Service") .AsInterfaces() .RegisterAsLazySingleton(); RegisterAppStart<LoginViewModel>(); //demo 1 //RegisterAppStart<MainViewModel>(); } } }
第三个例子(Xamarin.Android):
在Catcher.MVVMDemo.Day01DroidByMvvmCross中添加一个Services文件夹
同时添加一个DialogService去实现我们刚才定义的IDialogService接口。
using Android.App; using MvvmCross.Platform; using Catcher.MVVMDemo.Day01CrossCore; using MvvmCross.Platform.Droid.Platform; namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Services { public class DialogService : IDialogService { /// <summary> /// show the alert dialog /// </summary> /// <param name="message">the message of the dialog</param> /// <param name="title">the title of the dialog</param> /// <param name="okbtnText">the text of the button</param> public void Alert(string message, string title, string okbtnText) { //activity var topActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>(); var context = topActivity.Activity; //alert dialog var adb = new AlertDialog.Builder(context); adb.SetTitle(title); adb.SetMessage(message); adb.SetPositiveButton(okbtnText, (sender, args) => { }); adb.Create().Show(); } } }
这里用到了AlertDialog。
在Setup.cs中注册一下这个Service,重写InitializeFirstChance 方法
protected override void InitializeFirstChance() { base.InitializeFirstChance(); Mvx.RegisterSingleton<IDialogService>(() => new DialogService()); }
添加一个login.axml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="enter your name" local:MvxBind="Text Name" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="enter your password" local:MvxBind="Text Password" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login" local:MvxBind="Click LoginCommand" /> </LinearLayout>
在Activities文件夹添加一个LoginActivity
using Android.App; using MvvmCross.Droid.Views; namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Activities { [Activity(Label = "MvvmCross", MainLauncher = true)] public class LoginActivity : MvxActivity { protected override void OnViewModelSet() { SetContentView(Resource.Layout.login); } } }
去掉,MainActivity中的Mainlauncher=true
OK,效果如下:
第四个例子(UWP):
在Catcher.MVVMDemo.Day01UWPByMvvmCross中添加一个Services文件夹
同时添加一个DialogService去实现我们刚才定义的IDialogService接口。
using Catcher.MVVMDemo.Day01CrossCore; using System; using Windows.UI.Xaml.Controls; namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Services { public class DialogService : IDialogService { public async void Alert(string message, string title, string okbtnText) { var dialog = new ContentDialog() { Content = message, Title= title, PrimaryButtonText = okbtnText }; dialog.PrimaryButtonClick += (s, e) => { }; await dialog.ShowAsync(); } } }
这里用ContentDialog去实现这个提示。
在Setup.cs中注册一下这个Service,重写InitializeFirstChance 方法
protected override void InitializeFirstChance() { base.InitializeFirstChance(); Mvx.RegisterSingleton<IDialogService>(() => new DialogService()); }
在Views文件夹添加一个LoginPage.xaml
<views:MvxWindowsPage x:Class="Catcher.MVVMDemo.Day01UWPByMvvmCross.Views.LoginPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Catcher.MVVMDemo.Day01UWPByMvvmCross.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:views="using:MvvmCross.WindowsUWP.Views" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="5*"></RowDefinition> </Grid.RowDefinitions> <TextBox Grid.Row="1" Margin="15" Height="20" Text="{Binding Name,Mode=TwoWay}" PlaceholderText="enter you name" /> <PasswordBox Grid.Row="2" Margin="15" Height="20" Password="{Binding Password,Mode=TwoWay}" PasswordChar="*" PlaceholderText="enter your password" /> <Button Grid.Row="3" Margin="15,10" Content="Login" Command="{Binding LoginCommand}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> </Grid> </views:MvxWindowsPage>
LoginPage.xaml.cs
using Catcher.MVVMDemo.Day01CrossCore.ViewModels; using MvvmCross.WindowsUWP.Views; namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Views { public sealed partial class LoginPage :MvxWindowsPage { public new LoginViewModel ViewModel { get { return (LoginViewModel)base.ViewModel; } set { base.ViewModel = value; } } public LoginPage() { this.InitializeComponent(); } } }
OK,效果如下 :
0x04 简单总结
MvvmCross用起来跟MvvmLight基本是一样ViewModel这一块与MvvmLight的ViewModel基本没有太大的差别
其他方面,复杂一点的时候,工作量基本差不多,各有各的好,使用的话,都是看个人的兴趣爱好。
MvvmCross也在不断更新,昨天是4.1.5版本,今天就4.1.6了。
官网:https://mvvmcross.com/
Github:https://github.com/MvvmCross
相关文章推荐
- MVP模式在Android项目中的使用
- 实例讲解Android中SQLiteDatabase使用方法
- android ndk 创建过程
- Android SO文件保护加固(一)
- Android AlertDialog实现半透明的弹窗
- 侧滑可以删除的ListView
- Android巧用ActionBar实现下拉式导航
- android自定义View时报 error: No resource identifier found for attribute ‘XXX’ in package 'XXX'
- Android Studio快捷键整理
- Android Studio2.1版本后使用虚拟机碰见的问题总结
- Android studio 导入第三方类库工程 转
- Android 简述touch事件中的MotionEvent
- android shape的使用
- Android自定义ViewGroup的实现方法
- android 中 EditText加入图标 更改边框颜色 设置透明 代码
- Android事件总线 ( AndroidEventBus ) 开源库发布
- Android Studio导入并运行github下载的开源项目【转自 “阿敏其人” 简书博客】
- Android中的windowSoftInputMode属性详解
- Android性能优化
- Android开发之多线程编程Thread和Runnable使用