老司机夜插-理伦理片-理伦片免费-理伦片免费观看-理伦片免费看-理伦日韩-理论福利片-理论片第一页-理论片电影-理论片理论

金喜正规买球

Xamarin Forms的Prism第二部分:基本導航和依賴注入(Dependency Injection)模式

原創|使用教程|編輯:黃竹雯|2016-09-18 18:01:27.000|閱讀 1777 次

概述:本系列的第2部分展示了Prism如何在一個MVVM應用程序中啟動導航。

# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>

相關鏈接:

前一篇文章中,我們已經開始介紹在Xamarin Forms應用程序中如何利用Prism(6.2)的新版本來實現MVVM模式的基本概念。到目前為止,我們還沒有看到什么特別的東西是我們用另一個框架做不到的:我們在上一篇文章中創建了一個視圖(View)、一個視圖模型(ViewModel),然后我們通過綁定連接它們。在這篇文章中,我們將看到Prism如何幫助處理一個在MVVM應用程序中很難處理的非常常見的場景:導航和頁面的生命周期。

Xamarin Forms的Prism第二部分:基本導航和依賴注入(Dependency Injection)模式

正如我們在前一篇文章中提到的,我們要為TrackSeries——一個提供電視節目信息的網站,創建一個簡單的客戶端。該應用程序將顯示當前的頂級系列,將允許用戶發現更多關于它的內容。為了實現這一目標,我們可以用一組網站提供的REST服務,這是非常簡單的使用和處理REST服務的遵循標準的最佳實踐:你調用一個使用HTTP命令的URL,接收返回一個JSON響應結果。

舉個例子,如果你想知道哪些是頂級系列,你可以執行一個HTTP GET請求到以下URL:。服務將返回給你一個JSON響應,包含頂級系列的所有細節:

