Flutter สำหรับ iOS-การเพิ่มรายการ

ในแต่ละปีเราพยายามปรับปรุงอาหารค่ำของเราในวันคริสต์มาส ปีนี้มุ่งเน้นไปที่การคั่วที่ดีกว่า

มาดูกันว่าเราจะค้นหาและเพิ่มสูตรมันฝรั่งอบใหม่ลงในสรุปของเราได้อย่างไร

การยอมรับข้อกำหนดนี้คือสามารถ:

  • ค้นหาสูตรใหม่
  • บันทึกลงในสรุปของเรา:
  • ชื่อ
  • ผู้เขียน
  • ภาพขนาดย่อ

ในการเริ่มต้น ฉันได้เพิ่มแถบนำทางด้านบนพร้อมการดำเนินการที่ช่วยให้เราเพิ่มสูตรอาหารได้

@override
Widget build(BuildContext context) {
  return CupertinoPageScaffold(
    navigationBar: const CupertinoNavigationBar(
      heroTag: "RecipeTabHeroTag",
      transitionBetweenRoutes: false,
      middle: Text(
        "Recipies",
      ),
      trailing: Icon(CupertinoIcons.add)
    ),
    child: Container(
      color: CupertinoColors.activeGreen,
      child: recipiesList(),
    ),
  );
}

ฉันเปลี่ยนชื่อแท็บกลับเป็น "ไดเจสต์" ตอนนี้เรามีชื่อ "สูตรอาหาร" ในแถบนำทางด้านบน

สำหรับการตัดสินใจอย่างรวดเร็วอีกครั้ง เราจะเลื่อนหน้าจอขึ้นเมื่อมีการคลิกปุ่มเพิ่ม และแสดงแถบค้นหาเพื่อให้เราค้นหาสูตรอาหารใหม่ๆ

ด้วยวิธีนี้ เราเพียงแค่ต้องใช้ประโยชน์จากการค้นหาของ Google เพื่อค้นหาสูตรอาหารใหม่ๆ

ฉันหันไปหา "SerpAPI" เพื่อทำสิ่งนี้และดึงข้อมูลบางส่วนจากการค้นหาสูตรอาหารสำหรับมันฝรั่งย่างกับน้ำส้มสายชูบัลซามิก

https://serpapi.com/search.json?q=Roast+potatoes+with+balsamic&location=United+Kingdom&hl=en&gl=uk&google_domain=google.co.uk&api_key=secret_api_key

{
    "search_metadata": {
      "id": "61c3369cc99903747c1e643b",
      "status": "Success",
      "json_endpoint": "https://serpapi.com/searches/bdb5db8a7f4c5593/61c3369cc99903747c1e643b.json",
      "created_at": "2021-12-22 14:30:52 UTC",
      "processed_at": "2021-12-22 14:30:52 UTC",
      "google_url": "https://www.google.co.uk/search?q=Roast+potatoes+with+balsamic&oq=Roast+potatoes+with+balsamic&uule=w+CAIQICIOVW5pdGVkIEtpbmdkb20&hl=en&gl=uk&sourceid=chrome&ie=UTF-8",
      "raw_html_file": "https://serpapi.com/searches/bdb5db8a7f4c5593/61c3369cc99903747c1e643b.html",
      "total_time_taken": 1.99
    },
    "search_parameters": {
      "engine": "google",
      "q": "Roast potatoes with balsamic",
      "location_requested": "United Kingdom",
      "location_used": "United Kingdom",
      "google_domain": "google.co.uk",
      "hl": "en",
      "gl": "uk",
      "device": "desktop"
    },
    "search_information": {
      "organic_results_state": "Results for exact spelling",
      "query_displayed": "Roast potatoes with balsamic",
      "total_results": 12800000,
      "time_taken_displayed": 0.49
    },
    "recipes_results": [
      {
        "title": "Balsamic potatoes",
        "link": "https://www.jamieoliver.com/recipes/potato-recipes/balsamic-potatoes/",
        "source": "Jamie Oliver",
        "total_time": "2 hrs 20 mins",
        "ingredients":
        [
          "Balsamic vinegar",
          "maris piper potatoes",
          "red onions",
          "rocket",
          "olive oil"
        ],
        "thumbnail": "https://serpapi.com/searches/61c3369cc99903747c1e643b/images/bd928f9ef521c02bbdb2df96157011d6a02d619d06f8a6e0e62bb157f48e10e5.jpeg"
      },
      {
        "title": "Balsamic roast potatoes",
        "link": "https://www.taste.com.au/recipes/balsamic-roast-potatoes/1bcb6bd4-2efa-4f01-bc98-f2ce32eaa906",
        "source": "Taste",
        "rating": 4,
        "reviews": 2,
        "total_time": "1 hr 5 mins",
        "ingredients":
        [
          "Balsamic vinegar",
          "kipfler potatoes",
          "olive oil",
          "garlic"
        ],
        "thumbnail": "https://serpapi.com/searches/61c3369cc99903747c1e643b/images/bd928f9ef521c02bbdb2df96157011d625322c9b727d95f76706f0471bbaba31.jpeg"
      },
      {
        "title": "Balsamic roast potatoes",
        "link": "https://www.delicious.com.au/recipes/balsamic-roast-potatoes/1e2f30ad-d9b4-41bf-aa2e-16f1e2accfb7",
        "source": "Delicious",
        "rating": 5,
        "reviews": 1,
        "total_time": "1 hr 5 mins",
        "ingredients":
        [
          "Balsamic vinegar",
          "kipfler potatoes",
          "olive oil",
          "garlic"
        ],
        "thumbnail": "https://serpapi.com/searches/61c3369cc99903747c1e643b/images/bd928f9ef521c02bbdb2df96157011d6ebca3a2868589cb9feab32215a0ba5e8.jpeg"
      }
    ]
}

