شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز
🎯 ثبت نام

ساخت SessionView

کلیه حقوق مادی و معنوی این مقاله متعلق به آموزشگاه تحلیل داده می باشد و هر گونه استفاده غیر قانونی از آن پیگرد قانونی دارد.

ساخت SessionView

در این مرحله یک رابط کاربری برای SessionView (صفحه اصلی) میسازیم تا داده هایی را که در مرحله قبل تعریف کردیم، نشان دهیم.

ساخت یک صفحه XAML

در Xamarin Studio، پروژه ENEI.SessionsApp را انتخاب کنید و یک پوشه با نام View ایجاد کنید. مانند تصویر زیر:


clip_image002[6]

clip_image004[6]

سپس پوشه Views را انتخاب کرده و با دابل کلیک کردن روی آن، منوی context را باز کنید و بر روی گزینه Add>New File… کلیک کنید.

clip_image006[6]

مطابق تصویر زیر بر روی Forms ContentPage XAML کلیک کنید:

clip_image008[6]

نتیجه به شکل زیر خواهد بود:


clip_image010[6]

SessionsView XAML به شکل زیر تعریف می شود:

·         فایل XAML که رابط کاربری را تعریف می کند.

·         فایل cs که code behind را تشکیل می دهد.

این رویکرد زمانی مفید خواهد بود که برنامه نویسان و طراحان با هم کار کنند و با استفاده از الگوی MVVM رفتار یک صفحه را از ظاهر و UI آن جدا خواهد بود.

برای استفاده از SessionsView باید تغییراتی در App.cs در ENEI.SessionsApp ایجاد کنیم:

public class App : Application

        {

            public App()

            {

                // The root page of your application  

                MainPage = new NavigationPage(new SessionsView())

                {

                    BarBackgroundColor = Color.White,

                    BarTextColor = Color.Black

                };

            }

        }

در این حالت یک NavigationPage در MainPage مشخص کرده اید که محتویات آن بوسیله SessionView تعیین می شود. NavigationPage زمانی نیاز می شود که بخواهیم بین از یک صفحه به صفحه دیگر برویم. بنابراین برنامه فقط به یک NavigationPage نیاز دارد.

حالا اگر برنامه را اجرا کنید هیچ محتوایی مشاهده نحواهید کرد و با صفحه ای مانند تصویر زیر  مواجه خواهید شد:

 

clip_image012[6]

 

اجازه دهید UI را مشخص کنیم:

ساخت Header

اولین چیزی که باید تعریف کنید Title (عنوان) و آیکون مورد استفاده در Header (تیتر) یک صفحه است. چیزی مثل تصویر زیر:

 

clip_image013[6]

کد آن به شکل زیر خواهد بود:


<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

    x:Class="ENEI.SessionsApp.Views.SessionsView"

    Title="1010 ENEI || Sessões"

    BackgroundColor="White"

    Icon="ic_action_users.png">

این کد در Android و iOS درست کار می کند اما در Windows 8.0 باید یکسری عملیات اضافی انجام دهیم که در ادامه به توضیح آن خواهیم پرداخت:

در اندروید یا به طور دقیق تر، در MainActivity، باید Icon را در ActionBar تعیین کنید:

ActionBar.SetIcon(Resource.Drawable.ic_action_users)

SessionView یک ContentPage است. یعنی یک صفحه ساده که بوسیله ی Xamarin Forms API محیا می شود. برای تعیین محتویات آن، باید از controls layouts مثل یک StackLayout یا Grid استفاده کنید.

 

clip_image014[6]

به این ترتیب، یک Grid را به عنوان control layout انتخاب کرده و برای آن دو سطر و یک ستون تعریف می کنیم:

·         سطر اول شامل Header برای Windows Phone (که برای سایر پلت فرم ها مخفی خواهد بود)

·         سطر دوم شامل ListView جهت نمایش Sessionها

کد آن به شکل زیر خواهد بود:

xml version="1.0" encoding="utf-8" ?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

             x:Class="ENEI.SessionsApp.Views.SessionsView"

             Title="1010 ENEI || Sessões"

             BackgroundColor="White"

             Icon="ic_action_users.png">

  <Grid BackgroundColor="White">

    <Grid.RowDefinitions>

      <RowDefinition Height="Auto" />

      <RowDefinition Height="*" />

    Grid.RowDefinitions>

 

   

    <StackLayout Grid.Row="0" Orientation="Horizontal" Padding="20,10,0,0">

      <StackLayout.IsVisible>

        <OnPlatform Android="false"

                    WinPhone="true"

                    iOS="false"

                    x:TypeArguments="x:Boolean" />

      StackLayout.IsVisible>

      <Image WidthRequest="48"

             HeightRequest="38"

             Source="Images/ic_action_users.png"/>

      <Label FontSize="Large" FontAttributes="Bold"

           TextColor="Black">

 

        <OnPlatform Android=""

                    WinPhone="1010 ENEI || Sessões"

                    iOS=""

                    x:TypeArguments="x:String" />

      Label>

    StackLayout>

   

  Grid>