[
   {
      "id":121361,
      "name":"Game of Thrones",
      "followers":10230,
      "firstAired":"2011-04-17T21:00:00-04:00",
      "country":"us",
      "overview":"Seven noble families fight for control of the mythical land of Westeros. Friction between the houses leads to full-scale war. All while a very ancient evil awakens in the farthest north. Amidst the war, a neglected military order of misfits, the Night's Watch, is all that stands between the realms of men and the icy horrors beyond.",
      "runtime":55,
      "status":"Continuing",
      "network":"HBO",
      "airDay":"Sunday",
      "airTime":"9:00 PM",
      "contentRating":"TV-MA",
      "imdbId":"tt0944947",
      "tvdbId":121361,
      "tmdbId":1399,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/121361-49.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/121361-15.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/121361-g22.jpg"
      },
      "genres":[
         {
            "id":2,
            "name":"Adventure"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":5,
            "name":"Fantasy"
         }
      ],
      "added":"2014-08-08T13:30:46.227",
      "lastUpdated":"2016-08-18T03:03:50.05",
      "followedByUser":false,
      "slugName":"game-of-thrones"
   },
   {
      "id":257655,
      "name":"Arrow",
      "followers":7517,
      "firstAired":"2012-10-10T20:00:00-04:00",
      "country":"us",
      "overview":"Oliver Queen and his father are lost at sea when their luxury yacht sinks. His father doesn't survive. Oliver survives on an uncharted island for five years learning to fight, but also learning about his father's corruption and unscrupulous business dealings. He returns to civilization a changed man, determined to put things right. He disguises himself with the hood of one of his mysterious island mentors, arms himself with a bow and sets about hunting down the men and women who have corrupted his city.",
      "runtime":45,
      "status":"Continuing",
      "network":"The CW",
      "airDay":"Wednesday",
      "airTime":"8:00 PM",
      "contentRating":"TV-14",
      "imdbId":"tt2193021",
      "tvdbId":257655,
      "tmdbId":1412,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/257655-8.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/257655-47.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/257655-g9.jpg"
      },
      "genres":[
         {
            "id":1,
            "name":"Action"
         },
         {
            "id":2,
            "name":"Adventure"
         },
         {
            "id":4,
            "name":"Drama"
         }
      ],
      "added":"2014-08-08T13:37:00.133",
      "lastUpdated":"2016-08-15T03:11:32.013",
      "followedByUser":false,
      "slugName":"arrow"
   },
   {
      "id":153021,
      "name":"The Walking Dead",
      "followers":7185,
      "firstAired":"2010-10-31T21:00:00-04:00",
      "country":"us",
      "overview":"The world we knew is gone. An epidemic of apocalyptic proportions has swept the globe causing the dead to rise and feed on the living. In a matter of months society has crumbled. In a world ruled by the dead, we are forced to finally start living. Based on a comic book series of the same name by Robert Kirkman, this AMC project focuses on the world after a zombie apocalypse. The series follows a police officer, Rick Grimes, who wakes up from a coma to find the world ravaged with zombies. Looking for his family, he and a group of survivors attempt to battle against the zombies in order to stay alive.\n",
      "runtime":50,
      "status":"Continuing",
      "network":"AMC",
      "airDay":"Sunday",
      "airTime":"9:00 PM",
      "contentRating":"TV-MA",
      "imdbId":"tt1520211",
      "tvdbId":153021,
      "tmdbId":1402,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/153021-38.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/153021-77.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/153021-g44.jpg"
      },
      "genres":[
         {
            "id":1,
            "name":"Action"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":6,
            "name":"Horror"
         },
         {
            "id":20,
            "name":"Suspense"
         }
      ],
      "added":"2014-08-08T13:31:18.617",
      "lastUpdated":"2016-08-18T03:04:00.28",
      "followedByUser":false,
      "slugName":"the-walking-dead"
   },
   {
      "id":279121,
      "name":"The Flash (2014)",
      "followers":7069,
      "firstAired":"2014-10-07T20:00:00-04:00",
      "country":"us",
      "overview":"After a particle accelerator causes a freak storm, CSI Investigator Barry Allen is struck by lightning and falls into a coma. Months later he awakens with the power of super speed, granting him the ability to move through Central City like an unseen guardian angel. Though initially excited by his newfound powers, Barry is shocked to discover he is not the only \"meta-human\" who was created in the wake of the accelerator explosion – and not everyone is using their new powers for good. Barry partners with S.T.A.R. Labs and dedicates his life to protect the innocent. For now, only a few close friends and associates know that Barry is literally the fastest man alive, but it won't be long before the world learns what Barry Allen has become... The Flash.",
      "runtime":45,
      "status":"Continuing",
      "network":"The CW",
      "airDay":"Tuesday",
      "airTime":"8:00 PM",
      "contentRating":"TV-14",
      "imdbId":"tt3107288",
      "tvdbId":279121,
      "tmdbId":60735,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/279121-37.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/279121-23.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/279121-g7.jpg"
      },
      "genres":[
         {
            "id":1,
            "name":"Action"
         },
         {
            "id":2,
            "name":"Adventure"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":8,
            "name":"Science-Fiction"
         }
      ],
      "added":"2014-08-08T13:45:59.087",
      "lastUpdated":"2016-08-17T03:09:18.7",
      "followedByUser":false,
      "slugName":"the-flash-2014"
   },
   {
      "id":80379,
      "name":"The Big Bang Theory",
      "followers":6922,
      "firstAired":"2007-09-25T20:00:00-04:00",
      "country":"us",
      "overview":"What happens when hyperintelligent roommates Sheldon and Leonard meet Penny, a free-spirited beauty moving in next door, and realize they know next to nothing about life outside of the lab. Rounding out the crew are the smarmy Wolowitz, who thinks he's as sexy as he is brainy, and Koothrappali, who suffers from an inability to speak in the presence of a woman.",
      "runtime":25,
      "status":"Continuing",
      "network":"CBS",
      "airDay":"Monday",
      "airTime":"8:00 PM",
      "contentRating":"TV-PG",
      "imdbId":"tt0898266",
      "tvdbId":80379,
      "tmdbId":1418,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/80379-43.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/80379-38.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/80379-g28.jpg"
      },
      "genres":[
         {
            "id":3,
            "name":"Comedy"
         }
      ],
      "added":"2014-08-08T13:27:13.18",
      "lastUpdated":"2016-08-18T03:03:10.947",
      "followedByUser":false,
      "slugName":"the-big-bang-theory"
   },
   {
      "id":176941,
      "name":"Sherlock",
      "followers":6387,
      "firstAired":"2010-07-25T20:30:00+01:00",
      "country":"gb",
      "overview":"Sherlock is a British television crime drama that presents a contemporary adaptation of Sir Arthur Conan Doyle's Sherlock Holmes detective stories. Created by Steven Moffat and Mark Gatiss, it stars Benedict Cumberbatch as Sherlock Holmes and Martin Freeman as Doctor John Watson.",
      "runtime":90,
      "status":"Continuing",
      "network":"BBC One",
      "airDay":"Sunday",
      "airTime":"8:30 PM",
      "contentRating":"TV-14",
      "imdbId":"tt1475582",
      "tvdbId":176941,
      "tmdbId":19885,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/176941-11.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/176941-3.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/176941-g5.jpg"
      },
      "genres":[
         {
            "id":2,
            "name":"Adventure"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":14,
            "name":"Crime"
         },
         {
            "id":16,
            "name":"Mystery"
         },
         {
            "id":21,
            "name":"Thriller"
         }
      ],
      "added":"2014-08-08T13:32:27.247",
      "lastUpdated":"2016-08-17T03:07:09.747",
      "followedByUser":false,
      "slugName":"sherlock"
   },
   {
      "id":263365,
      "name":"Marvel's Agents of S.H.I.E.L.D.",
      "followers":5372,
      "firstAired":"2013-09-24T22:00:00-04:00",
      "country":"us",
      "overview":"Phil Coulson (Clark Gregg, reprising his role from \"The Avengers\" and \"Iron Man\" ) heads an elite team of fellow agents with the worldwide law-enforcement organization known as SHIELD (Strategic Homeland Intervention Enforcement and Logistics Division), as they investigate strange occurrences around the globe. Its members -- each of whom brings a specialty to the group -- work with Coulson to protect those who cannot protect themselves from extraordinary and inconceivable threats, including a formidable group known as Hydra.",
      "runtime":45,
      "status":"Continuing",
      "network":"ABC (US)",
      "airDay":"Tuesday",
      "airTime":"10:00 PM",
      "contentRating":"TV-PG",
      "imdbId":"tt2364582",
      "tvdbId":263365,
      "tmdbId":1403,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/263365-16.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/263365-26.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/263365-g7.jpg"
      },
      "genres":[
         {
            "id":1,
            "name":"Action"
         },
         {
            "id":2,
            "name":"Adventure"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":5,
            "name":"Fantasy"
         },
         {
            "id":8,
            "name":"Science-Fiction"
         }
      ],
      "added":"2014-08-08T13:39:45.967",
      "lastUpdated":"2016-08-18T03:05:30.987",
      "followedByUser":false,
      "slugName":"marvels-agents-of-shield"
   },
   {
      "id":81189,
      "name":"Breaking Bad",
      "followers":5227,
      "firstAired":"2008-01-20T21:00:00-04:00",
      "country":"us",
      "overview":"Walter White, a struggling high school chemistry teacher, is diagnosed with advanced lung cancer. He turns to a life of crime, producing and selling methamphetamine accompanied by a former student, Jesse Pinkman, with the aim of securing his family's financial future before he dies.",
      "runtime":45,
      "status":"Ended",
      "network":"AMC",
      "airDay":"Sunday",
      "airTime":"9:00 PM",
      "contentRating":"TV-MA",
      "imdbId":"tt0903747",
      "tvdbId":81189,
      "tmdbId":1396,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/81189-10.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/81189-21.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/81189-g21.jpg"
      },
      "genres":[
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":14,
            "name":"Crime"
         },
         {
            "id":20,
            "name":"Suspense"
         },
         {
            "id":21,
            "name":"Thriller"
         }
      ],
      "added":"2014-08-08T13:27:33.917",
      "lastUpdated":"2016-08-13T03:01:47.063",
      "followedByUser":false,
      "slugName":"breaking-bad"
   },
   {
      "id":247808,
      "name":"Suits",
      "followers":4835,
      "firstAired":"2011-06-24T21:00:00-04:00",
      "country":"us",
      "overview":"Suits follows college drop-out Mike Ross, who accidentally lands a job with one of New York's best legal closers, Harvey Specter. They soon become a winning team with Mike's raw talent and photographic memory, and Mike soon reminds Harvey of why he went into the field of law in the first place.",
      "runtime":45,
      "status":"Continuing",
      "network":"USA Network",
      "airDay":"Wednesday",
      "airTime":"9:00 PM",
      "contentRating":"TV-14",
      "imdbId":"tt1632701",
      "tvdbId":247808,
      "tmdbId":37680,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/247808-27.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/247808-43.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/247808-g17.jpg"
      },
      "genres":[
         {
            "id":4,
            "name":"Drama"
         }
      ],
      "added":"2014-08-08T13:33:45.423",
      "lastUpdated":"2016-08-18T03:04:21.37",
      "followedByUser":false,
      "slugName":"suits"
   },
   {
      "id":274431,
      "name":"Gotham",
      "followers":4718,
      "firstAired":"2014-09-23T20:00:00-04:00",
      "country":"us",
      "overview":"An action-drama series following rookie detective James Gordon as he battles villains and corruption in pre-Batman Gotham City.",
      "runtime":45,
      "status":"Continuing",
      "network":"FOX (US)",
      "airDay":"Monday",
      "airTime":"8:00 PM",
      "contentRating":"TV-14",
      "imdbId":"tt3749900",
      "tvdbId":274431,
      "tmdbId":60708,
      "language":"en",
      "images":{
         "poster":"//static.trackseries.tv/banners/posters/274431-17.jpg",
         "fanart":"//static.trackseries.tv/banners/fanart/original/274431-22.jpg",
         "banner":"//static.trackseries.tv/banners/graphical/274431-g6.jpg"
      },
      "genres":[
         {
            "id":1,
            "name":"Action"
         },
         {
            "id":4,
            "name":"Drama"
         },
         {
            "id":8,
            "name":"Science-Fiction"
         },
         {
            "id":14,
            "name":"Crime"
         },
         {
            "id":21,
            "name":"Thriller"
         }
      ],
      "added":"2014-08-08T13:44:55.4",
      "lastUpdated":"2016-08-17T03:08:55.473",
      "followedByUser":false,
      "slugName":"gotham"
   }
]

為了使用這些應用程序中的API,我用一組方法創建了一個稱為TsApiService的類,通過.NET框架和流行的JSON.NET庫的HttpClient類,負責下載JSON,解析它并返回一組可以使用C#很容易地操縱的對象。為了更好地構成我的解決方案, 我已經決定把所有的通信相關類與REST API (如服務和實體)放置在另一個叫做InfoSeries.Core的便攜式類庫(Portable Class Library)中,這是一個與實際Xamarin Forms應用程序的相比不同的PCL。

這就是負責解析之前的JSON的方法返回一個C#對象列表:

public async Task<List<SerieFollowersVM>> GetStatsTopSeries()
{
    using (HttpClient client = new HttpClient())
    {
        try
        {
            var response = await client.GetAsync("//api.trackseries.tv/v1/Stats/TopSeries");
            if (!response.IsSuccessStatusCode)
            {
                var error = await response.Content.ReadAsAsync<TrackSeriesApiError>();
                var message = error != null ? error.Message : "";
                throw new TrackSeriesApiException(message, response.StatusCode);
            }
            return await response.Content.ReadAsAsync<List<SerieFollowersVM>>();
        }
        catch (HttpRequestException ex)
        {
            throw new TrackSeriesApiException("", false, ex);
        }
        catch (UnsupportedMediaTypeException ex)
        {
            throw new TrackSeriesApiException("", false, ex);
        }
    }
}