เพิ่มรายการเพื่อแสดงผลลัพธ์จากการค้นหา

เมื่อเลือกผลลัพธ์ (onTap) เราจะเพิ่มลงในสรุปสูตรของเรา

Ta Da

เบิร์นเนอร์หลัง

กำลังบันทึกข้อมูลสรุป

สำหรับตอนนี้ เราบันทึกสูตรที่เพิ่มไว้ในหน่วยความจำ หลังจากนั้นเราสามารถคงไว้ในที่เก็บข้อมูลของเราทั้งภายในและระยะไกลได้

iOS เท่านั้น — คลิกแท็บเพื่อรีเซ็ต

การเพิ่มฟังก์ชันการทำงานเพื่อนำทางกลับไปยังระดับบนสุด/สถานะเมื่อแตะที่รายการแท็บปัจจุบัน นี่เป็นประสบการณ์ iOS ที่ดี ซึ่งเป็นการออกแบบที่ผู้คนคาดหวัง

แถบค้นหาแบบเคลื่อนไหว

ฉันตัดสินใจหลีกเลี่ยงการใช้แถบค้นหาขั้นสูงที่คล้ายกับแถบค้นหาในแอปพลิเคชัน "App Store" ของ Apple ที่มีภาพเคลื่อนไหวอยู่ในโฟกัส

เราสามารถดูสิ่งนี้ได้และพยายามปรับปรุงแถบค้นหาในภายหลังเมื่อข้อมูลพื้นฐานเป็นรูปเป็นร่างแล้ว

CupertinoSearchฟิลด์ข้อความ

ฉันได้รับข้อผิดพลาดระดับไลบรารีจาก Flutter ขอให้ฉันรายงานข้อบกพร่องของเฟรมเวิร์กเมื่อกด Enter บนแป้นพิมพ์ในช่องค้นหาโดยใช้โปรแกรมจำลอง iOS

ตอนนี้ฉันได้สรุปมันลงในวิดเจ็ตแล้วและตั้งใจที่จะแทนที่มันด้วยเวอร์ชันที่กำหนดเองพร้อมคุณสมบัติเพิ่มเติม

ฉันยังสังเกตเห็นด้วยว่าคุณต้องป้อนสองครั้งบนแป้นพิมพ์ในโปรแกรมจำลองก่อนที่เหตุการณ์ 'OnTap' จะเริ่มทำงาน

XP

ในข้อมูลหน่วยความจำ

เราจำเป็นต้องจัดเก็บและดูแลรักษารายการสูตรอาหารเพื่อให้สามารถเพิ่มสูตรอาหารใหม่ได้

ณ จุดนี้กำลังใช้คลาสที่เก็บหน่วยความจำเพื่อจัดการสิ่งนี้และแทรกเป็น ChangeNotifierProvider

ChangeNotifierProvider<MemoryRepository>(
	create: (_) => MemoryRepository(),
    lazy: false,
),

ฟังดูซับซ้อนแต่เป็นเพียงรายการสูตรอาหารในหน่วยความจำและวิธีการบางอย่างในการเพิ่มและดึงข้อมูลเหล่านั้น

List<Recipe> findAllRecipes();
Recipe addRecipe(Recipe recipe);

ดู Flutter เอกสารประกอบ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการจัดการของรัฐ

เมื่อเราย้ายไปยังที่เก็บข้อมูลเช่น ฐานข้อมูลผ่าน API ที่เราสามารถปรับปรุงโค้ดนี้ได้

รายการสินค้า นำมาใช้ใหม่

ในส่วนหนึ่งของการแสดงผลการค้นหา เราจำเป็นต้องแสดงรายการอีกครั้ง ดังนั้นฉันจึงสรุปรายการย่อยเบื้องต้นเพื่อให้เราสามารถนำมาใช้ซ้ำได้ และตรวจสอบให้แน่ใจว่ารายการของเรามีรูปลักษณ์และความรู้สึกเหมือนกันทั่วทั้งแอป