ContentPage>

 

تعیین تصاویر برای هر پلتفرم

در مرحله قبل از تصویر ic_action_users.png استفاده کردید که باید به هر پروژه (ENEI.SessionApp.Android، ENEI.SessionApp.iOS، ENEI.SessionApp.WinPhone) اضافه شود. به این ترتیب هر app تصاویر خودش را خواهد داشت که متناسب با پلتفرم ای است که از آنها استفاده می کنند.

تصاویر و Assets ها ی مناسب با هر پلتفرم را می توانید از مسیر زیر دانلود کنید:

https://github.com/saramgsilva/XamarinWorkshop/tree/master/1010ENEI/0.%20Assests%20and%20Images

به این ترتیب خروجی های شما باید مطابق تصاویر زیر باشند:

 

clip_image016[6]

 

ساخت ListView

در مرحله بعد باید لیست Sessionها را بوسیله  1010 ENEI تعیین کنیم.

برای نمایش Sessionهای مورد استفاده در ListView باید موارد زیر موجود باشند:

·         ItemSource که با لیست Sessionها تعریف می شود.

·         ItemTemplate که با قالب (template) هر سطر تعریف می شود.

در ادامه اولین نسخه از ListView را تعریف خواهیم کرد:

<ListView x:Name="SessionsList"

             Grid.Row="1"

             ItemSelected="SessionsList_OnItemSelected"

             ItemsSource="{Binding Sessions}"

             SeparatorColor="#0094FF">

 

  <ListView.RowHeight>

    <OnPlatform Android="150"

                WinPhone="180"

                iOS="150"

                x:TypeArguments="x:Int32" />

  ListView.RowHeight>

ListView>

 

نام این ListView، SessionList است که در سطر دوم از grid ای که محتوای اصلی صفحه را تشکیل می دهد، تعریف می شود. در آن ItemSelected از SelectItem چشم پوشی می کند، رنگ آبی برای SeparatorColor در نظر گرفته می شود و ItemSource با خاصیت Sessions (خاصیتی از یک شی تعریف شده در BindingContext) متصل (Bind) می شود.

DataBinding اجازه می دهد خواص دو شی طوری به هم متصل شوند که تغییر در یکی منجر به تغییر در دیگری شود.

سایز هر سطر از ListView می تواند ثابت (Static) و یا پویا (dynamic) باشد. در این حالت بسته به اندازه هر پلتفرم (بسته به رزولوشن صفحه نمایش) سایز static تعیین می شود. اگر نیاز داشته باشد سایز هر سطر  بسته به داده های نمایش داده شده در آن سطر تغییر کند، توصیه می شود از خاصیت HasUnevenRows استفاده کند.

جهت تکمیل کد، باید Sessionهایی را تعریف کنید که ObservableCollection از Session (این نوع لیست UI را مطلع می شازد که چه زمانی Object حذف یا اضافه شده است) باشند. شما باید Sessionها را از SessionsDataSource دریافت کرده و همچنین BindingContext را تعریف کنید. داده ها باید در متد OnAppearing بارگذاری شوند و توصیه می شود در سازنده صفحه این کار را انجام ندهید. چون زمان ساخت صفحه را بالا می برند و مشل ساز خواهند شد.

public partial class SessionsView : ContentPage

        {

            public SessionsView()

            {

                InitializeComponent();

                Sessions = new ObservableCollection();

                BindingContext = this;

 

            }

 

            public ObservableCollection Sessions { get; set; }

 

            protected override void OnAppearing()

            {

                base.OnAppearing();

                if (Sessions.Count == 0)

                {

                    var sessions = SessionsDataSource.GetSessions();

                    foreach (var session in sessions)

                    {

                        Sessions.Add(session);

                    }

                }

            }

            private void SessionsList_OnItemSelected(object sender, SelectedItemChangedEventArgs e)

            {

                if (SessionsList.SelectedItem == null)

                {

                    return;

                }

 

                SessionsList.SelectedItem = null;

            }

        } 

 

در این مورد شما از الگوی MVVM استفاده نمی کنید. البته شدیداً توصیه می شود که در پروژه های واقعی از آن استفاده کنید. برای ساده تر شدن کد، می توانید رفتارهای مورد استفاده UI را طبق الگوی MVVM در ViewModel تعریف کنید.