HttpClient類的GetAsync() 方法執行GET請求到URL,返回結果包含JSON響應的字符串。這個結果存儲在響應的Content 屬性:如果請求成功(我們使用IsSuccessStatusCode 屬性檢查這種情況),我們使用Content 屬性公開的ReadAsAsync< T >方法自動轉換為JSON導致SerieFollowersVM 對象的集合。SerieFollowersVM 無非是一個映射JSON響應的每個屬性的類 (如namecountryruntime)到一個C#屬性:

public class SerieFollowersVM
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Followers { get; set; }
    public DateTimeOffset FirstAired { get; set; }
    public string Country { get; set; }
    public string Overview { get; set; }
    public int Runtime { get; set; }
    public string Status { get; set; }
    public string Network { get; set; }
    public DayOfWeek? AirDay { get; set; }
    public string AirTime { get; set; }
    public string ContentRating { get; set; }
    public string ImdbId { get; set; }
    public int TvdbId { get; set; }
    public string Language { get; set; }
    public ImagesSerieVM Images { get; set; }
    public ICollection<GenreVM> Genres { get; set; }
    public DateTime Added { get; set; }
    public DateTime LastUpdated { get; set; }
    public string SlugName { get; set; }
}

在GitHub的完整示例(為了方便各位讀者,小編已經為大家整理了,請點擊這里下載)中你會發現很多這樣的類(映射各種被TrackSeries API返回的JSON響應)。此外,TsApiService 將實現另外的方法,一個用于我們想在我們的應用程序中利用的每個API的方法。我不會詳細解釋每個方法,因為這將超出本文的范圍,你可以在GitHub上看到所有的細節。對于這篇文章的目的,你只需要知道服務只是公開了一組方法,我們可以在各種ViewModels中使用來檢索可用的電視節目的信息。

注意:默認情況下,HttpClient 類沒有提供一個ReadAsAsync< T >方法,能夠自動對JSON響應為C#對象進行反序列化。為了獲得該擴展方法,我們需要添加Microsoft.AspNet.WebApi.Client NuGet包到便攜類庫(Portable Class Library)。為了讓它正常工作,你需要將這個包添加到解決方案的每個項目(Xamarin Forms PCL、Core PCL和所有特定于平臺的項目)。

然而,為了正確利用依賴注入(dependency injection),我們需要一個接口來描述TsApiService 類提供的操作。這就是我們的接口的樣子:

public interface ITsApiService
{
    Task<List<SerieFollowersVM>> GetStatsTopSeries();
    Task<SerieVM> GetSerieByIdAll(int id);
    Task<SerieInfoVM> GetSerieById(int id);
    Task<List<SerieSearch>> GetSeriesSearch(string name);
    Task<SerieFollowersVM> GetStatsSerieHighlighted();
}

現在我們有了一個服務,我們可以學習(多虧Prism)我們可以如何注冊到它的依賴容器,它會自動注入在我們的ViewModels。實際上,從這個角度來看,沒有什么特別強調:這與其他MVVM框架使用的方法是相同的,利用依賴注入的方法。首先,我們需要注冊我們想要在容器中使用的接口和實現之間的協會。在Prism的情況下,我們需要用App類的RegisterTypes()方法,通過使用Container對象和RegisterType< T, Y >()方法(其中T 是接口,Y是具體實現):

protected override void RegisterTypes()
{
    Container.RegisterTypeForNavigation<MainPage>();
    Container.RegisterType<ITsApiService, TsApiService>();
}

MainPage TsApiService 都在容器注冊了,我們可以在ViewModel獲得它,只需添加一個參數在公共構造函數,就像以下示例:

public class MainPageViewModel : BindableBase
{
    private readonly ITsApiService _apiService;
    public MainPageViewModel(ITsApiService apiService)
    {
        _apiService = apiService;
    }
}

MainPageViewModel 類將被加載時,我們已經在容器注冊的ITsApiService實現(在我們的例子中是TsApiService 類)將自動注入構造函數的參數,允許我們以我們將在ViewModel創建的所有其他的方法和屬性來使用它。使用這種方法,我們將容易改變服務的實現,以防我們需要它:它將足以改變App類的注冊類型,并且每個ViewModel將自動開始使用新的版本。

處理導航的生命周期

