การจัดการข้อมูลของ Form Element อื่นๆ ใน Flutter
เขียนเมื่อ 1 ปีก่อน โดย Ninenik Narkdeecheckboxlisttile radiolisttile dropdownbuttonformfield flutter
คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ checkboxlisttile radiolisttile dropdownbuttonformfield flutter
ไปที่
Copy







เนื้อหาต่อไปนี้ จะมาดูต่อเกี่ยวกับการใช้งานฟอร์ม ต่อจาก
เนื้อหาตอนที่แล้ว ที่เราพูดถึงเกี่ยวกับการใช้งาน TextFormField
เป็นส่วนใหญ่ ยังมี widget เพิ่มเติมที่ใช้งามร่วมกับฟอร์ม รวมไปถึง
การจัดการกับข้อมูลที่ได้จากฟอร์ม เพื่อนำไปใช้งานต่อ
ทบทวนตอนที่แล้วได้ที่บทความ
การใช้งาน Form และ Form Validation ใน Flutter http://niik.in/1048
https://www.ninenik.com/content.php?arti_id=1048 via @ninenik
*เนื้อหานี้ใช้เนื้อหาต่อเนื่องจากบทความ http://niik.in/961
การใช้งาน Checkbox
เราสามารถกำหนด checkbox ให้กับฟอร์มด้วย 2 widget คือ Checkbox กับ CheckboxListTile
แต่เราจะแนะนำเป็น CheckboxListTile() ที่จะใช้งานได้งายและสะดวกกว่า เพราะเป็นการนำเอา ListTile กับ
Checkbox มารวมกัน สามารถกดที่พื้นที่ของ ListTile หรือข้อความแทนการกดที่ตัว checkbox โดยตรง
สามารถจัดตำแหน่งไม่ว่าจะไว้ด้านหน้าข้อความ หรือด้านหลังข้อความก็ทำได้ง่าย
ดูตัวอย่างการใช้งาน checkbox ทั้งสองแบบ
ListTile( title: Text('This is title'), trailing: Checkbox( value: _termsChecked, onChanged: (bool? value) { setState(() { _termsChecked = value!; }); }, ), ), CheckboxListTile( value: _termsChecked, onChanged: (value) { setState(() { _termsChecked = value!; }); }, subtitle: !_termsChecked ? Text( 'Required', style: TextStyle(color: Colors.red, fontSize: 12.0), ) : null, title: new Text( 'I agree to the terms and condition', ), controlAffinity: ListTileControlAffinity.leading, ),
ผลลัพธ์ที่ได้

ตัวแรกเราต้องจัดรูปแบบใน ListTile อีกที แต่ตัวที่สองเราสามารถใช้งานคล้าย ListTile ได้เลย
ในที่นี้จะพูดถึง CheckboxListTile
ตัว checkbox จะรองรับค่าหรือ value ที่เป็น boolean เวลาเราจะใช้งาน ต้องกำหนดตัวแปร boolean
เพื่อรับค่ามาใช้งาน ใช้สำหรับตอบรับ หรือปฏิเสธในกรณีเงื่อนไขให้เลือก 1 รายการ อย่างในตัวอย่าง
เป็นการให้เลือก ตอบรับ ข้อกำหนดของการใช้งาน
ในกรณีใช้เป็นตัวเลือกหลายๆ รายการ จะหมายถึง ตอบรับกับรายการตัวเลือกนั้นๆ หรือไม่ ดูตัวอย่าง
// กำหนดตัวแปร ลิสรายการ checkbox List<Map<String, bool>> hobbies = [ {'อ่านหนังสือ': true}, {'วาดรูป': false}, {'ดูหนัง': true}, {'ช้อปปิ้ง': true}, ]; // กำหนดตัวแปร เก็บค่าของแต่ละ checkbxo List<bool> _checkHobby = [];
ต่อไปส่วนของการวนลูปแสดงข้อมูล และใช้งาน
Divider(), // ตัว widget แบ่ง Builder(builder: (context) { // เราใช้ Builder เพื่อที่จะใช้งานฟังก์ชั่นสร้าง widget ได้ List<Widget> list = <Widget>[]; hobbies.asMap().forEach((index, hobby){ // วนลูปสร้างลิสรายการ var key = hobby.keys.toList(); // แปลงเป็น list ของ key var val = hobby.values.toList(); // แปลงเป็น list ของ value _checkHobby.add(val[0]); // เก็บค่า value ขแงแต่ละรายการ list.add(CheckboxListTile( value: _checkHobby[index], // ใช้ค่า value ของแต่ละรายการ onChanged: (value) { setState(() { _checkHobby[index] = value!; // เปลี่ยนค่าเมื่อมีการเลือกหรือไม่เลือก }); }, title: Text( '${key[0]}', ), controlAffinity: ListTileControlAffinity.leading, )); }); return Column( // คืนค่าเป็นรายการ checkbox ในคอลัมน์ children: list, ); }),
ผลลัพธ์ที่ได้