Widget recipesList() {
  final repository = Provider.of<MemoryRepository>(context);
  var recipes = repository.findAllRecipes();

  return ListView.builder(
    itemCount: recipes.length,
    itemBuilder: (context, index) {
      var listItemInfo = ListItemInfo(
        id: recipes[index].link,
        author: recipes[index].source,
        title: recipes[index].title,
        titleImage: Image.network(recipes[index].thumbnail),
        showAddIcon: false,
      );

      return ListItem(listItemInfo);
    },
  );
}

Widget recipeSearchResultsList() {
  var searchResultRecipes = _searchResults.data.length > 0
    ? Recipe.fromSerpApiResultJson(_searchResults.data)
    : <Recipe>[];

  final repository = Provider.of<MemoryRepository>(context);

  return ListView.builder(
    itemCount: searchResultRecipes.length,
    itemBuilder: (context, index) {
      var listItemInfo = ListItemInfo(
        id: searchResultRecipes[index].link,
        author: searchResultRecipes[index].source,
        title: searchResultRecipes[index].title,
        titleImage: Image.network(searchResultRecipes[index].thumbnail),
        showAddIcon: true,
        onTap: () => {
          repository.addRecipe(searchResultRecipes[index]),
          Navigator.pop(context)
        },
      );

      return ListItem(listItemInfo);
    },
  );
}

Scope Creep (ระวัง — YUTNI คุณคงไม่จำเป็นต้องใช้มัน)

สำหรับฉัน นี่เป็นเวลาที่น่าดึงดูดใจที่สุดในการพยายามควบคุมโครงการ เนื่องจากยังขาดสิ่งสำคัญหลายประการ

ฉันอยากจะทำงานเพิ่มเติมเกี่ยวกับ:

  • การเข้าถึงข้อมูล รวมถึงคำขอ API แบบแบตช์
  • ออกแบบวิดเจ็ตที่ดีขึ้นมากพร้อมแอนิเมชั่นที่สวยงาม
  • เพิ่มธีมและรสชาติ
  • การบันทึก
  • การทดสอบการยอมรับอัตโนมัติ
  • ปรับปรุงการออกแบบสำหรับ Android
  • ดูว่ามันจะทำงานอย่างไรเป็นเว็บไซต์
  • นำห้องสมุดการจัดการของรัฐบางแห่งเข้ามา
  • ฯลฯ

แต่ประสบการณ์บอกให้ฉันต่อต้านความอยากที่จะติดตามด้านข้าง แม้แต่การวิจัยเบื้องต้นบน Google ก็ทำให้โพสต์นี้ช้าลงอย่างมาก

ในท้ายที่สุด ฉันกลับไปสู่แนวคิดแบบสาธิตที่จะทำให้มันใช้งานได้ โดยสมดุลกับคำแนะนำจากลุงบ๊อบ ซึ่งเมื่อมันได้ผลเพียง 50% เท่านั้น ตอนนี้คุณต้องทำให้ถูกต้อง

นั่นเท่ากับต้องใช้เวลาในการแยกวิธีการและจัดระเบียบให้มากขึ้น

ตราบใดที่เราให้แต่ละชั้นเรียน กำหนดความรับผิดชอบเดียวในไฟล์ของตัวเอง เราก็สามารถปรับปรุงพวกมันได้อย่างอิสระในภายหลัง เมื่อเราเปลี่ยนจากแนวคิดไปสู่การผลิตที่พร้อม

บ่อยครั้งที่ขอบเขตคืบคลานเข้ามาเมื่อฉันเบื่อกับระเบียบวินัยของงานที่ทำอยู่เพราะระเบียบวินัยรู้สึกช้า

ลิงค์

ขอขอบคุณอย่างยิ่งสำหรับ M4trix Dev เนื่องจากบทความของเขาเกี่ยวกับ iOS Tab Bar มีคุณค่าอย่างยิ่ง และทำให้ฉันสามารถแก้ไขปัญหาที่ฉันมีในการใช้งานครั้งแรกได้อย่างรวดเร็ว

ประชากร

“ประเด็นก็คือ มันง่ายมากที่จะแตกต่าง แต่ยากมากที่จะดีขึ้น”

โจนี่ ไอฟ์_

เสียงและการมองเห็น

อีกหนึ่งสิ่ง

“ฉันส่องกระจกทุกเช้าแล้วถามตัวเองว่า “ถ้าวันนี้เป็นวันสุดท้ายของชีวิต ฉันจะอยากทำสิ่งที่กำลังจะทำวันนี้ไหม?” และเมื่อใดก็ตามที่คำตอบคือ “ไม่” ติดต่อกันหลายวันเกินไป ฉันรู้ว่าฉันต้องเปลี่ยนแปลงอะไรบางอย่าง”

สตีฟ จ็อบส์_