ساخت ItemTemplate

در ListView خاصیتی به نام ItemTemplate وجود دارد که به شما اجازه می دهد یک DataTemplate برای هر سطر تعریف کنید. کافیست برای قالبی که در تصویر زیر مشاهده  می کنید، کد زیر را بنویسید:

clip_image017[6]

 

 <ListView.ItemTemplate>

  <DataTemplate>

    <ViewCell>

      <ViewCell.View>

        <Grid BackgroundColor="Transparent" Padding="20,0,20,0">

          <Grid.ColumnDefinitions>

            <ColumnDefinition Width="Auto" />

            <ColumnDefinition Width="*" />

          Grid.ColumnDefinitions>

          <Grid.RowDefinitions>

            <RowDefinition Height="5" />

            <RowDefinition Height="Auto" />

            <RowDefinition Height="48" />

            <RowDefinition Height="5" />

          Grid.RowDefinitions>

         

          <Image Grid.Row="1"

                 HorizontalOptions="StartAndExpand"

                 Source="{Binding Speaker.ImageUrl}"

                 VerticalOptions="Start">

            <Image.WidthRequest>

              <OnPlatform Android="50"

                          WinPhone="100"  iOS="50"

                          x:TypeArguments="x:Double" />

            Image.WidthRequest>

            <Image.HeightRequest>

              <OnPlatform Android="50"

                          WinPhone="100" iOS="50"

                          x:TypeArguments="x:Double" />

            Image.HeightRequest>

          Image>

         

          <StackLayout Grid.Row="1"

                       Grid.Column="1"

                       HorizontalOptions="FillAndExpand"

                       Padding="10,0,0,0">

            <Label Font="Medium"

                   FontAttributes="Bold"

                   Text="{Binding Name}"

                   TextColor="Black" />

            <Label Font="Medium"

                   LineBreakMode="TailTruncation"

                   Text="{Binding Speaker.Name}"

                   TextColor="Black" />

            <Label Font="Small"

                   LineBreakMode="TailTruncation"

                   TextColor="Black" Text="{Binding Details}"/>

          StackLayout>

         

        Grid>

      ViewCell.View>

    ViewCell>

  DataTemplate>

ListView.ItemTemplate>

 

با اجرای برنامه نتیجه ای مشابه تصاویر زیر مشاهده خواهید کرد:



clip_image019[6]

ساخت منو برای هر Session

برای ساخت منو برای هر Session باید یکسری تغییرات در ItemTemplate ای که در بالا تعریف کردید، ایجاد کنید:

clip_image020[6]

 

<Grid Grid.Row="2" Grid.Column="0"  Grid.ColumnSpan="2" Padding="0,5,0,0">

  <Grid.ColumnDefinitions>

    <ColumnDefinition Width="*" />

    <ColumnDefinition Width="Auto" />

    <ColumnDefinition Width="*" />

    <ColumnDefinition Width="Auto" />

    <ColumnDefinition Width="*" />

    <ColumnDefinition Width="Auto" />

    <ColumnDefinition Width="*" />

    <ColumnDefinition Width="Auto" />

    <ColumnDefinition Width="*" />

  Grid.ColumnDefinitions>

  <StackLayout Grid.Column="1" Orientation="Horizontal">

    <Image>

      <Image.WidthRequest>

        <OnPlatform Android="48" WinPhone="48" iOS="30"  x:TypeArguments="x:Double" />

      Image.WidthRequest>

      <Image.HeightRequest>

        <OnPlatform Android="48"  WinPhone="48" iOS="30" x:TypeArguments="x:Double" />

      Image.HeightRequest>

      <Image.Source>

        <OnPlatform x:TypeArguments="ImageSource">

          <OnPlatform.iOS>

            <FileImageSource File="ic_action_like.png" />

          OnPlatform.iOS>

          <OnPlatform.Android>

            <FileImageSource File="ic_action_like.png" />

          OnPlatform.Android>

          <OnPlatform.WinPhone>

            <FileImageSource File="Images/ic_action_like.png" />

          OnPlatform.WinPhone>

        OnPlatform>

      Image.Source>

    Image>

    <Label Font="Small" Text="{Binding NumLikes}" TextColor="#0094FF" VerticalOptions="Center" />

  StackLayout>

  <Image Grid.Column="3" Source="{Binding IsFavorite, Converter={StaticResource FavoriteImageConverter}}">

    <Image.WidthRequest>

      <OnPlatform Android="48" WinPhone="48" iOS="30"  x:TypeArguments="x:Double" />

    Image.WidthRequest>

    <Image.HeightRequest>

      <OnPlatform Android="48"  WinPhone="48"    iOS="30"  x:TypeArguments="x:Double" />

    Image.HeightRequest>

  Image>

  <Image Grid.Column="5">

    <Image.WidthRequest>

      <OnPlatform Android="30"  WinPhone="48" iOS="30" x:TypeArguments="x:Double" />

    Image.WidthRequest>

    <Image.HeightRequest>

      <OnPlatform Android="30"  WinPhone="48" iOS="30" x:TypeArguments="x:Double" />

    Image.HeightRequest>

    <Image.Source>

      <OnPlatform x:TypeArguments="ImageSource">

        <OnPlatform.iOS>

          <FileImageSource File="ic_action_share_2.png" />

        OnPlatform.iOS>

        <OnPlatform.Android>

          <FileImageSource File="ic_action_share_2.png" />

        OnPlatform.Android>

        <OnPlatform.WinPhone>

          <FileImageSource File="Images/ic_action_share_2.png" />

        OnPlatform.WinPhone>

      OnPlatform>

    Image.Source>

  Image>

  <Image Grid.Column="7">

    <Image.WidthRequest>

      <OnPlatform Android="30" WinPhone="48" iOS="30"   x:TypeArguments="x:Double" />

    Image.WidthRequest>

    <Image.HeightRequest>

      <OnPlatform Android="30"   WinPhone="48"  iOS="30" x:TypeArguments="x:Double" />

    Image.HeightRequest>

    <Image.Source>

      <OnPlatform x:TypeArguments="ImageSource">

        <OnPlatform.iOS>

          <FileImageSource File="ic_action_list.png" />

        OnPlatform.iOS>

        <OnPlatform.Android>

          <FileImageSource File="ic_action_list.png" />

        OnPlatform.Android>

        <OnPlatform.WinPhone>

          <FileImageSource File="Images/ic_action_list.png" />

        OnPlatform.WinPhone>

      OnPlatform>

    Image.Source>

  Image>