現在我們有一個服務,它提供了一種方法來檢索頂級系列的列表,在ViewModel加載時我們需要調用它。我們的目標是顯示(在應用程序的主頁)最熱門的電視節目列表。但是,我們即將面對使用MVVM模式時的一個常見的問題:檢索頂級系列列表的方法是異步的,但是隨著當前實現,唯一我們可以執行數據加載的地方就是ViewModel的構造函數,它不能執行異步調用(在C#中,事實上,一個類的構造函數不能用async關鍵字,因此,你不能用等待前綴的方法)。在non-MVVM應用程序中,這個問題很容易解決,因為導航的生命周期方法是由每一個平臺基本提供的。Xamarin Forms毫無例外,我們可以利用(在XAML頁面類的后面的代碼)OnAppearing()OnDisappearing()方法:因為它們是事件,我們可以沒有問題地調用異步代碼。

為了解決這個問題,Prism提供一個稱為INavigationAware的接口,我們可以在ViewModels實現。當我們實現它,我們可以訪問OnNavigatedTo()OnNavigatedFrom()事件,我們可以使用它們來執行數據加載或清理操作。這就是實現這個接口后我們的MainPageViewModel 的樣子:

public class MainPageViewModel : BindableBase, INavigationAware
{
    private readonly TsApiService _apiService;
    private ObservableCollection<SerieFollowersVM> _topSeries;
    public ObservableCollection<SerieFollowersVM> TopSeries
    {
        get { return _topSeries; }
        set { SetProperty(ref _topSeries, value); }
    }
    public MainPageViewModel(TsApiService apiService)
    {
        _apiService = apiService;
    }
    public void OnNavigatedFrom(NavigationParameters parameters)
    {
    }
    public async void OnNavigatedTo(NavigationParameters parameters)
    {
        var result = await _apiService.GetStatsTopSeries();
        TopSeries = new ObservableCollection<SerieFollowersVM>(result);
    }
}

正如你所看到的,現在我們實現了一個稱為OnNavigatedTo()的方法,我們可以安全地執行異步調用和加載數據。我們調用TsApiService類的GetStatsTopSeries()方法,我們封裝結果集合到ObservableCollection屬性。這是我們要連接的屬性,通過綁定到一個ListView 控件,為了在主頁顯示電視節目列表。

出于完整性的考慮,這是MainPage的XAML的樣子:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="//xamarin.com/schemas/2014/forms"
             xmlns:x="//schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="InfoSeries.Views.MainPage"
             Title="Info Series">
  <ContentPage.Resources>
    <ResourceDictionary>
      <DataTemplate x:Key="TopSeriesTemplate">
        <ViewCell>
          <ViewCell.View>
            <Grid>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="2*" />
              </Grid.ColumnDefinitions>
              <Image Source="{Binding Images.Poster}" Grid.Column="0" x:Name="TopImage" />
              <StackLayout Grid.Column="1" Margin="12, 0, 0, 0" VerticalOptions="Start">
                <Label Text="{Binding Name}" FontSize="18" TextColor="#58666e" FontAttributes="Bold" />
                <StackLayout Orientation="Horizontal">
                  <Label Text="Runtime: " FontSize="14" TextColor="#58666e" />
                  <Label Text="{Binding Runtime}" FontSize="14" TextColor="#98a6ad" Margin="5, 0, 0, 0" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                  <Label Text="Air day: " FontSize="14" TextColor="#58666e" />
                  <Label Text="{Binding AirDay}" FontSize="14" TextColor="#98a6ad" Margin="5, 0, 0, 0" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                  <Label Text="Country: " FontSize="14" TextColor="#58666e" />
                  <Label Text="{Binding Country}" FontSize="14" TextColor="#98a6ad" Margin="5, 0, 0, 0" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                  <Label Text="Network: " FontSize="14" TextColor="#58666e" />
                  <Label Text="{Binding Network}" FontSize="14" TextColor="#98a6ad" Margin="5, 0, 0, 0" />
                </StackLayout>
              </StackLayout>
            </Grid>
          </ViewCell.View>
        </ViewCell>
      </DataTemplate>
    </ResourceDictionary>
  </ContentPage.Resources>
  <ListView ItemTemplate="{StaticResource TopSeriesTemplate}"
            ItemsSource="{Binding Path=TopSeries}" RowHeight="200"/>
</ContentPage>

如果你已經知道Xamarin Forms(或一般的XAML),你應該會覺得這段代碼很容易理解:頁面包含一個ListView 控件、一個描述單個電視節目的模板。我們展示節目的海報,還有一些其他信息,如標題、運行時、生產國家等等。因為(根據命名約定)MainPageViewModel 類已經設置為頁面的BindingContext ,我們可以通過綁定ListViewItemsSource屬性和我們之前在ViewModel填充的TopSeries集合進行簡單地連接。

導航與參數

我們已經看到了如何利用OnNavigatedTo()方法來執行數據加載,但通常這種方法在另一個場景中也是有用的:檢索參數通過前一頁,這通常需要了解當前的上下文(在我們的示例中,在我們的應用程序的詳細信息頁面,我們需要理解用戶已經選擇的電視節目)。

Prism支持這個特性是由于一個稱為NavigationParameters的類稱,可以作為NavigationServiceNavigationAsync()方法的一個可選參數傳遞,它被自動包括作為OnNavigatedTo()OnNavigatedFrom()事件的參數。讓我們看看如何通過向我們的應用程序添加詳細信息頁面利用這個特性,顯示選擇的節目的一些額外的信息。

第一步是同時添加一個新頁面到Views 文件夾中(稱為DetailPage.xaml)和一個新類到ViewModels文件夾中(稱為DetailPageViewModel.cs)。你需要記住,每一頁都需要在App類的容器中注冊,在OnRegisterTypes()方法內:

protected override void RegisterTypes()
{
    Container.RegisterTypeForNavigation<MainPage>();
    Container.RegisterTypeForNavigation<DetailPage>();
    Container.RegisterType<ITsApiService, TsApiService>();
}

由于命名約定,我們不需要做任何特別的操作:新頁面和新ViewModel已經連接。現在我們需要通過ListView控件中所選條目到新頁面。讓我們先看看如何在主頁處理選擇。通過使用由我親愛的朋友Corrado Cavalli創建的庫,我們會得到一些幫助,它允許你在Xamarin Forms應用程序實現行為。可用的行為中的EventToCommand允許我們連接暴露于控件的任何事件與ViewModel中定義的命令。我們要用它來連接ListView 控件的ItemTapped 事件(當用戶點擊列表中的一個項目時會觸發)與我們要在MainPageViewModel中創建來觸發導航到詳細頁面的命令。

你可以從NuGet安裝由Corrado創建的套包,它的名字叫Corcav.Behaviors。使用它你需要添加一個額外的名稱空間到MainPage的root,像下面這個示例:

<ContentPage xmlns="//xamarin.com/schemas/2014/forms"
             xmlns:x="//schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:behaviors="clr-namespace:Corcav.Behaviors;assembly=Corcav.Behaviors"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="InfoSeries.Views.MainPage"
             Title="Info Series">
    ...
</ContentPage>

然后你可以申請ListView 控件的行為,就像你在普通Windows應用程序中會做的一樣:

<ListView ItemTemplate="{StaticResource TopSeriesTemplate}"
          ItemsSource="{Binding Path=TopSeries}" RowHeight="200">
  <behaviors:Interaction.Behaviors>
    <behaviors:BehaviorCollection>
      <behaviors:EventToCommand EventName="ItemTapped" Command="{Binding GoToDetailPage}" />
    </behaviors:BehaviorCollection>
  </behaviors:Interaction.Behaviors>
</ListView>

由于這種行為,我們已經連接了ListView 控件的ItemTapped 事件與我們要在ViewModel定義的稱為GoToDetailPage 的命令。從一個框架的角度,Prism沒有做任何不尋常的事幫助開發者實現命令:它只是提供了一個稱為DelegateCommand的類,這允許你定義操作來執行調用命令和可選的條件來啟動命令。如果你有一些MVVM Light以往的經驗,它會以RelayCommand 類那樣完全相同的方式運作。以下是我們的命令在MainPageViewModel 類的樣子:

private DelegateCommand<ItemTappedEventArgs> _goToDetailPage;
public DelegateCommand<ItemTappedEventArgs> GoToDetailPage
{
    get
    {
        if (_goToDetailPage == null)
        {
            _goToDetailPage = new DelegateCommand<ItemTappedEventArgs>(async selected =>
            {
                NavigationParameters param = new NavigationParameters();
                param.Add("show", selected.Item);
                await _navigationService.NavigateAsync("DetailPage", param);
            });
        }
        return _goToDetailPage;
    }
}

我們已經創建了的命令是一個參數化命令;事實上,屬性類型是DelegateCommand< ItemTappedEventArgs >:這種方式,在方法內部,我們獲得存儲在Item 屬性中的選中的條目。命令觸發時調用的方法展示了如何用參數的工作原理導航:首先我們創建一個新的NavigationParameters對象,最后,只不過是一個你可以存儲鍵/值對的字典。因此,我們只需添加一個新項,作為關鍵,關鍵字show ,作為值,選中的項的類型是SerieFollowersVM。這是與我們在App類中看到的導航的唯一的區別:其余的都是一樣的,這意味著我們調用NavigationServicetheNavigateAsync()方法,傳遞標識詳細信息頁面(DetailPage)和參數的關鍵參數。

重要事項!App類中,我們能夠自動使用NavigationService ,因為它繼承自PrismApplication 類。如果我們要在ViewModel中使用NavigationService (像在這種情況下),我們需要使用基于依賴注入(dependency injection)的傳統方法。NavigationService 實例已經在Prism容器注冊,所以我們只需要添加一個INavigationService 參數到MainPageViewModel的公共構造函數:

public MainPageViewModel(TsApiService apiService, INavigationService navigationService)
{
    _apiService = apiService;
    _navigationService = navigationService;
}

既然我們已經完成了導航到詳細頁面,我們就需要檢索DetailPageViewModel 類的參數。第一步,像我們為MainPageViewModel做的那樣,讓它從INavigationAware 接口繼承,除了BindableBase 類。通過這種方式,我們可以訪問OnNavigatedTo()事件:

public class DetailPageViewModel : BindableBase, INavigationAware
{
    private SerieFollowersVM _selectedShow;
    public SerieFollowersVM SelectedShow
    {
        get { return _selectedShow; }
        set { SetProperty(ref _selectedShow, value); }
    }
    public DetailPageViewModel()
    {
    }
    public void OnNavigatedFrom(NavigationParameters parameters)
    {
    }
    public void OnNavigatedTo(NavigationParameters parameters)
    {
        SelectedShow = parameters["show"] as SerieFollowersVM;
    }
}

前面的代碼顯示了如何處理我們從主頁收到的參數:同一個我們通過的MainPageViewModel對象到作為 OnNavigatedTo()方法的參數傳遞的NavigateAsync()方法。因此,我們可以用show 鍵簡單的檢索先前存儲的項。在這種情況下,因為我們預計SerieFollowersVM類型的對象,我們可以執行一個計算并將其存儲到稱為SelectedShow的ViewModel的屬性中。多虧了這個屬性,我們可以利用綁定到選擇顯示的各種信息連接到XAML頁面的空間。以下是DetailPage.xaml的樣子:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="//xamarin.com/schemas/2014/forms"
             xmlns:x="//schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             Title="{Binding Path=SelectedShow.Name}"
             x:Class="InfoSeries.Views.DetailPage">
  <StackLayout>
    <Image x:Name="InfoPoster"
           Source="{Binding Path=SelectedShow.Images.Fanart}" Aspect="AspectFill" />
    <Label Text="{Binding Path=SelectedShow.Overview}" LineBreakMode="WordWrap" FontSize="13" TextColor="#98a6ad" Margin="15" />
  </StackLayout>
</ContentPage>

內容很簡單:我們顯示show的圖片(存儲在SelectedShow.Images.Fanart屬性)和一段簡要描述(存儲在SelectedShow.Overview屬性)。

結束語

在這篇文章中,我們已經看到在用Prism 作為MVVM框架創建的Xamarin Forms應用程序中處理導航和依賴注入的一些基本概念。在下一篇文章中,我們將看到幾個高級場景,有關導航和特定于平臺的代碼的處理。你能在GitHub存儲庫找到這篇文章使用的示例應用程序(為了方便各位讀者,小編已經為大家整理了,請點擊這里下載)。

本文翻譯自:

 

PS: 關于移動開發,這些產品你可以關注>>
關于移動開發的最新資訊和產品推薦,請<>!

標簽:移動開發導航控件Xamarin

本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn


為你推薦

  • 推薦視頻
  • 推薦活動
  • 推薦產品
  • 推薦文章
  • 慧都慧問
掃碼咨詢


添加微信 立即咨詢

電話咨詢

客服熱線
023-68661681

TOP
国产 亚洲 中文字幕 在线 | 国精产品三区四区有限公司 | 四虎成人免费观看在线网址 | 老王轻一点儿好爽在深一点 | 色网站在线观看 | 国产深夜男女无套内射 | 亚洲一区 中文字幕 久久 | 国产午夜伦鲁鲁 | 99国产精品人妻无码一区 | 不卡免费在线视频 | 性欧美另类 | 国产成人精品高清在线观看99 | 国产精品麻豆久久久 | 免费国产直接看片av | 日本VA在线视频播放 | 国产精品天天狠天天看 | 一本大道一卡二卡三卡四卡在线观 | 蜜臀91丨九色丨蝌蚪 | 亚洲国色天香卡2卡3卡4 | 999国产精华是正规产品吗 | 成人免费视频l免费观看 | 无限看片的动漫视频在线观看 | 欧亚乱熟女一区二区在线 | 国产AV一区二区三区传媒 | 中文国产成人精品久久下载 | 欧美综合色网 | 少妇人妻真实偷人精品视频 | 免费日产乱码卡一卡 | 色丁香久久 | 精品一品国产午夜福利视频 | 影音先锋影av色资源网 | 久久国产香蕉视频 | 日本不卡高清免费v日本 | 中国xxxxwwww泡妞的软件 | 天堂网在线看 | 伦 乱真实故事 | 精品国产国产精2024久久日 | A片扒开双腿猛进入免费观看 | 92kyy福利合集| 国产精品久久久久久久久久直 | 最近免费观看高清日本大全 | 亚洲 欧美 制服 另类 无码 | 色网站在线视频 | 欧美日韩精品一区二区三区视频在线 | 日本高清另类videohd | 午夜精品成人毛片 | 99久久亚洲综合精品网站 | 天天草夜夜草 | 三八色 | 国内一级黄色片 | 韩国伦理片在线2018 | 麻豆最新国产剧情AV原创免费 | 国产精品久久毛片A片杨颖 国产精品久久人妻互换 | 2o18国产大陆天天弄 | 色视频2 | 91最新网站| 黄色网址在线视频 | 五月丁香合缴情网 | 最好影院在线免费看 | 性做爰添LBB在线视频 | 好吊妞无缓冲视频观看 | 亚洲欧美日韩国产成人app | 军婚H全肉辣文 | 国产精品久久久久久久久久久久久久 | 国产亚洲精品久久久久久一区二区 | 欧美性xx18一19| 欧美性生交XXXXX无码久久久 | 国产第一综合另类色区奇米 | 婷婷久月 | 欧美一级中文字幕 | 美女逼逼图片 | 国产妇女视频 | 亚洲护士老师的毛茸茸 | 99久久亚洲综合精品网站 | 一个综合色 | 被黑人强到高潮喷水A片 | 91精品国产一区 | 国产精品网站在线观看免费传媒 | 亚洲二区在线视频 | 免费精品国产人妻国语三上优雅 | 国产精品久久久久久99人妻精品 | 偷拍快播| 自拍视频在线观看完整版 | 久久狠狠色情网 | 黄乱色伦 | 老师解我胸罩让我去他办公室 | 思思玖玖玖在线精品视频 | 日本 韩国 三级 国产 欧美 | 国产乱码人妻一区二区三区 | 蜜月a 免费一区二区三区 | 国产午夜免费视频片夜色 | 国产在线观看免费视频软件 | 成人A片产无码免费视频软件 | 2020年精品国产品在线网站 | 四虎影视在线看免费完整版 | 曰本女人一级毛片看一级毛 | 久久国产乱子精品免费女 | 欧美日韩资源 | 九九免费精品视频 | 在线播放精品 | 啪啪婷婷| 免费国产又色又爽又黄的网站 | 国产成人mv 在线播放 | 亚洲A片无码一区二区三区在线 | 久久亚洲欧美 | 一区二区三区不卡视频 | 一级黄色片网 | 亚洲乱码无人区卡1卡2卡3 | 精品国产露脸久久AV麻豆 | 日本亚洲欧美 | 久久91精品国产91久久户 | 亚洲精品深夜AV无码一区二区 | 美国三圾片在线观看 | 亚洲欧美中文字幕高清在线 | 在线视频精品免费观看10 | 久久久久久久一线毛片 | 国内精品久久久久久久久 | 粗大的内捧猛烈进出A片黄 粗大的内捧猛烈进出A片小说 | 无套内射无矿码免费看黄 | 搞黄网站免费看 | 日本一区二区不卡视频 | 国产综合无码一区二区色蜜蜜 | 日韩一卡二卡3卡四卡2021高清妈妈的朋友 | 国内自拍 在线 亚洲 欧美 | 亚洲AV久久无码精品九九九小说 | 精品爽爽久久久久久蜜臀 | 欧美XXXXX俄罗斯乱妇 | 日韩一卡2卡3卡4卡乱码网站导航 | 国精产品一二二区传媒公司 | 亚洲精品九色在线网站 | 久久国产精品-久久精品 | 亚洲精品久久久AV无码专区 | 免看黄大片AA | 人善交zzzxxx另类 | 九月丁香婷婷亚洲综合色 | 欧美色丁香 | 亚洲欧美久久久久久久久久爽 | 性一交一乱一伦在线播放 | 波多野结衣在线家庭教师 | 天天躁日日躁狠狠躁黑人躁 | 护士毛茸茸 | 黄色一区二区三区 | 女人被添全过程A片免费视频 | 天天躁了天天躁了天天躁 | 麻豆一二三四区乱码 | 天堂岛WWW最新版在线资源 | 高潮真紧好爽我视频 | 日本黄色一区 | 久久99九九99九九精品 | 亚洲久久无码在线视频 | 在线观看国产三级视频 | 久操资源在线 | 六十路の高齢熟女が中文在线播放 | 又黄又大又猛的A片 | 一区二区三区线日本 | 天天草综合网 | k8禁忌美国在线观看 | h片在线观看视频 | 99国内精品久久久久久久 | 中文字幕人妻熟女在线 | 影音先锋av999资源网 | 1区2区3区4区产品在线线乱码 | 伊人久久综在合线亚洲91 | 99精品影视 | 日本久久精品 | 国产高潮久久精品AV无码 | 97在线免费看视频 | A国产一区二区免费入口 | 人人模人人干 | 少妇毛又多又黑A片欧美 | 国偷盗摄自产福利一区在线 | 麻豆一区二区免费播放网站 | 色噜噜狠狠狠狠色综合久不 | 日本高清视频在线无吗 | 日韩做A爰片久久毛片A片毛茸茸 | 国产人妻久久久精品麻豆 | 国产黄的网站免费 | 中文字幕国产视频 | 中文字幕日韩在线观看 | 毛片资源 | 国产福利一区二区三区在线观看 | 99re在线视频免费观看 | 天堂tv亚洲tv日本tv欧洲 | 高清国产天堂在线BT免费 | 超清波多野结衣精品一区 | 亚洲午夜视频在线 | 2022麻豆福利午夜久久 | 91精品国产高清久久久久 | 丰满熟女人妻大乳波多野吉衣 | 中文字幕在线观看亚洲视频 | 美女被c网站 | 天天躁日日躁 疯人影院 | 国产精品亚洲污污网站入口 | 久久精品99久久香蕉国产色戒 | 成人AV久久一区二区三区 | 国产精品香蕉视频在线 | 在线视频一区二区三区四区 | 青草影院在线观看 | 国产一级大片免费看 | 欧美精品一区二区少妇免费A片 | 久久久国产一区二区三区四区小说 | 国产片入口 | 国产精品麻豆久久久 | 亚洲日本中文 | 日韓無碼人妻不倫A片 | 国产成人精品福利网站人 | 日本高清视频免费观看 | 日本一区二区在线播放 | 宝贝把内衣脱了我想吃胸 | 少妇被多人C夜夜爽爽 | 国产视频日韩 | 精品亚洲成A人7777在线观看 | 国产一性一交一伦一A片小说 | 久久久久久久久久久大尺度免费视频 | 波多野一区二区三区在线 | 欧美在线看视频 | 久久精品国产99国产精偷 | 欧美精品毛片久久久久久久 | 国产麻豆精品一区 | 亚洲欧美日本综合一区二区三区 | 精品亚洲卡一卡2卡三卡乱码 | 中文有码中文字幕免费视频 | 亚洲精品久久久久久久观小说 | 新婚夜被五个伴郎强H | 99在线国产 | 国产成人免费网站 | 精品久久久久久无码人妻国产馆 | 欧美在线观看第一页 | 午夜福利电影 | 精品国产亚洲AV麻豆 | 久久久久久综合对白国产 | 日本无码精油按摩WWW视频 | 中文线码中文高清播放中 | 中文在线免费不卡视频 | 日本韩国伦理片 | 国产在线观看免费视频在线 | 日日夜夜影院 | 成年视频xxxxx在线网站 | 欧美三圾片在线观看 | 免费一二三-片 | 99re最新视频| 99热这里只就有精品22 | 成全免费高清观看在线 | 亚洲乱轮视频 | 伊人狠狠丁香婷婷综合尤物 | jizz韩国 | 四房播播网址 | 粉嫩被粗大进进出出视频 | 午夜毛片在线观看 | 高清电视剧 ok影视 高清成人影院 | 黑帮少爷爱上我第一季在线观看 | 亚洲精品中文字幕乱码影院 | 双腿挂他肩上撞击轻哼 | 免费在线a | 国产专区_爽死2024 | 免费成人一级片 | 伦理片在线观看午夜伦理电影三级网 | 欧美黄色免费网址 | 精品视频| 久久精品视频免费看 | 欧美精品v | 亚洲一区日韩一区欧美一区a | 日本伦理网站 | 黄网站免费永久在线观看下载 | 国产精品爽爽久久久久久无码 | 秋霞97| 成熟妇女免费看A片视频 | 99久久久国产精品免费牛牛四川 | LINODEIPHONE孕妇视频欢迎你 | 中国国产成人精品久久 | 国产又爽又大又黄A片软件 国产又爽又大又黄A片图片 | 黄页网站在线观看 | 久久成人18免费网站 | 88华人永久免费 | 日日摸人人拍人人澡 | 中文字幕中文字幕在线 | 97福利视频精品第一导航 | 欧美xxxxx在线观看 | 国产AV午夜精品一区二区入口 | 影音先锋 av男人资源 | 在线看无码的免费网站 | 美女大尺度裸体写真 | 九九久久国产 | 琪琪电影网午夜理论片717西瓜 | 激情文学综合丁香 | 日本一二三不卡视频 | 少妇被躁爽到高潮无码文 | 国产人妻无码一区二区三区18 | 国产真实乱xxxav | 2022国产成人福利精品视频 | 欧美97| 狠狠躁日日躁夜夜躁A片小说按摩 | 成人污污污WWW网站免费直播 | 天天天天夜夜夜夜爱爱爱爱 | 囯精品人妻无码一区二区三区99 | 一级特黄国产高清毛片97看片 | 我要爱久久影视 | 亚洲欧美一区二区三区九九九 | 桃花久久| 成年女人免费看一级人体片 | 亚洲欧美日本国产综合在线 | 国产精品涩涩涩视频网站 | 无码AV免费精品一区二区三区 | 色综合色综合色综合网址 | 国产精品久久久久久久9999 | 97caopeng| avav在线精品| 欧美韩日| 国产精品人人妻人色五月 | 国产综合亚洲区 | 久久AV亚洲精品一区无码 | 国产亚洲精品成人久久网站 | 色中色导航 | 久久久久一| 我国产码在线观看AV哈哈哈网站 | 亚洲国产欧美目韩成人综合 | 一级做a爰片久久免费 | 少妇做爰特黄A片免费看9588 | YY视频大片免费看网站 | 成人深夜视频在线观看 | 免费观看全黄做爰大片 | 日本免费在线看 | 狠狠狠狠狠狠干 | 无码无遮挡成人A片 | 戳女人屁股流水羞羞漫画 | 成人片毛片A片免费观看欧美 | 女人18毛片a级毛片 女人扒开屁股爽桶30分钟 | 日本中文字幕网站 | 精品国产乱码久久久久久浪潮小说 | 99视频只有精品 | 黄网免费观看 | 久久精品视在线-2 | 91精品国产高清久久久久久 | 羞羞麻豆国产精品1区2区3区 | 日韩色情综合网 | 亚洲AV國產国产久青草 | 亚洲一区二区三区四区五区六 | 另类网站 | 国产精品日韩 | 在线观看黄页网站 | 国产亚洲福利精品一区 | 欧美日韩视频在线第一区二区三区 | 色哟哟免费视频播放网站 | 日本一区二区三区无码苍井空 | 九九热这里只有国产精品 | 性一交| 国产一区二区精品在线观看 | 日韩在线视屏 | 精品综合久久88色鬼首页 | 免费国产又色又爽又黄的网站 | 一区二区播放 | 性色AV一区二区三区V视界影院 | 日本在线有码电影网站 | 亚洲VA天堂VA欧美片A在线 | 最近中文字幕完整版视频1 最近中文字幕完整版视频 最近中文字幕视频国语中文字幕 | 深爱五月激情 | 被黑人伦流澡到高潮HNP动漫 | 色综合AV亚洲超碰少妇 | 我们的生活第七季在线观看免费高清 | 中文字幕一区二区区免 | 狠狠色噜噜狠狠狠狠888奇米 | ed2k 大桥未久| 国产91精品新入口 | 黄频网站| 亚洲AV无码一区东京热在线播放 | 妞干网在线观看 | 国产乱码精品一区二区三区四川 | 精品无人区麻豆乱码1区2区新区 | 黄网站在线观看高清免费 | 欧美又长又大又深又爽A片特黄 | 日本公妇里乱片A片在线播放保姆 | 三要四妾国语免费观看 | 国产麻豆乱子伦午夜视频观看 | 国产成人精品综合在线 | 星崎アンリ | 精品水蜜桃久久久久久久 | 亚洲午夜精品A片久久WWW软件 | 女同网站在线观看免费 | 91午夜精品亚洲一区二区三区 | 午夜亚洲福利在线老司机 | 亚洲永久精品日本无码 | 香港三级日本三级妇三级 | 国产精品久久久久精 | 91精品国产品国语在线不卡 | 欧美亚洲天堂 | 欧美猛交XXX无码黑寡妇 | 又湿又深又爽的A片视频 | 欧美日韩成人高清色视频 | 日本aⅴ网站 | 国产乱码精品一区二区三区四川人 | 四虎永久在线精品免费观看视频 | 福利网站在线 | 97色伦图片97色伦图影院久久 | 三级视屏| 大陆黄色网 | 狼狼鲁色在线视频播放 | 欧美精品亚洲精品日韩专区 | 亚洲精品国产不卡在线观看 | 亚洲不卡高清免v无码屋 | xxxx日本免费高清视频 | 影音先锋影院中文无码 | 国产精品久久久久一区二区三区共 | 麻豆高清免费国产一区 | 四虎影视永久免费观看 | 国产真实乱人偷精品人妻69 | 四虎综合九九色九九综合色 | 色综合成人网 | 亚洲国产无线乱码在线观看 | 中文字幕亚洲男人的天堂网络 | 欧美一区二区在线观看免费网站 | 中文字幕一区二区在线播放 | 苍井空三年级片网站 | 日韩欧美日本 | 嫩B人妻精品一区二区三区 嫩草AV久久伊人妇女 | 麻豆国产成人AV在线 | 亚洲视频日韩 | 中文字幕人妻少妇引诱隔壁 | 亚洲久悠悠色悠在线播放 | AV无码国产精品午夜A片 | 日本jizz视频 | 中国国产一级毛片视频 | 苍井空毛片精品久久久 | 久久国产精品99久久小说 | 免费 在线电影 | 欧美一区二区激情视频 | 性生交大片免费看A片 | 日产电影一区二区三区 | 国产无遮挡A片无码免费 | 国产亚洲精品久久久久久老妇小说 | 国色天香精品卡一卡二卡三二百 | 国产精品系列在线一区 | 玩弄放荡人妇系列短篇下载 | 五月婷婷在线观看视频 | 国产精品久久久久不卡绿巨人 | 韩国高清乱理伦片在线观看 | 调教済み変态JK扩张调教し | 国产又黄又爽又猛免费app | 欧美精品一区二区蜜臀亚洲 | 97精品国产福利一区二区三区 | 98色精品视频在线 | 宅男噜噜噜66国产在线观看 | 和少妇邻居做爰5 | 国产第6页 | 麻豆自制传媒 国产之光黄 麻豆在视频线 | 性色小视频| 蜜色欲多人AV久久无码 | 自拍 亚洲 偷拍 青涩 | 亚洲快插 | 伊人久久亚洲精品一区 | 欧美又大又粗又爽无码视频 | 高清欧美日韩一区二区三区在线观看 | 久久99精品久久久久久 | 波多野结衣中文字幕在线播放 | 天天干夜夜添 | 日韩欧美高清DVD碟片 | 国产成人福利免费观看 | 国产午精品午夜福利757视频播放 | 欧洲成人 | 久久99精品国产麻豆宅宅 | 神马电影dy888午夜我不卡 | 久久国产精品人妻无码 | 午夜福利观看视频1 | 欧美乱大交xxxxx | 抽插内射高潮呻吟爆乳 | 美国一级毛片片aa久久综合 | 麻豆自制传媒 最新网站 | 丁香花成人电影 | 国产老熟女伦老熟妇视频 | 中文字幕区 | 日本毛茸茸 | 嗨嗨影院伦理电影 | 色天使最新网址 | 黑人巨茎大战欧美白妇 | 男女爽爽午夜18污污影院 | 日本一区二区三区视频在线观看 | 中文字幕永久 | 性爱视频在线播放 | 天天操天天干天天拍 | 色爱区综合激情五月综合色 | 松岛枫 qvod 四四房播播 | 蜜桃视频在线观看免费网址入口 | 韩国中文全部三级伦在线观看中文 | 色欲AV蜜臀AV久久浪潮AV | 一级片中文字幕 | 国产福利美女福利视频免费看 | 蜜桃色欲AV久久无码精品软件 | 无码日本电影一区二区网站 | 变天就草逼| 久久国产精品福利影集 | XL上司在线完整版无马赛克 | 国产极品JK白丝喷白浆在 | 日本不卡视频在线播放 | 噜噜噜在线观看播放视频 | 我被几个男的玩爽到死 | 91色在线观看国产 | 精品国产一区二区三区四区阿崩 | 久久澡| 纯肉高H种马艳遇风流多 | 第一次破處在线国语视频播放 | 少妇愉情理伦片丰满丰满午夜小说 | 永久免费的无码中文字幕 | 五月婷婷开心 中文字幕 | 欧美乱码卡一卡二卡四卡免费 | 想见你电影版免费观看 | 国产亚洲精品资源在线26u | MAC水蜜桃色314麻豆 | 特级毛片片A片AAAAAA | 色婷婷综合缴情综六月 | 欧美亅性猛交内射 | 久久久亚洲精品国产 | 国产99er66在线视频 | 新97在线超级碰碰免费视频 | 精品一区二区三区四区五区六区 | 久久久不卡 | 久久99久久精品国产99热 | 少妇P毛又多又黑A片免费 | 强操| 成年18网站免费视频网站 | 把腿张开看老子臊烂你免费 | 精品伊人久久大线蕉色首页 | 亚洲精品卡2卡3卡4卡乱码 | 午夜快车神马影视 | 亚洲精品免费日日日夜夜夜夜 | 动漫美女的巨乳被揉胸 | 国产乱码精品一区二区三区四川人 | 最近最新中文字幕免费高清1 | 久久精品国产波多野结衣 | 亚洲免费在线播放 | 亚洲另类欧美日本 | 果冻传媒和91制片厂a | www.av免费| 麻豆WWW传媒入口 | 精品国产人成亚洲区 | 国产乱码精品一区二区三区四川 | 日韩伦理在线 | 日韩做A爰片久久毛片A片 | 欧美日韩精品一区二区三区高清视频 | 69精品视频| 免费中文字幕囯产在线网站 | 天天射天天干天天色 | 又黄又刺激又高潮的小说 | 四虎影视884a精品国产古代 | 午夜视频a| 伧理片午夜伧理片 | 国产精品人成视频免费999 | 激情网成人 | 午夜福利123 | 三男玩一女三A片 | 99久久免费看国产精品 | 男人J进入女人P呻吟视频免费 | 91制片厂果冻传媒公司一卡 | 国产区免费在线观看 | 草莓ap| 最好看的最新的中文字幕1 最好看的最新的中文字幕3 | 免费伦费一区二区三区四区 | 韩日a级片 | 99视频精品全部免费 在线 | 无码精品A片一区二区电影在线 | 国产三级精品久久三级国专区 | 麻豆MD传媒MD0049入口 | 天天操天天干天天干 | 久久久无码精品成人A片小说 | 国产无遮挡A片又黄又爽漫画 | 北女网 | 国产亚洲精品久久久久婷婷图片 | 久久无码人妻中文国产 | 国产日韩欧美精品一区二区三区 | 成人黄18免费视频 | 亚洲老熟女AV一区二区在线播放 | 呻吟国产AV久久一区二区 | 8050午夜一级全黄毛片 | 国产美女被爽到高潮激情免费A片 | 黄色毛片免费网站 | 国产a视频 | 欧美色爱综合 | 日本三级2020 | 伦理片韩国免观看 | 日韩18视频在线观看 | 国产精品久久久久久久免费大片 | 国产毛片女人高潮叫声 | 欧美一区二区三区高清不卡tv | 成人精品国产亚洲AV久久 | 亚洲精品色情婷婷在线播放 | 色噜噜噜色噜噜噜色琪琪 | 无码免费视频AAAAAA片草莓 | 色琪琪av男人的天堂 | 千涩成人社区 | 美女搭车色诱司机 | 亚洲综合色色图 | 2024亚洲电影最新地址 | 国产在线观看免费视频在线 | 中国毛片在线观看 | 久久久久一 | 日韩精品视频免费 | 高清波多野结衣一区二区三区 | 成人国内精品久久久久影院 | 波多野结衣在线网址 | 夜夜爽夜夜操 | 日本视频在线观看免费 | 日本jizz18| 国产成人亚洲综合 | 日本阿v无码观看dvd | 亚洲精品做爰无码片 | 国内精品久久久久久中文字幕 | 亚洲国产35p | 精品人妻无码一区二区三区下一页 | 天天综合天天射 | 精品国产成人亚洲午夜福利 | 欧美另类久久久精品 | 9966久久精品免费看国产 | 国产一卡2卡3卡4卡网站免费 | 色综合视频一区二区三区 | 亚洲精品无码成人A片蜜臀 亚洲精品无码AV久久久久久小说 | 日本一区二区三区四区在线观看 | 大学生做爰全过程免费的视频 | 欧美在线观看 cao38 | 人人搞人人 | 国产福利2021最新在线观看 | 操日韩美女| 亚洲无线看天堂av | 成年黄网站色视频免费观看 | 黄色网址视频 | 久久成人小视频 | 欧美啪啪小视频 | 日本护士xxxxx高清免费 | 2018国产大陆天天弄 | 午夜影院06o6tv | 一级a级毛片 | 四虎影视在线看免费 720p | 国产永不无码精品AV永久 | 免费一级毛片免费播放 | 成人性视频免费网站在线 | fryee性欧美18 19 | 婷婷我也去俺也去狠狠爱 | 欧美变态口味重另类牲交视频 | 在线天堂WWW资源网 在线天堂中文最新版资源 在线天堂中文最新版资源天堂 | 最近高清中文在线观看国语字幕7 | 欧美最猛黑人猛男无码视频 | 亚洲精品久久精品一区二区 | 啊灬啊别停灬用力啊免费看 | 亚洲高清视频一区 | 四虎8848永久在线 | 婷婷人人爽人人爽人人A片 婷婷色情 | 丰满年轻岳欲乱中文字幕电视 | 日本色呦呦 | 99精品丰满人妻无码A片 | 国产一级特黄在线播放 | 日韩综合在线观看 | 国产精品久久久久久久久久一区 | 一区二区三区四区在线 | 久久人人玩人妻潮喷内射人人 | 美日韩在线视频 | 国产高清毛片 | 日本久久综合视频 | 免费无码无遮挡永久色情聊天下载 | 亚洲成_人网站图片 | 一区二区三区毛A片特级 | 久热这里只有精品6 | 久久福利合集精品视频 | 热99re久久国超精品首页 | 人妖另类亚洲xxxx | 亚洲中文在线无码永久色情 | 久久伊人中文字幕有码 | 久久这里只有精品1 | 日韩成人免费在线视频 | 久热爱免费精品视频在线播放 | 偷拍亚洲网友图片区 | 国产大片黄在线观看 | 国产精品萌白酱在线观看 | 日本一卡二卡三卡四卡试看 | 欧美视频一区在线 | 边做边爱完整版免费视频播放 | 美国三级网站 | 色琪琪女色窝202477 | 一区二区三区四区在线免费观看 | 秋霞成人国产理论A片 | 97视频在线观看视频在线精品 | 日本又色又爽又黄又免费网站 | 精品人妻无码一区二区三区在线 | 亚洲国产精华液2024 | 在线观看你懂的网址 | 国产极品JK白丝喷白浆免费视频 | 亚洲国产成人精品无码区5566 | 日本欧美一区二区三区乱码 | 秋霞网午夜伦理国产 | 黄色你懂的 | 欧美日韩亚洲二区在线 | 亚洲成AV人片在线观看WV | 999国产高清在线精品 | 看全黄大色黄大片老人做 | 窝窝色资源站 | 色婷婷.com| 黄视频在线观看www免费 | 色爱区综合 | 毛片三级在线观看 | 色天使亚洲 | 国产色女人| 快播免费片毛网站 | 人妻免费久久久久久久了 | 小小视频资源免费观看高清 | 国产一级毛片大陆 | 中国字字幕在线播放2024 | 久re这里只有精品最新地址 | 黄色三级视屏 | 日韩色情无码免费A片 | 国产91精品久久久久久久 | 国内精品久久久久影院优 | 丰满的日本护士xxx 疯狂撞击美妇雪白的大肉臀 | 久久亚洲精品高潮综合色A片小说 | 美女精品久久久久久国产潘金莲 | 在线观看黄网视频免费播放 | 色情无码永久免费网站APP | 午夜福利试看120秒体验区 | 最近高清中文在线字幕在线观看1 | 久草视频免费看 | 久久久香蕉视频 | 日本熟妇乱妇熟色A片在线观看 | 国产精品系列在线一区 | 日日摸夜夜添夜夜添A片看见 | 最近最好的中文字幕免费 | 久久日本无码一区二区三区 | 越南少妇做受XXX片 雨宫琴音qvod | 老湿影院视色情下 | 欧美在线网址 | 色综合天天综合高清影视 | 99爱视频免费高清在线观看 | 丁香花色情成人网站 | YELLOW字幕中文字幕免费 | 中文区中文字幕免费看 | 三级免费黄 | 欧美三级A做爰在线观看 | 亚洲免费网址 | 蜜桃传媒一区二区亚洲AV | 久久网站视频 | 水蜜桃文化传媒网站 | 亚洲AV无码午夜国产精品色软件 | 国产成人综合色 | 久久精品视频91 | 内射囯产旡码丰满少妇 | 免费性网站 | 灌满抽搐合不拢双性HBL | av基地| 亚洲第色情一区二区 | 成人电ying | 99r精品视频 | 日韩精品一卡2卡3卡4卡乱码 | AV午夜久久蜜桃传媒软件 | 乖宝真紧H嘶爽老子H | 久久精品午夜一区二区福利 | 激情综| 2021天天躁狠狠燥 | 99久久人妻无码精品系列性欧美 | 美国三级在线 | 色偷偷AV老熟女色欲涩爱 | 无码日本少妇舒爽视频 | 久久精品麻豆日日躁夜夜躁 | 黑人二十厘米进入A片 | 无码射肉在线播放视频 | np文超级肉一女多男(H) | 亚洲四播房 | 99视频精品国产免费观看 | 中文字幕一级毛片视频 | 亚洲区色影| 亚洲国产精品色情20242024 | 亚洲性久久久久久久久久 | 最近免费字幕中文大全视频 | 日本无码色哟哟婷婷最新网站 | 毛片区| 香蕉久久一区二区三区啪啪 | 亚洲精品一区二区三区四区五区 | 黑人巨大两根一起挤进A片小说 | 人人爱夜夜爽日日做视频 | 最近国语视频免费观看在线播放 | 国产日韩精品一区二区在线观看 | 免费看少妇高潮A片特黄 | 97伦理97伦理2018最新 | 婷婷中文在线 | 久久久乱码精品亚洲日韩小说 | 一区二区三区好的精华液杨朝越 | 亚洲在线成色综合网站 | 色播开心网 | 91在线视频播放 | 亚洲国产系列久久精品99人人 | 亚洲国产精品无码成人A片小说 | 色欲国产麻豆一精品一AV一免费 | 亚洲综合色色图 | 免费啪视频在线观看视频久18 | 欧美日韩不卡合集视频 | 国产九九九九九九九A片 | 欧美一区二区三区红桃小说 | 日本香港三级亚洲三级 | 精品无码无人网站免费视频 | 国产又粗又黄又爽的A片精华 | 91孕妇精品一区二区三区 | 911精品国产自产在线观看 | 亚洲精品大片 | 人妻熟女制服师生中文字幕 | 露脸一二三区国语对白 | 亚洲国产精品色情20242024 |