Formsで使えるライブラリやテクニックをご紹介 〜日本酒アプリSakenomyは、Forms製です〜

Formsで使えるライブラリやテクニックをご紹介 〜日本酒アプリSakenomyは、Forms製です〜

JXUG#13発表資料
#ayasesh

Abf04d3b669c9b2d7a8d94df64f774e7?s=128

yo ohtagawa

May 07, 2016
Tweet

Transcript

  1. FormsͰ࢖͑ΔϥΠϒϥϦ΍ς ΫχοΫΛ͝঺հ ʙ೔ຊञΞϓϦSakenomy͸ɺForms੡Ͱ͢ʙ

  2. ࣗݾ঺հ Sakenomyͬͯ ςΫχοΫ ListView + Cell Custom Url Scheme ϥΠϒϥϦ

    FFImageLoading ACR UserDialogs
  3. XamarinແྉԽʂ ΦʔϓϯιʔεԽʂ

  4. ࣗݾ঺հ ଠా઒ɹ༸ʢ͓͓͕ͨΘɹΑ͏ʣ • 2013೥4݄ גࣜձࣾΤϜςΟʔΞΠʹ৽ଔೖࣾ • ϞόΠϧΞϓϦέʔγϣϯΤϯδχΞ • ۀ຿ͰObjective-C &

    javaΛɺڵຯͰswift & kotlin • ̎೥લ͔Β Xamarin (iOS → Forms) • ઈࢍ TypeScript ͰͷϑϩϯτΤϯδχΞษڧத • twitter.com/AyaseSH • www.facebook.com/you.ootagawa
  5. Sakenomyͱ͸

  6. None
  7. ʮ೔ຊञΛֶͿʯ ʮ೔ຊञΛ୳͢ʯ ʮ೔ຊञΛه࿥͢Δʯ ʮ৽ͨͳ೔ຊञͱग़ձ͏ʯ Sakenomy

  8. ListView + ViewCell

  9. Button inside Cell • એݴ࣌ʹॻ͖׵͑ΔͱViewCellʹҾ਺͕Θͨͤ·͢ɻ • CellͷதʹButtonͷ࣮૷͍ͨ࣌͠ɺActionΛ౉͢͜ͱͰ ListView͔ΒΠϕϯτͷίϯτϩʔϧ͕ग़དྷ·͢ɻ WBSMJTU7JFXOFX-JTU7JFX\ *UFN5FNQMBUFOFX%BUB5FNQMBUF

    UZQFPG 4BNQMF-JTU7JFX$FMM  *UFNT4PVSDFMJTU4PVSDF ^ WBSMJTU7JFXOFX-JTU7JFX\ *UFN5FNQMBUFOFX%BUB5FNQMBUF OFX4BNQMF-JTU7JFX$FMM  *UFNT4PVSDFMJTU4PVSDF ^
  10. Button inside Cell ※΍Γํ࣍ୈͰ͸ViewΛ౉͠ޙ෇΋Ͱ͖·͕͢ɺ X.Forms v2.1͔ΒTemplateΛෳ਺࣋ͯͨΓ͢ΔͷͰࠓ͸ඞཁͳ͍͔ͱࢥ͍·͢ "DUJPOUBQ 4ZTUFN%JBHOPTUJDT%FCVH8SJUF-JOF $BMMFE.FUIPE"DUJPO5BQ 

    WBSMJTU7JFXOFX-JTU7JFX\ *UFN5FNQMBUFOFX%BUB5FNQMBUF OFX4BNQMF-JTU7JFX$FMM UBQ  *UFNT4PVSDFMJTU4PVSDF  ^ QVCMJDDMBTT4BNQMF-JTU7JFX$FMM7JFX$FMM \ 4UBDL-BZPVU@TUBDL-BZPVU QVCMJD4BNQMF-JTU7JFX$FMM "DUJPOUBQ UIJT  \ WBSCVUUPOOFX#VUUPO \5FYU"EE#VUUPO 5FYU$PMPS$PMPS/BWZ^ CVUUPO$MJDLFE  TFOEFS F UBQ  @TUBDL-BZPVU$IJMESFO"EE OFX$POUFOU7JFX\ $POUFOUCVUUPO  7FSUJDBM0QUJPOT-BZPVU0QUJPOT$FOUFS ^  ^ ddd
  11. Button inside Cell CellΛCellࣗ਎Ͱม͑ͯ͠·͑ • ListView͔Βมߋ͢Δͱ DataTemplateͷ࠶౓ॳظԽ΍ List<T>Ͱ͸ͳ͘ ObservableCollection<T>Λ࢖ ͏ඞཁ͕͋Δ

  12. Button inside Cell • CellͷBindingContextʹදࣔͷσʔλ͕͋Δ • CellͰ্ॻ͖͢Ε͹σʔλ΋มΘΔ nextButton.Clicked += (sender,

    e) =>
 {
 var property = BindingContext as Property;
 BindingContext = new Helper().NextColor(property);
 };
 
 var beforeButton = new Button {
 Text = "Before",
 WidthRequest = 100,
 VerticalOptions = LayoutOptions.FillAndExpand
 };
 beforeButton.Clicked += (sender, e) =>
 {
 var property = BindingContext as Property;
 BindingContext = new Helper().BeforeColor(property);
 }; var listView = new ListView
 {
 ItemTemplate = new DataTemplate(() => new SampleListViewCell()),
 ItemsSource = new List<Property>(),
 HasUnevenRows = true,
 };
  13. Sample.iOS

  14. Custom Url Scheme

  15. Custom Url Scheme • Url Scheme ͱ͸ɺޚଘ஌ͷ௨Γ”http”ͷ͜ͱ • ϞόΠϧΞϓϦͰ͸
 SchemeΛมߋͨ͠ϦϯΫΛ౿·ͤΔͱରԠͨ͠ΞϓϦ

    ʹભҠͤ͞Δ͜ͱ͕Ͱ͖Δ࢓૊Έ • LINEͩͬͨΒ line:// ͳͲɹTwitterͰ͸ twitter:// ͳͲ • iOSͷUniversal Links͸৮Ε·ͤΜʢWebଆͷ࢓૊Έ͕ Α͘Θ͔ͬͯͳ͍…ʣ
  16. Πϝʔδ • X.Formsͷόʔδϣϯ͋͛ ͨΒAndroidͷγϛϡ Ϩʔλʔ͕ಈ͔ͳ͘ͳͬ ͨʗ(^o^)ʘ

  17. Android • MainActivity ʹ Attribute ௥Ճ // sakenomy-schemes://ayase.com/Sheeeeeeeep?id=1 [IntentFilter( new[]{

    Intent.ActionView }, 
 Categories = new[]{ Intent.CategoryDefault, Intent.CategoryBrowsable },
 DataScheme = "sakenomy-schemes",
 DataHost = "ayase.com",
 DataPathPrefix = “/Sheeeeeeeep", 
 DataPathPattern = “*")] public class MainActivity : FormsApplicationActivity {
 protected override void OnCreate(Android.OS.Bundle savedInstanceState) {
 ~~~ ~~~
 if (Intent.Data != null && !string.IsNullOrEmpty(Intent.Data.EncodedPath) && !string.IsNullOrEmpty(Intent.Data.EncodedQuery)) {
 var prefix = Intent.Data.EncodedPath;
 var id = Intent.Data.GetQueryParameter("id");
 
 if (Intent.Data.EncodedPath.Equals(“/Sheeeeeeeep”) {
 MessagingCenter.Send<App, string> (Xamarin.Forms.Application.Current as NSake.Core.App, "Ayase", id);
 } } }
  18. iOS 1. Info.plist > Advanced > URL Types > Add

    URL Type 2. AppDelegate.cs > OpenUrl Λ override // sakenomy-schemes://ayase.com/Sheeeeeeeep?id=1 public override bool OpenUrl (UIApplication application, NSUrl url, string sourceApplication, NSObject annotation) { if (url.LastPathComponent.Equals(“Sheeeeeeeep”) && url.Query.Contains(“id=")) { MessagingCenter.Send<App, string>(Xamarin.Forms.Application.Current as App, "Ayase", url.Query.Split(‘=')[1]); return true; } return false; }
  19. Xamarin.Forms • id͸AppͷҾ਺Ͱ౉͢͜ͱ΋Ͱ͖Δ͔ͳʁ • MessagingCenterΛ࢖༻ͨ͠ཧ༝͸ɺ
 ෳ਺ͷ࣮૷Λͨ࣌͠ʹɺCoreଆͷ࣮૷͕͖ͬ͢Γ • ͔͠͠ ֤ϓϥοτϑΥʔϜͰͷ࣮૷͸ ifจ

    ͷཛྷ… public App() { ~~~ ~~~ MessagingCenter.Subscribe <App, string>(this, "ShowTasted", (sender, arg) => naviPage.PushAsync(new AyasePage(arg))); // arg == id ~~~ ~~~
 }
  20. FFImageLoading

  21. FFImageLoading https://www.nuget.org/packages/Xamarin.FFImageLoading.Forms

  22. FFImageLoading ػೳҰཡ • ϝϞϦΩϟογϡͱͦͷσΟεΫ༰ྔͷઃఆ • ॏෳͨ͠ϩʔυཁٻͷ৔߹ɺআ֎͢Δ • Τϥʔɺϩʔυ࣌ʹϓϨεϗϧμʔͱͯ͠ը૾Λઃఆ Մೳ •

    ը૾ͷϩʔυࣦഊ࣌ɺࣗಈϦτϥΠʢϦτϥΠ਺΍ ϦτϥΠִؒͷઃఆՄೳʣ • ৭ʑը૾Λม׵ͯ͘͠ΕΔɻؙͨ͘͠Γɺനࠇͨ͠Γ • ϩʔυͨ͠ը૾͔ΒByte[]͕औΕΔ
  23. FFImageLoading + ReactiveProperty WBSMBCFMOFX$BDIFE*NBHF \ "TQFDU"TQFDU"TQFDU'JU  8JEUI3FRVFTU  )FJHIU3FRVFTU

     $BDIF%VSBUJPO5JNF4QBO'SPN%BZT  Ωϟογϡظؒ 'BEF"OJNBUJPO&OBCMFEGBMTF  -PBEJOH1MBDFIPMEFSMPBEJOH*NBHFQOH  )PSJ[POUBM0QUJPOT-BZPVU0QUJPOT$FOUFS  7FSUJDBM0QUJPOT-BZPVU0QUJPOT$FOUFS  5SBOTGPSNBUJPOTOFX-JTU''*NBHF-PBEJOH8PSL*5SBOTGPSNBUJPO \ม׵ OFX''*NBHF-PBEJOH5SBOTGPSNBUJPOT$JSDMF5SBOTGPSNBUJPO ؙ͘͢Δ ^ ^ MBCFM4FU#JOEJOH7JFX.PEFM $BDIFE*NBHF4PVSDF1SPQFSUZ WNWN*NBHF1SPQFSUZ7BMVF  WBSUBQ-BCFMOFX5BQ(FTUVSF3FDPHOJ[FS  UBQ-BCFM5BQQFE BTZOD TFOEFS F \ WBSJNBHFTBXBJUMBCFM(FU*NBHF"T+QH"TZOD  WBSDPNNBOE #JOEJOH$POUFYUBT7JFX.PEFM 5BQQFE$PNNBOE&YDVUF JNBHFT  ^ MBCFM(FTUVSF3FDPHOJ[FST"EE UBQ-BCFM 
  24. ACR UserDialogs

  25. ACR UserDialogs • MVVMͰͷ՝୊ͷҰͭ ϙοϓΞοϓ • ≒ MvvmCrossͷDialogService https://www.nuget.org/packages/Acr.UserDialogs/

  26. ࣮૷ WBSDPOpHOFX"MFSU$POpH\ 5JUMF3FTPVSDFT&SSPS@4FMFDU@5JUMF  .FTTBHF3FTPVSDFT&SSPS@4FMFDU@.FTTBHF  0O0L \ ॲཧ ^

    ^ BXBJU6TFS%JBMPHT*OTUBODF"MFSU"TZOD DPOpH  6TFS%JBMPHT*OTUBODF"MFSU DPOpH  VTJOH WBSMPBEJOH%JBMPH6TFS%JBMPHT*OTUBODF-PBEJOH lϩʔσΟϯάz \ ॏ͍ͨॲཧ΍αʔόʔͱͷ௨৴ॲཧΛॻ͍ͨΓ ^
  27. ࠔͬͨͱ͖ ٸʹಈ͔ͳ͘ͳͬͨ࣌ • ͱ͋ΔOSͷͱ͋Δ୺຤ͷΈόά͕ى͖ͨ • UIAlertController͕དྷͨ ͦͷ࣌ʹ͸ࣗ෼Ͱ࣮૷Λ্ॻ͖Ͱ͖Δͷ΋޷ධՁ <BTTFNCMZ9BNBSJO'PSNT%FQFOEFODZ UZQFPG .Z$VTUPN6TFS%JBMPHT

    > OBNFTQBDF.Z"QQ1PQVQ7JFX\ QVCMJDDMBTT.Z$VTUPN6TFS%JBMPHT"DS6TFS%JBMPHT6TFS%JBMPHT*NQM\ QVCMJDPWFSSJEFWPJE"MFSU "DS6TFS%JBMPHT"MFSU$POpHDPOpH \ WBSEMHOFX6*"MFSU7JFX DPOpH5JUMF 4USJOH&NQUZ DPOpH.FTTBHF OVMM OVMM DPOpH0L5FYU  JG DPOpH0O0LOVMM EMH$MJDLFE  T F DPOpH0O0L  EMH4IPX  ^ ^ ^ QVCMJDQBSUJBMDMBTT"QQ%FMFHBUFHMPCBM9BNBSJO'PSNT1MBUGPSNJ04'PSNT"QQMJDBUJPO%FMFHBUF\ QVCMJDPWFSSJEFCPPM'JOJTIFE-BVODIJOH 6*"QQMJDBUJPOVJ"QQMJDBUJPO /4%JDUJPOBSZMBVODI0QUJPOT \ 6TFS%JBMPHT*OTUBODFOFX.Z"QQ1PQVQ7JFX.Z$VTUPN6TFS%JBMPHT  ^ ^
  28. ·ͱΊ SakenomyΑΖ͓͘͠ئ͍͠·͢ʂ

  29. ͓͠·͍ ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