Grid>

 

در SessionDetaiView هم مشابه کد SessionsView را برای پیاده سازی Header خواهیم داشت. تنها تفاوت در مقدار عنوان است که به وسیله نام Session تعیین میشود.

در کد فوق یک grid به همراه تصاویری برای Favorites، Shares و Details وجود دارد و برای هر یک باید با استفاده از  GestureRecognizers  هر تصویر یک رخداد Tap تعریف کنیم. به این ترتیب باید برای هر تصویر TapGesture مناسب را تعیین کنیم:

 

<Image.GestureRecognizers>

  <TapGestureRecognizer x:Name="FavoriteGesture"

CommandParameter="{Binding}" Tapped="FavoriteGestureRecognizer_OnTapped" />

Image.GestureRecognizers>

 

در پیاده سازی مبتنی بر الگوی MVVM به جای رخداد Tapped از Command استفاده می کنیم.

event's handler آن عبارت است از:

 

private void FavoriteGestureRecognizer_OnTapped(object sender, EventArgs e)

        {

            var tappedEventArg = e as TappedEventArgs;

            if (tappedEventArg != null)

            {

                var session = tappedEventArg.Parameter as Session;

                if (session != null)

                {

                    session.IsFavorite = !session.IsFavorite;

                }

            }

        }

مشابه Like، برای  Share و Details نیز همین فرآیند را انجام می دهیم.

گزینه Favorates از FavoriteImageConverter استفاده می کند تا بتواند بر اساس انتخاب کاربر، تصویر مناسب را نمایش دهد. یعنی وقتی گزینه favorates قرمز باشد یعنی کاربر Session را به عنوان favorates انتخاب کرده. به صورت پیشفرض به رنگ آبی  خواهد بود.

پیاده سازی FavoriteImageConverter عبارت است از:

public class FavoriteImageConverter : IValueConverter

        {

            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

            {

                if (value == null)

                {

                    return Device.OS == TargetPlatform.WinPhone ? "Images/ic_action_heart.png" : "ic_action_heart.png";

                }

                var isFavorite = (bool)value;

 

                if (isFavorite)

                {

                    return Device.OS == TargetPlatform.WinPhone ? "Images/ic_action_heart_red.png" : "ic_action_heart_red.png";

                }

                return Device.OS == TargetPlatform.WinPhone ? "Images/ic_action_heart.png" : "ic_action_heart.png";

            }

 

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

            {

                throw new NotImplementedException();

            }

        } 

 

اجرای برنامه 

همانطور که در شکل زیر می بینید، 1010 ENEI Sessions App UI مانند تصویر زیر خواهد بود:


clip_image022[6]

 

 

 

1394/10/02 1499 1042
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...