กรณีมีตัวเลือกหลายรายการ จะเป็นลักษณะ ว่าแต่ละรายการเราเลือกหรือไม่
การใช้งาน Radio
รูปแบบการใช้งาน radio ร่วมกับฟอร์ม ก็สามารถทำได้คล้ายๆ กับ checkbox โดยเราสามารถใช้ได้ทั้ง
Radio กับ RadioListTile และวิธีการที่สะดวกและง่ายก็แนะนำเป็น RadioListTile
radio จะใช้สำหรับให้เลือกอย่างใดอย่างหนึ่งเพียงอย่างเดียว จากรายการที่แสดงให้เลือก โดยค่าที่กำหนดให้
กับ radio จะเป็น object แตกต่างจาก checkbox ซึ่ง object หรือ class ที่เหมาะจะมาใช้เป็นข้อมูล radio ก็คือ
enum ( มีอธิบายไว้ในบทความ http://niik.in/1044 )
อย่างสมมติเช่น เรากำหนดสีตัวเลือก ให้ผู้ใช้ระบุ ก็จะกำหนดเป็น
enum ColorOption { red, green, blue }
อย่าลืมว่า enum เป็น class หนึ่ง ดังนั้นเวลาระบุ ก็ต้องกำหนดไว้ด้านนอกของ class อื่นๆ
ปกติจะใช้ radio ในการกำหนดตัวเลือกที่ไม่มากนัก ดูตัวอย่าง การเลือกเพศ ชาย หญิง
สิ่งแรกก็คือกำหนด class หรือ object ของค่าข้อมูลที่จะใช้งาน
enum Gender { male, female }
จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
// กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก Gender? _selectedGender = Gender.male; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String? _selectedGenderText = 'ชาย';
เรากำหนดตัวแปรค่าเริ่มต้นสำหรับรายการที่ถูกเลือก และกำหนดตัวแปร
ข้อมูลเพิ่มเติม สำหรับนำไปใช้งาน อย่างข้างต้น ให้ค่าเริ่มต้นเป็น male และข้อความ
ที่สัมพันธ์ก็คือ เพศ 'ชาย'
ตัวอย่างการเรียกใช้งาน RadioListTile
Column( children: <Widget>[ RadioListTile( title: const Text('Male'), value: Gender.male, // ค่าของตัวเล็อก male groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = (_selectedGender == Gender.male) ? 'ชาย' : 'หญิง'; }); }, controlAffinity: ListTileControlAffinity.leading, ), RadioListTile( title: const Text('Female'), value: Gender.female, // ค่าของตัวเล็อก female groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = (_selectedGender == Gender.male) ? 'ชาย' : 'หญิง'; }); }, controlAffinity: ListTileControlAffinity.leading, ), ],
ผลลัพธ์ที่ได้

ค่าเริ่มต้นที่ถูกเลือกเป็น male เมื่อเรากดปุ่ม submit ก็จะแสดงในส่วนของข้อความที่เรากำหนดไว้ใช้งาน
ให้สัมพันธ์กับข้อมูลที่เลือก
สมมติเราอยากสร้างรายการ radio รองรับจำนวนมากขึ้นมาหน่อย ก็สามารถใช้เป็นแบบนี้ได้
enum ColorOption { red, green, blue }
จากนั้นเราก็กำหนดตัวแปรค่าเริ่มต้น
// กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก ColorOption? _selectedColorOption = ColorOption.red; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String _selectedColorOptionText = 'สีแดง'; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิงในลูป List<String> _listColorOptionText = ['สีแดง', 'สีเขียว', 'สีน้ำเงิน'];
ตัวอย่างการเรียกใช้งาน RadioListTile
Divider(), Builder(builder: (context) { List<Widget> list = <Widget>[]; ColorOption.values.asMap().forEach((index, val){ list.add( RadioListTile( title: Text(_listColorOptionText[index]), value: val, // ค่าของตัวเล็อก female groupValue: _selectedColorOption, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (ColorOption? value) { setState(() { _selectedColorOption = value; _selectedColorOptionText = _listColorOptionText[index]; }); }, controlAffinity: ListTileControlAffinity.leading, ), ); }); return Column( children: list, ); }),
ผลลัพธ์ที่ได้

วิธีนี้เหมาะกับรายการตัวเลือกที่มีจำนวนมากๆ เวลากำหนดก็จะทำได้ง่ายขึ้น กว่าการเพิ่มทีละตัว
การใช้งาน Dropdown
ใช้สำหรับแสดงลิสรายการเพื่อให้ผู้ใช้เลือกหรือกำหนดค่าที่ต้องการ คล้ายกับการเลือกของ radio ที่จะ
สามารถเลือกได้เพียงอันเดียว จากรายการทั้งหมด การใช้งาน DropdownButtonFormField จะรองรับสำหรับ
ฟอร์มมากกว่าการใช้งาน DropdownButton ธรรมดา ดูตัวอย่างทั้งสองรูปแบบ เบื้องต้น
DropdownButton<String>( value: _dropdownValue, onChanged: (String? newValue) { setState(() { _dropdownValue = newValue!; }); }, isExpanded: true, items: <String>['One', 'Two', 'Three', 'Four'] .map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), SizedBox(height: 5.0,), DropdownButtonFormField<String>( value: null, onChanged: (value) { setState(() { _dropdownValue = value!; }); }, hint: Text('Rating'), isExpanded: true, items: <String>['One', 'Two', 'Three', 'Four'] .map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ),
ผลลัพธ์ที่ได้

มาดูวิธีการกำหนดและใช้งานสำหรับฟอร์ม
// กำหนดตัวแปรสำหรับลิสรายการ List<String> maritalStatus = ['โสด','แต่งงาน','หย่า','หม้าย']; // กำหนดตัวแปรสำหรับเก็บค่าที่เลือก เริ่มต้นเป็นค่าว่าง String _seslectedMaritalStatus = '';
ต่อไปเรียกใช้งานเป็นดังนี้
Divider(), DropdownButtonFormField<String>( value: null, autovalidateMode: AutovalidateMode.always, // validator: (value) => (value == null) ? 'เลือกสถานะการแต่งงาน' : null, validator: Validators.required('เลือกสถานะการแต่งงาน'), onChanged: (value) { setState(() { _seslectedMaritalStatus = value!; }); }, hint: Text('สถานะการแต่งงาน'), isExpanded: true, items: maritalStatus.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ),
ผลลัพธ์ที่ได้

จะเห็นว่า DropdownButtonFormField รองรับการตรวจสอบข้อมูลด้วย validator เหมือนกับ TextFormField
เราสามารถสร้าง List<String> เพื่อวนลูปสร้างรายการตัวเลือกให้กับ dropbox ได้ง่าย
ตอนนี้เราได้รู้จัก element ที่ใช้งานร่วมกับฟอร์มเพิ่มเติม รวมถึง TextFormFiled จากบทความตอนที่แล้ว เราได้
รู้จักวิธีการสร้างลิสรายการสำหรับแต่ละ widget รู้จักกำหนดตัวแปรสำหรับรับค่าเพื่อนำไปใช้งานต่อ
เราจะลองสร้างฟอร์มสมมติ โดยรวม element ต่างๆ มาไว้ด้วยกันในฟอร์ม ตามตัวอย่างข้างล่าง และรูปแบบการ
กำหนดสำหรับเป็นข้อมูลของฟอร์ม เมื่อกดส่งข้อมูล จะจำลองการแสดงข้อมูลที่เป็น Map
ไฟล์ contact.dart
import 'package:flutter/material.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/intl.dart'; import 'package:flutter/services.dart'; import '../validations/validation.dart'; class Contact extends StatefulWidget { static const routeName = '/contact'; const Contact({Key? key}) : super(key: key); @override State<StatefulWidget> createState() { return _ContactState(); } } class _ContactState extends State<Contact> with Validators { // กำหนดข้อมูลฟิลด์ สำหรับบันทึก final Map<String, dynamic> formData = { 'email': null, 'password': null, 'birthday': null, 'gender': null, 'hobby': null, 'maritalstatus': null, }; // สร้างฟอร์ม key หรือ id ของฟอร์มสำหรับอ้างอิง final _formKey = GlobalKey<FormState>(); late DateFormat dateFormat; // รูปแบบการจัดการวันที่และเวลา // กำหนดตัวแปรรับค่า final _text1 = TextEditingController(); final _text2 = TextEditingController(); final _text3 = TextEditingController(); final _text4 = TextEditingController(); // กำหนดตัวแปร ลิสรายการ checkbox List<Map<String, bool>> hobbies = [ {'อ่านหนังสือ': true}, {'วาดรูป': false}, {'ดูหนัง': true}, {'ช้อปปิ้ง': true}, ]; // กำหนดตัวแปร เก็บค่าของแต่ละ checkbxo List<bool> _checkHobby = []; List<String> _checkedHobby = []; // ค่าสำหรับส่งไปใช้งาน // กำหนดตัวแปรค่าเริ่มต้นของรายการที่่ถูกเลือก Gender? _selectedGender = Gender.male; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิง String? _selectedGenderText = 'ชาย'; // กำหนดตัวแปรสำหรับใช้เก็บข้อความอ้างอิงในลูป List<String> _listGenderText = ['ชาย', 'หญิง']; // กำหนดตัวแปรสำหรับลิสรายการ List<String> maritalStatus = ['โสด','แต่งงาน','หย่า','หม้าย']; // กำหนดตัวแปรสำหรับเก็บค่าที่เลือก เริ่มต้นเป็นค่าว่าง String _seslectedMaritalStatus = ''; // กำหนดสถานะการแสดงแบบรหัสผ่าน bool _isHidden = true; bool _termsChecked = false; void _selectDate() async { final DateTime? newDate = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2017, 1), lastDate: DateTime(2022, 7), helpText: 'Select a date', ); if (newDate != null) { setState(() { _text2.value = TextEditingValue(text: dateFormat.format(newDate).toString()); }); } } // เกียวกับการใช้เวลา /// แปลงเวลาจากวันที่ TimeOfDay.fromDateTime(DateTime.now()) /// เวลาปัจจุบัน TimeOfDay.now() /// แบบกำหนดเอง TimeOfDay(hour: 7, minute: 15), void _selectTime() async { final TimeOfDay? newTime = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (newTime != null) { setState(() { _text2.value = TextEditingValue(text: newTime.format(context)); }); } } @override void initState() { // กำหนดรูปแบบการจัดการวันที่และเวลา Intl.defaultLocale = 'en'; initializeDateFormatting(); dateFormat = DateFormat('d/MM/y','en'); } @override void dispose() { _text1.dispose(); // ยกเลิกการใช้งานที่เกี่ยวข้องทั้งหมดถ้ามี _text2.dispose(); _text3.dispose(); _text4.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Contact Us'), ), body: SingleChildScrollView( child: Form( // ใช้งาน Form key: _formKey, // กำหนด key child: Padding( padding: const EdgeInsets.all(10.0), child: Column( children: <Widget>[ // กำหนด widget ที่จะใช้งานกับฟอร์ม TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( hintText: 'อีเมล', icon: Icon(Icons.email_outlined), ), controller: _text1, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.compose([ Validators.required('กรุณาระบุอีเมล'), Validators.email('กรุณาใส่อีเมลให้ถูกต้อง') ]), ), SizedBox(height: 5.0,), TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( icon: Icon(Icons.vpn_key), hintText: 'รหัสผ่าน', suffixIcon: IconButton( onPressed: (){ setState(() { _isHidden = !_isHidden; // เมื่อกดก็เปลี่ยนค่าตรงกันข้าม }); }, icon: Icon( _isHidden // เงื่อนไขการสลับ icon ? Icons.visibility_off : Icons.visibility ), ), ), controller: _text3, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.required('กรุณาระบุรห้สผ่าน'), obscureText: _isHidden, // การซ่อนหรือแสดงข้อความในรูปแบบรหัสผ่าน ), SizedBox(height: 5.0,), TextFormField( autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( hintText: 'วันเกิด', icon: Icon(Icons.date_range), ), controller: _text2, // ผูกกับ TextFormField ที่จะใช้ validator: Validators.required('กรุณาระบุวันเกิด'), onTap: _selectDate, readOnly: true, ), Divider(), Builder(builder: (context) { List<Widget> list = <Widget>[]; Gender.values.asMap().forEach((index, val){ list.add( RadioListTile( title: Text(_listGenderText[index]), value: val, // ค่าของตัวเล็อก female groupValue: _selectedGender, // ใช้กลุ่มค่าที่ถูกเลือกเป็นตัวแปรเดียวกัน onChanged: (Gender? value) { setState(() { _selectedGender = value; _selectedGenderText = _listGenderText[index]; }); }, controlAffinity: ListTileControlAffinity.leading, ), ); }); return Column( children: list, ); }), Divider(), // ตัว widget แบ่ง Builder(builder: (context) { // เราใช้ Builder เพื่อที่จะใช้งานฟังก์ชั่นสร้าง widget ได้ List<Widget> list = <Widget>[]; _checkedHobby.clear(); hobbies.asMap().forEach((index, hobby){ // วนลูปสร้างลิสรายการ var key = hobby.keys.toList(); // แปลงเป็น list ของ key var val = hobby.values.toList(); // แปลงเป็น list ของ value _checkHobby.add(val[0]); // เก็บค่า value ขแงแต่ละรายการ if(_checkHobby[index]) _checkedHobby.add(key[0]); // เก็บรายการที่เลือก list.add(CheckboxListTile( value: _checkHobby[index], // ใช้ค่า value ของแต่ละรายการ onChanged: (value) { setState(() { _checkHobby[index] = value!; // เปลี่ยนค่าเมื่อมีการเลือกหรือไม่เลือก }); }, title: Text( '${key[0]}', ), controlAffinity: ListTileControlAffinity.leading, )); }); return Column( // คืนค่าเป็นรายการ checkbox ในคอลัมน์ children: list, ); }), Divider(), DropdownButtonFormField<String>( value: null, autovalidateMode: AutovalidateMode.always, decoration: InputDecoration( icon: Icon(Icons.family_restroom_outlined), ), validator: Validators.required('เลือกสถานะการแต่งงาน'), onChanged: (value) { setState(() { _seslectedMaritalStatus = value!; }); }, hint: Text('สถานะการแต่งงาน'), isExpanded: true, items: maritalStatus.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), Divider(), CheckboxListTile( value: _termsChecked, onChanged: (value) { setState(() { _termsChecked = value!; }); }, subtitle: !_termsChecked ? Text( 'ต้องระบุ', style: TextStyle(color: Colors.red, fontSize: 12.0), ) : null, title: new Text( 'ยอมรับเงื่อนไขและข้อตกลงการใช้งาน', ), controlAffinity: ListTileControlAffinity.leading, ), ElevatedButton( onPressed: () { // อ้างอิงฟอร์มที่กำลังใช้งาน ตรวจสอบความถูกต้องข้อมูลในฟอร์ม if (_formKey.currentState!.validate()) { //หากผ่าน formData['email'] = _text1.text; formData['password'] = _text2.text; formData['birthday'] = _text3.text; formData['gender'] = _selectedGenderText; formData['hobby'] = _checkedHobby; formData['maritalstatus'] = _seslectedMaritalStatus; // print(formData); // แสดงข้อความจำลอง ใน snackbar ScaffoldMessenger.of(context).showSnackBar( // นำค่าข้อมูลไปแสดงหรือใช้งานผ่าน controller SnackBar(content: Text('Process Data...${formData}')), ); } }, child: const Text('Submit'), ), ], ), ), ), ), ); } } // กำหนดข้อมูลสำหรับ radio enum Gender { male, female }
ผลลัพธ์ที่ได้

เมื่อทำการ submit หรือ validate ฟอร์มผ่านแล้ว เราทำการเก็บค่าข้อมูลทั้งหมด ไว้ใน Map ที่ชื่อ
formData เพื่อนำไปใช้งานต่อ ข้างต้น เราแค่แสดงผลข้อมูลด้วย snackBar
สำหรับเนื้อหาเกี่ยวกับการใช้งาน element ของฟอร์มเพิ่มเติมในตอนนี้ก็มีประมาณนี้ หวังว่าจะเป็แแนวทาง
นำไปปรับใช้งานต่อไป เนื้อหาตอนหน้า เราจะนำสิ่งที่ได้เรียนรู้เกี่ยวกับฟอร์มทั้งสองตอนนี้ ไปประยุกต์
กับการใช้งานฟอร์มที่บันทึกลงฐานข้อมูลหนังสือของบทความก่อนหน้า รอติดตาม
กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ

อ่านต่อที่บทความ
-
11 Nov2021ประยุกต์ใช้งาน Form บันทึกลงฐานข้อมูล ใน Flutter อ่าน 2,794
เนื้อหานี้จะเป็นเนื้อหาประยุกต์เพิ่มเติม เล็กน้อยเกี่ยวกับการ ปรับใช้งานฟ
เนื้อหาที่เกี่ยวข้อง
-
23 Oct2021จัดการ Tab ด้วย TabController ใน Flutter อ่าน 5,373
เนื้อหานี้มาดูเกี่ยวกับการใช้งาน tab ใน flutter ซึ่งเป็นรูปแบบ การใช้งานท
-
24 Oct2021การใช้งาน FutureBuilder ที่เป็น Async widgets ใน Flutter อ่าน 4,211
เนื้อหาตอนต่อไปนี้ จะมาดูเกี่ยวกับการใช้งาน async widgets ที่ชื่อว่า Futu
-
25 Oct2021การใช้งาน StreamBuilder จัดการข้อมูล Stream ใน Flutter อ่าน 3,651
ในตอนที่แล้วเรารู้จักกับ FutureBuilder ซึ่งเป็น async widgets หนึ่งใน Flu
-
26 Oct2021การใช้งาน Http ดึงข้อมูลจาก Server มาแสดงใน Flutter อ่าน 7,511
เนื้อหาตอนต่อไปนี้ เราจะมาดูเกี่ยวกับวิธีการดึงข้อมูลจาก Server ที่เป็นข้
-
27 Oct2021การใช้งาน Card Widget ร่วมกับ ListView ใน Flutter อ่าน 5,066
เนื้อหาตอนต่อไปนี้ จะมาดูเกี่ยวกับ widget เล็กๆ ที่จะมาช่วย ให้การแสดงผลใ
-
28 Oct2021การใช้งาน RefreshIndicator ปัดเพื่อรีเฟรชข้อมูล ใน Flutter อ่าน 3,234
ต่อเนื่องจากเนื้อหาตอนที่แล้ว เนื้อหานี้เราจะมาดูเกี่ยวกับ widget ที่ให้เ
-
29 Oct2021จัดการข้อมูล Model และแนวทางการนำมาใช้งาน ใน Flutter อ่าน 4,234
เนื้อหาตอนต่อไปนี้จะประยุกต์ต่อเนื่องจากตอนที่แล้ว เราจะลองใช้ ข้อมูลทดสอ
-
30 Oct2021การใช้งาน GridView widget ใน Flutter อ่าน 6,966
เนื้อหาตอนต่อไปนี้ จะมาดูเกี่ยวกับการใช้งาน GridView เป็นเนื้อหาต่อ
-
31 Oct2021การใช้งาน WebView แสดงเว็บไซต์ ใน Flutter อ่าน 5,113
เนื้อหานี้จะมาดูเกี่ยวกับการใช้งาน WebView widget ซึ่งจะเป็น package ที่เ
-
01 Nov2021การกำหนดและใช้งาน PopupMenuButton ใน Flutter อ่าน 2,417
เนื้อหาตอนต่อไปนี้จะมาดู Widget เล็กๆ ที่มีรูปแบบการใช้งาน ง่ายๆ ที่เรียก
-
02 Nov2021การกำหนดและใช้งาน BottomSheet ใน Flutter อ่าน 2,865
เนื้อหาต่อไปนี้จะมาดูเกี่ยวกับการใช้งาน Bottom Sheet ส่วน ที่ใช้สำหรับแสด
-
05 Nov2021การใช้งาน Provider จัดการข้อมูล App State ใน Flutter อ่าน 8,771
เนื้อหาตอนต่อไปนี้เราจะมาดูเกี่ยวกับการใช้งาน provider จ้ดการข้อมูล app s
-
06 Nov2021จัดการข้อมูลด้วย SQL Database โดยใช้ Sqflite ใน Flutter อ่าน 7,914
เนื้อหาตอนต่อไปนี้จะมาแนะนำ การบันทึกข้อมูลไว้ใน app ในรูปแบบ SQLite data
-
08 Nov2021การใช้งาน Form และ Form Validation ใน Flutter อ่าน 9,267
เนื้อหาตอนต่อไปนี้ เราจะมาดูเกี่ยวกับการใช้งาน form ใน flutter เริ่มตั้งแ
-
กำลังอ่านเนื้อหานี้อยู่10 Nov2021การจัดการข้อมูลของ Form Element อื่นๆ ใน Flutter อ่าน 2,831
เนื้อหาต่อไปนี้ จะมาดูต่อเกี่ยวกับการใช้งานฟอร์ม ต่อจาก เนื้อหาตอนที่แล้ว
-
11 Nov2021ประยุกต์ใช้งาน Form บันทึกลงฐานข้อมูล ใน Flutter อ่าน 2,794
เนื้อหานี้จะเป็นเนื้อหาประยุกต์เพิ่มเติม เล็กน้อยเกี่ยวกับการ ปรับใช้งานฟ
URL สำหรับอ้างอิง
Top
Copy
ขอบคุณทุกการสนับสนุน
![]()