{"id":296,"date":"2025-09-27T07:03:16","date_gmt":"2025-09-27T07:03:16","guid":{"rendered":"https:\/\/devia.infokand23.my.id\/laprak1\/?p=296"},"modified":"2025-09-27T07:32:26","modified_gmt":"2025-09-27T07:32:26","slug":"laporan-praktikum-aplikasi-mobile-3","status":"publish","type":"post","link":"https:\/\/devia.infokand23.my.id\/laprak1\/laporan-praktikum-aplikasi-mobile-3\/","title":{"rendered":"LAPORAN PRAKTIKUM APLIKASI MOBILE 3"},"content":{"rendered":"\n<h1 class=\"wp-block-heading has-medium-font-size\">Input Widgets dan Basic Form<\/h1>\n\n\n\n<a href=\"https:\/\/github.com\/deviapujiastuti\/Aplikasi-Mobile\/tree\/5b6f7e684019df2287b21be99dea51a5e13d0b8f\/praktikum3\"><\/i> GitHub\n<\/a>\n\n\n\n<div class=\"wp-block-group alignfull has-background-color has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-16c0760e24b11d67e5dafb4871ba7d71\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-container-core-group-is-layout-97875daf wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group alignwide is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-256aec57 wp-block-group-is-layout-flex\">\n<div class=\"wp-block-group is-layout-flex wp-block-group-is-layout-flex\"><\/div>\n\n\n\n<div class=\"wp-block-group is-layout-flex wp-block-group-is-layout-flex\"><nav class=\"is-responsive items-justified-right wp-block-navigation is-content-justification-right is-layout-flex wp-container-core-navigation-is-layout-3817c3ed wp-block-navigation-is-layout-flex\" aria-label=\"Navigation\" \n\t\t data-wp-interactive=\"core\/navigation\" data-wp-context='{\"overlayOpenedBy\":{\"click\":false,\"hover\":false,\"focus\":false},\"type\":\"overlay\",\"roleAttribute\":\"\",\"ariaLabel\":\"Menu\"}'><button aria-haspopup=\"dialog\" aria-label=\"Open menu\" class=\"wp-block-navigation__responsive-container-open\" \n\t\t\t\tdata-wp-on-async--click=\"actions.openMenuOnClick\"\n\t\t\t\tdata-wp-on--keydown=\"actions.handleMenuKeydown\"\n\t\t\t><svg width=\"24\" height=\"24\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><rect x=\"4\" y=\"7.5\" width=\"16\" height=\"1.5\" \/><rect x=\"4\" y=\"15\" width=\"16\" height=\"1.5\" \/><\/svg><\/button>\n\t\t\t\t<div class=\"wp-block-navigation__responsive-container\"  id=\"modal-1\" \n\t\t\t\tdata-wp-class--has-modal-open=\"state.isMenuOpen\"\n\t\t\t\tdata-wp-class--is-menu-open=\"state.isMenuOpen\"\n\t\t\t\tdata-wp-watch=\"callbacks.initMenu\"\n\t\t\t\tdata-wp-on--keydown=\"actions.handleMenuKeydown\"\n\t\t\t\tdata-wp-on-async--focusout=\"actions.handleMenuFocusout\"\n\t\t\t\ttabindex=\"-1\"\n\t\t\t>\n\t\t\t\t\t<div class=\"wp-block-navigation__responsive-close\" tabindex=\"-1\">\n\t\t\t\t\t\t<div class=\"wp-block-navigation__responsive-dialog\" \n\t\t\t\tdata-wp-bind--aria-modal=\"state.ariaModal\"\n\t\t\t\tdata-wp-bind--aria-label=\"state.ariaLabel\"\n\t\t\t\tdata-wp-bind--role=\"state.roleAttribute\"\n\t\t\t>\n\t\t\t\t\t\t\t<button aria-label=\"Close menu\" class=\"wp-block-navigation__responsive-container-close\" \n\t\t\t\tdata-wp-on-async--click=\"actions.closeMenuOnClick\"\n\t\t\t><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z\"><\/path><\/svg><\/button>\n\t\t\t\t\t\t\t<div class=\"wp-block-navigation__responsive-container-content\" \n\t\t\t\tdata-wp-watch=\"callbacks.focusFirstElement\"\n\t\t\t id=\"modal-1-content\">\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div><\/nav>\n\n\n<a href=\"https:\/\/devia.infokand23.my.id\/about.html\" target=\"_blank\">Document<\/a>\n\n\n\n<a href=\"https:\/\/devia.infokand23.my.id\/index.html\" target=\"_blank\">Home<\/a>\n<\/div>\n<\/div>\n<\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading has-medium-font-size\">1. Tujuan<\/h3>\n\n\n\n<p class=\"has-small-font-size\">Tujuan praktikum ini yaitu pengguna mampu membuat membuat basic form untuk menerima inputan dari keyboard dan mengelola inputan :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"has-small-font-size\">Membuat beberapa input widgets<\/li>\n\n\n\n<li class=\"has-small-font-size\">Membuat dan mengontrol inputan dari user<\/li>\n\n\n\n<li class=\"has-small-font-size\">Menambahkan informasi error ketika memasukkan input yang tidak sesuai<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading has-medium-font-size\">2. Alat yang Digunakan<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>IDE (Visual Studio Code)<\/li>\n\n\n\n<li>Flutter &amp; Dart<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading has-medium-font-size\">3. Teori<\/h3>\n\n\n\n<p class=\"has-small-font-size\"><strong>Basic Form<\/strong><\/p>\n\n\n\n<p class=\"has-small-font-size\">Basic Form merupakan widget yang berfungsi sebagai inputan nilai seperti TextField, TextFormField, CheckBox, Switch, Dropdown, Radio, Dialog, DatePicker, BottomSheet, Snackbar dan lain-lain. Basic Form digunakan untuk validasi dan mengelola inputan dari berbagai field. Form ini akan memberikan tampilan inputan kemudian inputan akan diperiksa apakah sudah sesuai dengan aturan atau format yang ditetapkan, selanjtunya data inputan akan diambil nilainya setelah proses pengecekan selesai dilakukan.<\/p>\n\n\n\n<p class=\"has-small-font-size\"><strong>Text Field<\/strong><\/p>\n\n\n\n<p class=\"has-small-font-size\">TextField adalah widget yang digunakan untuk memasukkan text oleh pengguna, widget ini biasanya digunakan untuk membuat form inputan seperti form login, pencarian dll. fiturnya : Menerima input dari keyboard, Memiliki property yang lengkap style, decoration, dan jenis inputan dan Dapat mengelola teks menggunakan TextEditingController<\/p>\n\n\n\n<p class=\"has-small-font-size\"><strong>Text Form Field<\/strong><\/p>\n\n\n\n<p class=\"has-small-font-size\">TextFormField adalah widget versi lengkap dari TextField yang secara otomatis terintegrasi dengan logika validasi dan manajemen state dari sebuah form Fitur TextFormField antara lain : Menerima input teks dari keyboard, Memiliki properti validator yang berfungsi untuk memeriksa apakah input sudah sesuai dengan aturan yang ditentukan, Menampilkan pesan error secara otomatis di bawah field jika validasi gagal, dan Berinteraksi dengan FormState untuk melakukan validasi secara kolektif dengan validate() method.<\/p>\n\n\n\n<p>LANGKAH LANGKAH<\/p>\n\n\n\n<p>A. Basic Form TextField<\/p>\n\n\n\n<p class=\"has-small-font-size\">Buat file dart baru dengan nama\u00a0<code>form-textfield.dart<\/code>\u00a0di dalam folder lib<br>Buat sebuah tampilan basic form dengan menggunakan widget TextField untuk inputan dan ElevatedButton sebagai tombol event listener<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(\n          title: const Text('Basic Form'),\n        ),\n        body: const MyForm(),\n      ),\n    );\n  }\n}\n\nclass MyForm extends StatefulWidget {\n  const MyForm({super.key});\n\n  @override\n  State&lt;MyForm> createState() => _MyFormState();\n}\n\nclass _MyFormState extends State&lt;MyForm> {\n  String _inputText = '';\n  final _textEditingController = TextEditingController();\n\n  @override\n  void dispose() {\n    _textEditingController.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.all(20.0),\n      child: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: &#91;\n          const Text('Masukkan nama anda :'),\n          const SizedBox(\n            height: 10,\n          ),\n          TextField(\n            decoration: const InputDecoration(\n                labelText: 'Nama Lengkap',\n                hintText: 'masukan nama lengkap anda',\n                border: OutlineInputBorder(),\n                prefixIcon: Icon(Icons.person)),\n            controller: _textEditingController,\n            keyboardType: TextInputType.text,\n            onChanged: (text) {\n              print('Sedang mengetik teks : ,$text');\n            },\n          ),\n          const SizedBox(\n            height: 20,\n          ),\n          ElevatedButton(\n            onPressed: () {\n              String inputText = _textEditingController.text;\n              ScaffoldMessenger.of(context).showSnackBar(\n                  SnackBar(content: Text('Nama anda adalah: $inputText')));\n              setState(() {\n                _inputText = _textEditingController.text;\n              });\n            },\n            style: ElevatedButton.styleFrom(\n                backgroundColor: Colors.amber, foregroundColor: Colors.black),\n            child: const Text('Tampilkan Nama'),\n          ),\n          const SizedBox(\n            height: 20,\n          ),\n          Text(\n            'Nama anda: $_inputText',\n            style: const TextStyle(fontSize: 20),\n          ),\n        ],\n      ),\n    );\n  }\n}\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list has-small-font-size\">\n<li><strong>MyFormState<\/strong>: membuat variabel TextEditingController yang berguna untuk mengambil inputan dari pengguna, lalu membuat variabel yang membersihkan teks inputan<\/li>\n\n\n\n<li><strong>TextField<\/strong>: menambahkan controller properti jenis inputan agar bisa di lakukan aksi input dari pengguna<\/li>\n\n\n\n<li><strong>ElevatedButton<\/strong>: pada bagian onPressed ditambahkan program agar tombol bisa ditekan dan menampilkan inputan pengguna dari textfield ke dalam widget snackbar (yang biasanya berada di paling bawah halaman), bisa juga menampilkan inputan ke dalam suatu area teks<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"909\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-19.png\" alt=\"\" class=\"wp-image-303\" style=\"width:388px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-19.png 624w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-19-206x300.png 206w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure><\/div>\n\n\n<p class=\"has-small-font-size\">ketika memasukkan nama misalnya : Devia Puji Astuti <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"713\" height=\"987\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.25.30_ff1e078b.jpg\" alt=\"\" class=\"wp-image-305\" style=\"width:421px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.25.30_ff1e078b.jpg 713w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.25.30_ff1e078b-217x300.jpg 217w\" sizes=\"auto, (max-width: 713px) 100vw, 713px\" \/><\/figure><\/div>\n\n\n<p><\/p>\n\n\n\n<p>B. Basic Form TextFormField<\/p>\n\n\n\n<p>Buat file dart baru dengan nama&nbsp;<code>form-textformfield.dart<\/code>&nbsp;di dalam folder libBuat form inputan pengguna menggunakan widget TextFormField dan ElevatedButton beserta handling jika inputan tidak sesuai<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(\n          title: const Text(\"Basic Form TextFormField\"),\n        ),\n        body: const MyFormText(),\n      ),\n    );\n  }\n}\n\nclass MyFormText extends StatefulWidget {\n  const MyFormText({super.key});\n\n  @override\n  State createState() => _MyFormTextState();\n}\n\nclass _MyFormTextState extends State {\n  final _formKey = GlobalKey&lt;FormState>();\n  final _nameController = TextEditingController();\n  final _emailController = TextEditingController();\n\n  @override\n  void dispose() {\n    _nameController.dispose();\n    _emailController.dispose();\n    super.dispose();\n  }\n\n  void _submitForm() {\n    if (_formKey.currentState!.validate()) {\n      String name = _nameController.text;\n      String email = _emailController.text;\n\n      ScaffoldMessenger.of(context).showSnackBar(\n          SnackBar(content: Text('Validasi $name, $email Berhasil')));\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Form(\n      key: _formKey,\n      child: Padding(\n        padding: const EdgeInsets.all(20.0),\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.start,\n          children: &#91;\n            const SizedBox(\n              height: 10,\n            ),\n            TextFormField(\n              controller: _nameController,\n              decoration: const InputDecoration(\n                  labelText: \"Nama : \", border: OutlineInputBorder()),\n              validator: (value) {\n                if (value == null || value.isEmpty) {\n                  return 'Masukkan nama anda';\n                }\n                return null;\n              },\n            ),\n            const SizedBox(\n              height: 10,\n            ),\n            TextFormField(\n              controller: _emailController,\n              decoration: const InputDecoration(\n                  labelText: \"Email : \", border: OutlineInputBorder()),\n              validator: (value) {\n                if (value == null || value.isEmpty) {\n                  return 'Masukkan email anda ';\n                }\n                if (!value.contains('@')) {\n                  return 'Email tidak valid';\n                }\n                return null;\n              },\n            ),\n            const SizedBox(\n              height: 10,\n            ),\n            SizedBox(\n              width: double.infinity,\n              child: ElevatedButton(\n                  onPressed: _submitForm, child: const Text('Submit')),\n            )\n          ],\n        ),\n      ),\n    );\n  }\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list has-small-font-size\">\n<li><strong>_MyFormTextState<\/strong>: membuat controller untuk textformfield bagian nama dan email, lalu membuat method yang menghapus inputan nama dan email dan membuat method yang berjalan ketika ElevatedButton di tekan<\/li>\n\n\n\n<li><strong>TextFormField<\/strong>: membuat handling pada textformfield berdasarkan inputan yang diberikan pengguna kosong ataupun tidak sesuai dengan format biasanya<\/li>\n\n\n\n<li><strong>ElevatedButton<\/strong>: pada bagian onPressed ditambahkan method _submitform agar bisa menampilkan output Validasi Berhasil berupa Snackbar<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"673\" height=\"982\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.29.56_d003b20e.jpg\" alt=\"\" class=\"wp-image-306\" style=\"width:307px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.29.56_d003b20e.jpg 673w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.29.56_d003b20e-206x300.jpg 206w\" sizes=\"auto, (max-width: 673px) 100vw, 673px\" \/><\/figure><\/div>\n\n\n<p class=\"has-small-font-size\">dalam pengisiannya Ketika ElevatedButton ditekan dan TextField kosong dan ketika ElevatedButton ditekan dan TextField salah format maka nanti hasilnya akan merah<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"609\" height=\"261\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-21.png\" alt=\"\" class=\"wp-image-307\" style=\"width:331px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-21.png 609w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-21-300x129.png 300w\" sizes=\"auto, (max-width: 609px) 100vw, 609px\" \/><\/figure><\/div>\n\n\n<p class=\"has-small-font-size\">ketika diisi dengan format yang benar maka outputnya seperti dibawah ini.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"675\" height=\"994\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.48.50_b21341d3.jpg\" alt=\"\" class=\"wp-image-308\" style=\"width:405px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.48.50_b21341d3.jpg 675w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/Gambar-WhatsApp-2025-09-24-pukul-11.48.50_b21341d3-204x300.jpg 204w\" sizes=\"auto, (max-width: 675px) 100vw, 675px\" \/><\/figure><\/div>\n\n\n<!--nextpage-->\n\n\n\n<p>LATIHAN<\/p>\n\n\n\n<p class=\"has-small-font-size\">Buatlah aplikasi kalkulator yang dapat menjalankan operasi\u00a0kabataku\u00a0dengan menggunakan 2 buah widget inputan (TextField atau TextFormField), lalu menggunakan ElevatedButton dan widget text untuk menampilkan hasil opersi aritmatikanya. Berikut kode operasi aritmatika\u00a0kabataku<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import 'package:flutter\/material.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(\n          title: const Text('Aplikasi Kalkulator Sederhana'),\n        ),\n        body: const CalculatorForm(),\n      ),\n    );\n  }\n}\n\nclass CalculatorForm extends StatefulWidget {\n  const CalculatorForm({super.key});\n\n  @override\n  State&lt;CalculatorForm> createState() => _CalculatorFormState();\n}\n\nclass _CalculatorFormState extends State&lt;CalculatorForm> {\n  final _formKey = GlobalKey&lt;FormState>();\n  final _controller1 = TextEditingController();\n  final _controller2 = TextEditingController();\n  double _result = 0.0;\n  String _operation = '';\n\n  @override\n  void dispose() {\n    _controller1.dispose();\n    _controller2.dispose();\n    super.dispose();\n  }\n\n  void _calculate(String operation) {\n    if (_formKey.currentState!.validate()) {\n      double num1 = double.parse(_controller1.text);\n      double num2 = double.parse(_controller2.text);\n      double result;\n\n      setState(() {\n        _operation = operation;\n        switch (operation) {\n          case '+':\n            result = num1 + num2;\n            break;\n          case '-':\n            result = num1 - num2;\n            break;\n          case 'x':\n            result = num1 * num2;\n            break;\n          case '\/':\n            if (num2 != 0) {\n              result = num1 \/ num2;\n            } else {\n              \/\/ Menampilkan pesan error jika pembagian dengan nol\n              ScaffoldMessenger.of(context).showSnackBar(\n                const SnackBar(content: Text('Error: Pembagian dengan nol tidak diizinkan')),\n              );\n              return;\n            }\n            break;\n          default:\n            result = 0;\n        }\n        _result = result;\n      });\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Form(\n      key: _formKey,\n      child: Padding(\n        padding: const EdgeInsets.all(20.0),\n        child: Column(\n          children: &#91;\n            TextFormField(\n              controller: _controller1,\n              decoration: const InputDecoration(\n                labelText: 'Nilai Pertama',\n                border: OutlineInputBorder(),\n              ),\n              keyboardType: const TextInputType.numberWithOptions(decimal: true),\n              validator: (value) {\n                if (value == null || value.isEmpty) {\n                  return 'Masukkan angka';\n                }\n                if (double.tryParse(value) == null) {\n                  return 'Masukkan angka yang valid';\n                }\n                return null;\n              },\n            ),\n            const SizedBox(height: 16),\n            TextFormField(\n              controller: _controller2,\n              decoration: const InputDecoration(\n                labelText: 'Nilai Kedua',\n                border: OutlineInputBorder(),\n              ),\n              keyboardType: const TextInputType.numberWithOptions(decimal: true),\n              validator: (value) {\n                if (value == null || value.isEmpty) {\n                  return 'Masukkan angka';\n                }\n                if (double.tryParse(value) == null) {\n                  return 'Masukkan angka yang valid';\n                }\n                return null;\n              },\n            ),\n            const SizedBox(height: 24),\n            Row(\n              mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n              children: &#91;\n                ElevatedButton(onPressed: () => _calculate('+'), child: const Text('+')),\n                ElevatedButton(onPressed: () => _calculate('-'), child: const Text('-')),\n                ElevatedButton(onPressed: () => _calculate('x'), child: const Text('x')),\n                ElevatedButton(onPressed: () => _calculate('\/'), child: const Text('\/')),\n              ],\n            ),\n            const SizedBox(height: 24),\n            Text(\n              _operation.isEmpty\n                  ? 'Hasil: '\n                  : 'Hasil: $_result',\n              style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"has-small-font-size\">Kode ini membuat operasi aritmatika sederhana berdasarkan 2 buah inputan yang diisi oleh pengguna pada TextFormField yang mana menggunakan handling ketika pengguna memasukkan inputtan yang tidak sesuai formatnya.<\/p>\n\n\n\n<p class=\"has-small-font-size\">Berikut tampilan dari aplikasi kalkulator aritmatika sederhana<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"982\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-22.png\" alt=\"\" class=\"wp-image-309\" style=\"width:345px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-22.png 666w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-22-203x300.png 203w\" sizes=\"auto, (max-width: 666px) 100vw, 666px\" \/><\/figure><\/div>\n\n\n<p class=\"has-small-font-size\">seperti halnya sebuah kalkulator, kita hanya tinggal menginputkan nilainya saja dan nantinya hasil akan tertera. berikut contoh penjumlahan<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"674\" height=\"387\" src=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-23.png\" alt=\"\" class=\"wp-image-310\" style=\"width:357px;height:auto\" srcset=\"https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-23.png 674w, https:\/\/devia.infokand23.my.id\/laprak1\/wp-content\/uploads\/2025\/09\/image-23-300x172.png 300w\" sizes=\"auto, (max-width: 674px) 100vw, 674px\" \/><\/figure><\/div>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Input Widgets dan Basic Form GitHub Document Home 1. Tujuan Tujuan praktikum ini yaitu pengguna mampu membuat membuat basic form untuk menerima inputan dari keyboard dan mengelola inputan : 2. Alat yang Digunakan 3. Teori Basic Form Basic Form merupakan widget yang berfungsi sebagai inputan nilai seperti TextField, TextFormField, CheckBox, Switch, Dropdown, Radio, Dialog, DatePicker, &hellip; <a href=\"https:\/\/devia.infokand23.my.id\/laprak1\/laporan-praktikum-aplikasi-mobile-3\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">LAPORAN PRAKTIKUM APLIKASI MOBILE 3<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-296","post","type-post","status-publish","format-standard","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":6,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":312,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/posts\/296\/revisions\/312"}],"wp:attachment":[{"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devia.infokand23.my.id\/laprak1\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}