$30 off During Our Annual Pro Sale. View Details »

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

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

JXUG#13発表資料
#ayasesh

yo ohtagawa

May 07, 2016
Tweet

More Decks by yo ohtagawa

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. ࣗݾ঺հ
    ଠా઒ɹ༸ʢ͓͓͕ͨΘɹΑ͏ʣ
    • 2013೥4݄ גࣜձࣾΤϜςΟʔΞΠʹ৽ଔೖࣾ
    • ϞόΠϧΞϓϦέʔγϣϯΤϯδχΞ
    • ۀ຿ͰObjective-C & javaΛɺڵຯͰswift & kotlin
    • ̎೥લ͔Β Xamarin (iOS → Forms)
    • ઈࢍ TypeScript ͰͷϑϩϯτΤϯδχΞษڧத
    • twitter.com/AyaseSH
    • www.facebook.com/you.ootagawa

    View Slide

  5. Sakenomyͱ͸

    View Slide

  6. View Slide

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

    View Slide

  8. ListView + ViewCell

    View Slide

  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
    ^

    View Slide

  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

    View Slide

  11. Button inside Cell
    CellΛCellࣗ਎Ͱม͑ͯ͠·͑
    • ListView͔Βมߋ͢Δͱ
    DataTemplateͷ࠶౓ॳظԽ΍
    ListͰ͸ͳ͘
    ObservableCollectionΛ࢖
    ͏ඞཁ͕͋Δ

    View Slide

  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(),

    HasUnevenRows = true,

    };

    View Slide

  13. Sample.iOS

    View Slide

  14. Custom Url Scheme

    View Slide

  15. Custom Url Scheme
    • Url Scheme ͱ͸ɺޚଘ஌ͷ௨Γ”http”ͷ͜ͱ
    • ϞόΠϧΞϓϦͰ͸

    SchemeΛมߋͨ͠ϦϯΫΛ౿·ͤΔͱରԠͨ͠ΞϓϦ
    ʹભҠͤ͞Δ͜ͱ͕Ͱ͖Δ࢓૊Έ
    • LINEͩͬͨΒ line:// ͳͲɹTwitterͰ͸ twitter:// ͳͲ
    • iOSͷUniversal Links͸৮Ε·ͤΜʢWebଆͷ࢓૊Έ͕
    Α͘Θ͔ͬͯͳ͍…ʣ

    View Slide

  16. Πϝʔδ
    • X.Formsͷόʔδϣϯ͋͛
    ͨΒAndroidͷγϛϡ
    Ϩʔλʔ͕ಈ͔ͳ͘ͳͬ
    ͨʗ(^o^)ʘ

    View Slide

  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
    (Xamarin.Forms.Application.Current as NSake.Core.App, "Ayase", id);

    }
    }
    }

    View Slide

  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(Xamarin.Forms.Application.Current as App,
    "Ayase", url.Query.Split(‘=')[1]);
    return true;
    }
    return false;
    }

    View Slide

  19. Xamarin.Forms
    • id͸AppͷҾ਺Ͱ౉͢͜ͱ΋Ͱ͖Δ͔ͳʁ
    • MessagingCenterΛ࢖༻ͨ͠ཧ༝͸ɺ

    ෳ਺ͷ࣮૷Λͨ࣌͠ʹɺCoreଆͷ࣮૷͕͖ͬ͢Γ
    • ͔͠͠ ֤ϓϥοτϑΥʔϜͰͷ࣮૷͸ ifจ ͷཛྷ…
    public App() {
    ~~~
    ~~~
    MessagingCenter.Subscribe (this, "ShowTasted", (sender, arg) =>
    naviPage.PushAsync(new AyasePage(arg))); // arg == id
    ~~~
    ~~~

    }

    View Slide

  20. FFImageLoading

    View Slide

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

    View Slide

  22. FFImageLoading
    ػೳҰཡ
    • ϝϞϦΩϟογϡͱͦͷσΟεΫ༰ྔͷઃఆ
    • ॏෳͨ͠ϩʔυཁٻͷ৔߹ɺআ֎͢Δ
    • Τϥʔɺϩʔυ࣌ʹϓϨεϗϧμʔͱͯ͠ը૾Λઃఆ
    Մೳ
    • ը૾ͷϩʔυࣦഊ࣌ɺࣗಈϦτϥΠʢϦτϥΠ਺΍
    ϦτϥΠִؒͷઃఆՄೳʣ
    • ৭ʑը૾Λม׵ͯ͘͠ΕΔɻؙͨ͘͠Γɺനࠇͨ͠Γ
    • ϩʔυͨ͠ը૾͔ΒByte[]͕औΕΔ

    View Slide

  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-BCFM5BQQFEBTZOD TFOEFS F
    \
    WBSJNBHFTBXBJUMBCFM(FU*NBHF"T+QH"TZOD

    WBSDPNNBOE #JOEJOH$POUFYUBT7JFX.PEFM
    5BQQFE$PNNBOE&YDVUF JNBHFT

    ^
    MBCFM(FTUVSF3FDPHOJ[FST"EE UBQ-BCFM

    View Slide

  24. ACR UserDialogs

    View Slide

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

    View Slide

  26. ࣮૷
    WBSDPOpHOFX"MFSU$POpH\
    5JUMF3FTPVSDFT&SSPS@4FMFDU@5JUMF
    .FTTBHF3FTPVSDFT&SSPS@[email protected]
    0O0L
    \ॲཧ^
    ^
    BXBJU6TFS%JBMPHT*OTUBODF"MFSU"TZOD DPOpH

    6TFS%JBMPHT*OTUBODF"MFSU DPOpH

    VTJOH WBSMPBEJOH%JBMPH6TFS%JBMPHT*OTUBODF-PBEJOH lϩʔσΟϯάz

    \
    ॏ͍ͨॲཧ΍αʔόʔͱͷ௨৴ॲཧΛॻ͍ͨΓ
    ^

    View Slide

  27. ࠔͬͨͱ͖
    ٸʹಈ͔ͳ͘ͳͬͨ࣌
    • ͱ͋ΔOSͷͱ͋Δ୺຤ͷΈόά͕ى͖ͨ
    • UIAlertController͕དྷͨ
    ͦͷ࣌ʹ͸ࣗ෼Ͱ࣮૷Λ্ॻ͖Ͱ͖Δͷ΋޷ධՁ

    >
    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

    ^
    ^

    View Slide

  28. ·ͱΊ
    SakenomyΑΖ͓͘͠ئ͍͠·͢ʂ

    View Slide

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

    View Slide