ຮວບຮວມ Widgets ຂອງ Flutter ທີ່ຖືກໃຊ້ເປັນປະຈຳ (Part 1)
ສະບາຍດີ! ໃນບົດຄວາມນີ້ Comet ໄດ້ຂົນເອົາບັນດາ widget ທີ່ສຳຄັນ ແລະ ຖືກໃຊ້ເປັນປະຈຳໃນ Flutter ພ້ອມທັງຄຳອະທິບາຍວິທີການໃຊ້ແຕ່ລະ widget ໃຫ້ທຸກຄົນໄດ້ອ່ານ ແລະ ນຳໄປໃຊ້ຕົວຈິງ, ເຊິ່ງເຮົາຈະແບ່ງຫົວຂໍ້ນີ້ອອກເປັນ 2 ບົດຄວາມ ເພາະຖ້າບໍ່ແບ່ງອອກມາຈະຍາວວ~ຍາວວວວ~~ 🤣
ແລະ ບັນດາ widgets ທີ່ເຮົາຈະໄດ້ຮຽນຮູ້ໃນບົດຄວາມນີ້ມີຄື:
I. Text fields
II. Buttons
III. Image
I. Text fields
Text fields ເປັນ widget ທີ່ໃຫ້ຜູ້ໃຊ້ສາມາດປ້ອນຂໍ້ມູນເຂົ້າສູ່ application ເຊິ່ງໃນ Flutter ມີ text fields ຢູ່ 2 ປະເພດຄື: TextField
ແລະ TextFormField
.
TextField
ແມ່ນ widget ທີ່ໃຊ້ຮັບ input ຈາກຜູ້ໃຊ້.
ການສ້າງ TextField
ແບບພື້ນຖານ
TextField()
TextFormField
ແມ່ນ widget ທີ່ຄ້າຍຄືກັບ
TextField
ແຕ່ສ່ວນຫຼາຍເຮົາຈະໃຊ້TextFormField
ໃນກໍລະນີທີ່ຕ້ອງການ validate ຫຼື ກວດສອບຂໍ້ມູນ.
ການສ້າງ TextFormField
ແບບພື້ນຖານ
TextFormField()
ເຮົາສາມາດປັບປ່ຽນ text field ໂດຍໃຊ້ property ຕ່າງໆດັ່ງນີ້:
initialValue
: ກຳນົດຄ່າເລີ່ມຕົ້ນຂອງ text field (ສຳລັບ TextFormField)keyboardType
: ເລືອກປະເພດ keyboard ເຊັ່ນ: text, number, email.obscureText
: ກຳນົດວ່າໃຫ້ປິດຕົວໜັງສື ຫຼື ບໍ່ (ເຊັ່ນ ກໍລະນີປ້ອນ password).maxLine
: ກຳນົດໃຫ້ມີສູງສຸດຈັກແຖວ.maxLength
: ກຳນົດໃຫ້ປ້ອນໄດ້ສູງສຸດຈັກໂຕtextAlign
: ກຳນົດວ່າ text ຄວນຖືກວາງແນວໃດ.textCapitalization
: ເປັນການກຳນົດການເຮັດຕົວໜັງສືເປັນຕົວພິມໃຫຍ່. ຕົວຢ່າງ: ເຮັດໃຫ້ຕົວພິມໃຫຍ່ສະເພາະຕົວທຳອິດຂອງປະໂຫຍກ ຫຼື ຕົວທຳອິດຂອງຄຳ.
ການປັບແຕ່ງ text field
ການປັບແຕ່ງ TextField
ແລະ TextFormField
ສາມາດເຮັດໄດ້ໃນ property ທີ່ຊື່ວ່າ decoration
TextField(
textCapitalization: TextCapitalization.characters,
decoration: InputDecoration(
prefixIcon: Icon(Icons.email),
labelText: 'Email',
hintText: 'example@gmail.com',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(color: Colors.teal, width: 2)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide(width: 2)),
),
)
prefixIcon
: ກຳນົດ icon ທີ່ສະແດງກ່ອນບ່ອນ input ຂອງ TextFieldlabelText
: ຕົວໜັງສືທີ່ສະແດງໃນບ່ອນຂໍ້ມູນ, ໃນເວລາທີ່ textfield ຖືກໃຊ້ງານ (focus) ມັນຈະຍ້າຍໄປຢູ່ເທິງ.hintText
: ຕົວໜັງສືທີ່ແນະນຳວ່າໃຫ້ປ້ອນຂໍ້ມູນແບບໃດenabledBorder
: ປັບແຕ່ງຂອບຂອງ TextField ກໍລະນີທີ່ເປັນ text field ທີ່ໃຊ້ງານໄດ້ (enabled text field)focusedBorder
: ປັບແຕ່ງຂອບຂອງ TextField ທີ່ຜູ້ໃຊ້ກຳລັງ focus ຫຼື ໃຊ້ງານຢູ່
Note: ນອກຈາກ
enabledBorder
ແລະfocusedBorder
ແລ້ວ, ເຮົາຍັງສາມາດແກ້ໄຂຮູບແບບຂອງerrorBorder
ແລະdisabledBorder
ໄດ້ນຳ.
ການຮັບຄ່າທີ່ປ້ອນເຂົ້າ text field
ການຮັບຄ່າຈາກ text field ເປັນສິ່ງທີ່ສຳຄັນທີ່ສຸດໃນການໃຊ້ text field. ໃນ Flutter, ເຮົາສາມາດເຮັດໄດ້ໂດຍໃຊ້ TextEditingController
.
TextEditingController
ໃຊ້ໃນການຄວບຄຸມ text field, ມັນຈະຟັງການປ່ຽນແປງຂອງ text field ແລະ ອັບເດດຄ່າຂອງມັນທຸກໆຄັ້ງທີ່ text ໃນ text field ມີການປ່ຽນແປງ.
ໃນຕົວຢ່າງນີ້ ເຮົາໄດ້ເພີ່ມ Button
ແລະ Text
ເພື່ອໃຫ້ Text
ສະແດງຂໍ້ຄວາມທີ່ພິມໃນ text field ຫຼັງຈາກກົດປຸ່ມ “Show text”.
- ສ້າງ
TextEditingController
ແລະ ປະກາດຕົວປ່ຽນmyText
ເພື່ອຮັບຄ່າຈາກ text field
final myController = TextEditingController();
String myText = '';
2. ເຊື່ອມຕໍ່ TextEditingController
ເຂົ້າ text field ທີ່ຕ້ອງການ (TextField ຫຼື TextFormField).
TextField(
controller: myController,
),
3. ທຸກຄັ້ງທີ່ກົດປຸ່ມ “Show text” ໃຫ້ set ຄ່າຂອງ myText
ໃຫ້ເທົ່າກັບ myController.text
ElevatedButton(
onPressed: () {
setState(() {
myText = myController.text;
});
},
child: const Text('Show text')),
4. ສ້າງ widget Text
ເພື່ອສະແດງຄ່າ myText
ຫຼັງຈາກກົດປຸ່ມ
Text(
myText,
style: const TextStyle(fontSize: 20),
),
Code ທັງໝົດ
class RetrieveValueFromTextField extends StatefulWidget {
const RetrieveValueFromTextField({super.key});
@override
State<RetrieveValueFromTextField> createState() =>
_RetrieveValueFromTextFieldState();
}
class _RetrieveValueFromTextFieldState
extends State<RetrieveValueFromTextField> {
final myController = TextEditingController();
String myText = '';
@override
void dispose() {
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: myController,
),
const SizedBox(
height: 30,
),
ElevatedButton(
onPressed: () {
setState(() {
myText = myController.text;
});
},
child: const Text('Show text')),
const SizedBox(
height: 30,
),
Text(
myText,
style: const TextStyle(fontSize: 20),
)
],
);
}
}
Note: ຢ່າລືມ dispose TextEditingController ໃນຕອນທີ່ບໍ່ໄດ້ໃຊ້ແລ້ວເພື່ອໃຫ້ປະຢັດ memory.
ຜົນທີ່ໄດ້:
ການເຮັດ validation ໃນ TextFormField
Validation ແມ່ນການກວດສອບວ່າຜູ້ໃຊ້ໄດ້ປ້ອນຂໍ້ມູນຄົບຖ້ວນບໍ່ ຫຼື ຂໍ້ມູນທີ່ຜູ້ໃຊ້ປ້ອນມານັ້ນຖືກຕ້ອງຕາມທີ່ກຳນົດໄວ້ບໍ່.
- ສ້າງ GlobalKey ທີ່ຊື່ວ່າ
_formKey
final _formKey = GlobalKey<FormState>();
GlobalKey ມີຄວາມສຳຄັນຫຼາຍ ເພາະມັນສາມາດເຂົ້າເຖິງ state ປັດຈຸບັນຂອງ widget ຈາກບ່ອນອື່ນໄດ້ ແລະ ເຮັດໃຫ້ເຮົາສາມາດເຂົ້າເຖິງ FormState
ແລະ ເຮັດ validation ໄດ້.
2. ສ້າງ Form
ແລະ set _formKey
ໃຫ້ກັບ key
ໃນ Form widget.
class FormValidation extends StatefulWidget {
const FormValidation({super.key});
@override
State<FormValidation> createState() => _FormValidationState();
}
class _FormValidationState extends State<FormValidation> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [],
));
}
}
3. ສ້າງ TextFormField
ແລະ ຂຽນ validation logic ໃນ validator
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter this field';
}
return null;
},
),
ໃນນີ້ເຮົາຂຽນວ່າ ຖ້າຄ່າຂອງ text ໃນ TextFormField
ເປັນ null ຫຼື ເປັນ empty ໃຫ້ return error text, ຖ້າບໍ່ ແມ່ນໃຫ້ return ເປັນ null.
4. ສ້າງປຸ່ມເພື່ອ validate ແລະ submit form
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Done')),
);
}
},
child: const Text('Submit')),
ໃນນີ້ເຮົາຂຽນວ່າ ຖ້າ validate ຜ່ານ, app ຈະສະແດງ snackbar ທີ່ຂຽນວ່າ ‘Done’.
Code ທັງໝົດ:
class FormValidation extends StatefulWidget {
const FormValidation({super.key});
@override
State<FormValidation> createState() => _FormValidationState();
}
class _FormValidationState extends State<FormValidation> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter this field';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Done')),
);
}
},
child: const Text('Submit')),
],
));
}
}
ຜົນທີ່ໄດ້:
II. Buttons
Button ເປັນໜຶ່ງໃນ widget ທີ່ນິຍົມໃຊ້ຫຼາຍທີ່ສຸດ ແລະ ເປັນ widget ທີ່ທຸກໆ application ຕ້ອງມີ.
Flutter ມີ button ຢູ່ຫຼາຍປະເພດ ແຕ່ເຮົາຈະຂໍນຳສະເໜີ 5 ປະເພດຂອງ button ທີ່ຖືກໃຊ້ເປັນປະຈຳ ເຊັ່ນ:
- TextButton
- ElevatedButton
- OutlinedButton
- IconButton
- ToggleButtons
TextButton
ແມ່ນປຸ່ມທີ່ມີຕົວໜັງສືສະແດງເທິງ material widget ທຳມະດາທີ່ບໍ່ມີມິຕິ (zero-elevation), ຕາມ default ແລ້ວ ປຸ່ມປະເພດນີ້ຈະບໍ່ມີສີພື້ນຫຼັງ ແລະ ເສັ້ນຂອບ.
ຕົວຢ່າງການໃຊ້ TextButton
TextButton(
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
child: const Text('Simple button'),
)
- ເພີ່ມ
icon
ໃຫ້ກັບTextButton
ໂດຍໃຊ້TextButton.icon
TextButton.icon(
icon: const Icon(Icons.favorite, size: 18),
label: const Text('Add to favorite'),
// ປ່ຽນ foregroundColor (ສີຕົວໜັງສື ແລະ icon)
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
)
- ເຮັດໃຫ້ປຸ່ມບໍ່ສາມາດກົດໄດ້ (disabled button) ໂດຍກຳນົດ
onPressed
ເປັນ null
TextButton(
onPressed: null,
child: Text('Disabled button'),
);
ຜົນທີ່ໄດ້:
ElevatedButton
ແມ່ນປຸ່ມທີ່ມີມິຕິ (elevation). ຕາມ default ແລ້ວ ປຸ່ມປະເພດນີ້ຈະມີສີພື້ນຫຼັງ ແລະ ມີສີຂອບ.
ຕົວຢ່າງການໃຊ້ ElevatedButton
ElevatedButton(
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
child: const Text('Elevated button'))
- ເພີ່ມ
icon
ໃຫ້ກັບElevatedButton
ໂດຍໃຊ້ElevatedButton.icon
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.add, size: 18),
label: const Text('Add new list'))
- ເຮັດໃຫ້ປຸ່ມບໍ່ສາມາດກົດໄດ້ (disabled button) ໂດຍກຳນົດ
onPressed
ເປັນ null
ElevatedButton(
onPressed: null, child: Text('Disabled Elevated button'))
ຜົນທີ່ໄດ້:
OutlinedButton
ແມ່ນປຸ່ມທີ່ມີລັກສະນະຄືກັນກັບ
TextButton
. ໂດຍ default ແລ້ວOutlinedButton
ເປັນປຸ່ມທີ່ບໍ່ມີສີພື້ນຫຼັງ ແຕ່ມີເສັ້ນຂອບ.
ຕົວຢ່າງການໃຊ້ OutlinedButton
OutlinedButton(
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
// ປ່ຽນຂອບໃຫ້ເປັນສີຂຽວ ແລະ ມີຄວາມໜາ 2
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.green, width: 2)),
child: const Text('Outlined button'));
- ເພີ່ມ
icon
ໃຫ້ກັບOutlinedButton
ໂດຍໃຊ້OutlinedButton.icon
OutlinedButton.icon(
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
icon: const Icon(
Icons.delete,
size: 18
),
label: const Text(
'Delete',
style: TextStyle(fontSize: 18),
),
// ປ່ຽນ foregroundColor (ສີຕົວໜັງສຶ ແລະ icon) ແລະ backgroundColor (ສີພຶ້ນຫຼັງຂອງປຸ່ມ)
style: OutlinedButton.styleFrom(
backgroundColor: Colors.red, foregroundColor: Colors.white),
)
- ເຮັດໃຫ້ປຸ່ມບໍ່ສາມາດກົດໄດ້ (disabled button) ໂດຍກຳນົດ
onPressed
ເປັນ null
OutlinedButton.icon(
onPressed: null,
icon: const Icon(
Icons.restore,
size: 18,
),
label: const Text(
'Reset',
style: TextStyle(fontSize: 18),
),
// ປ່ຽນ backgroundColor (ສີພື້ນຫຼັງຂອງປຸ່ມ)
style: OutlinedButton.styleFrom(backgroundColor: Colors.teal),
)
ຜົນທີ່ໄດ້:
IconButton
ເປັນ widget ທີ່ຄ້າຍກັບ
TextButton
ແຕ່ປ່ຽນຈາກຕົວໜັງສືມາເປັນ icon.
ຕົວຢ່າງການໃຊ້ IconButton
IconButton(
iconSize: 50,
onPressed: () {
// ກຳນົດໃຫ້ເຮັດວຽກບາງຢ່າງເວລາປຸ່ມຖືກກົດ
},
icon: const Icon(Icons.alarm))
- ເຮັດໃຫ້ປຸ່ມບໍ່ສາມາດກົດໄດ້ (disabled button) ໂດຍກຳນົດ
onPressed
ເປັນ null
IconButton(iconSize: 50, onPressed: null, icon: Icon(Icons.alarm_off_sharp))
ຜົນທີ່ໄດ້:
ToggleButtons
ແມ່ນ widget ທີ່ເຮັດໃຫ້ເຮົາສາມາດສ້າງກຸ່ມຂອງປຸ່ມທີ່ສາມາດເລືອກໄດ້ຫຼາຍຕົວເລືອກໄດ້.
ToggleButtons ຈະສະແດງກຸ່ມຂອງປຸ່ມຕາມລວງທີ່ກຳນົດ (ລວງຕັ້ງ ຫຼື ລວງນອນ). State ຂອງແຕ່ລະປຸ່ມແມ່ນຖືກຄວບຄຸມໂດຍ isSelected
ເຊິ່ງເປັນ List ຂອງ boolean ທີ່ເປັນໂຕພິຈາລະນາວ່າ state ຂອງປຸ່ມປັດຈຸບັນແມ່ນກຳລັງຖືກເລືອກ ຫຼື ບໍ່.
ຕົວຢ່າງ: ຖ້າ boolean ໃນ index ທຳອິດຂອງ isSelected
ແມ່ນ true, ໝາຍເຖິງ widget ທຳອິດໃນ children ກຳລັງຖືກເລືອກຢູ່.
ຕົວຢ່າງການໃຊ້:
- ສ້າງ List ຂອງ boolean ທີ່ຊື່ວ່າ
isSelected
(ອາດຈະຕັ້ງຊື່ອື່ນກໍໄດ້)
List<bool> isSelected = [false, false, false];
2. ສ້າງ widget ToggleButtons
ແລະ ສ້າງ widget ພາຍໃນ children
ໃຫ້ພໍດີກັບຈຳນວນ boolean (length) ຂອງ isSelected
ToggleButtons(
// ກຳນົດໃຫ້ສະແດງ widget ໃນລວງຕັ້ງ
direction: Axis.vertical,
selectedBorderColor: Colors.purpleAccent,
// ກຳນົດ property isSelected ໃຫ້ເທົ່າກັບ list isSelected ທີ່ເຮົາສ້າງໄວ້
isSelected: isSelected,
onPressed: (index) {
// do something
},
children: const [
Icon(Icons.format_bold),
Icon(Icons.format_italic),
Icon(Icons.format_underline)
])
3. ໃນ onPressed()
ໃຫ້ຂຽນຄຳສັ່ງເພື່ອປ່ຽນຄ່າ boolean ຕຳແໜ່ງ index ຂອງ widget ທີ່ຖືກກົດ ໃຫ້ເປັນຄ່າທີ່ກົງກັນຂ້າມກັບປັດຈຸບັນ.
onPressed: (index) {
setState(() {
isSelected[index] = !isSelected[index];
});
},
ເມື່ອເອົາ code ມາປະກອບກັນໄດ້:
class ToggleButtonsWidget extends StatefulWidget {
const ToggleButtonsWidget({super.key});
@override
State<ToggleButtonsWidget> createState() => _ToggleButtonsWidgetState();
}
class _ToggleButtonsWidgetState extends State<ToggleButtonsWidget> {
List<bool> isSelected = [false, false, false];
@override
Widget build(BuildContext context) {
return Center(
child: ToggleButtons(
direction: Axis.vertical,
isSelected: isSelected,
onPressed: (index) {
setState(() {
isSelected[index] = !isSelected[index];
});
},
children: const [
Icon(Icons.format_bold),
Icon(Icons.format_italic),
Icon(Icons.format_underline)
]),
);
}
}
ຜົນທີ່ໄດ້:
III. Image
ເປັນ widget ທີ່ໃຊ້ໃນການສະແດງຮູບພາບ
ບົດຄວາມນີ້ຈະອະທິບາຍ constructor ຂອງ Image 5 ແບບທີ່ນິຍົມໃຊ້ສະແດງຮູບພາບ ເຊັ່ນ:
- Image.asset
- Image.network
- Image.file
- Image.memory
- Image
Image ສາມາດຮອງຮັບຮູບພາບໄດ້ຫຼາຍ format ເຊັ່ນ: JPEG, PNG, GIF, Animated GIF, WebP, Animated WebP, BMP, ແລະ WBMP
Image.asset
ໃຊ້ໃນການສະແດງຮູບພາບຈາກ assets, ເຊິ່ງເຮັດໃຫ້ການສະແດງຮູບພາບເຮັດໄດ້ໄວ ເນື່ອງຈາກເປັນການສະແດງຮູບພາບຈາກ local.
- ສ້າງ folder assets ໃນ root ຂອງ project
- ສ້າງ folder images ທາງໃນ folder assets (ອາດຈະຕັ້ງຊື່ເປັນ pictures, photos ຫຼື ຊື່ອື່ນກໍໄດ້)
- ເພີ່ມຮູບພາບເຂົ້າໄປໃນ folder images
4. ເພີ່ມ path assets/images/
ໄວ້ໃນ file ທີ່ຊື່ວ່າ pubspec.yaml ເພື່ອໃຫ້ສາມາດເຂົ້າເຖິງຮູບພາບທັງໝົດໃນ images ໄດ້
5. ສະແດງຮູບພາບໂດຍໃຊ້ Image.asset
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
'assets/images/comet.jpg',
),
),
],
)
ຜົນທີ່ໄດ້:
Image.network
ໃຊ້ໃນການສະແດງຮູບພາບຈາກ url ໂດຍຜູ້ຂຽນຈະຕ້ອງເພີ່ມ url ຂອງຮູບພາບໄວ້ໃນ
Image.network
.
ຕົວຢ່າງ:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.network( // ໃສ່ url ຂອງຮູບພາບ
'https://rb.gy/elmdc',
),
],
)
ຜົນທີ່ໄດ້:
Image.file
ໃຊ້ໃນການສະແດງຮູບພາບຈາກ File ຈາກ device ຂອງຜູ້ໃຊ້ງານ.
ໃນຕົວຢ່າງການໃຊ້ງານ Image.File
ເຮົາຈະໃຊ້ package ທີ່ຊື່ວ່າ file_picker
ເພື່ອໃຊ້ເລືອກຮູບພາບໃນ device ຂອງເຮົາ.
- ເພີ່ມ package
file_picker
ໂດຍໃຊ້ຄຳສັ່ງflutter pub add file_picker
- Import package ເຂົ້າມາໃຊ້
import 'package:file_picker/file_picker.dart';
3. ຂຽນຄຳສັ່ງເລືອກຮູບພາບຈາກ device
Future<void> pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
if (result.files.first.path != null) {
setState(() {
file = File(result.files.first.path!);
});
}
}
}
4. ສ້າງປຸ່ມເພື່ອໃຊ້ງານ method pickFile()
ແລະ ສະແດງຮູບພາບໂດຍໃຊ້ Image.File
class PickImage extends StatefulWidget {
const PickImage({super.key});
@override
State<PickImage> createState() => _PickImageState();
}
class _PickImageState extends State<PickImage> {
File? file;
Future<void> pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
if (result.files.first.path != null) {
setState(() {
file = File(result.files.first.path!);
});
}
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
ElevatedButton(
onPressed: () {
pickFile();
},
child: const Text(
"select image",
style: TextStyle(fontSize: 24),
)),
file == null
? const Text(
'No image',
style: TextStyle(fontSize: 24),
)
: Center(
child: Image.file(
file!,
height: 250,
width: 250,
))
],
),
);
}
}
Image.memory
ໃຊ້ໃນການສະແດງຮູບພາບທີ່ໄດ້ຈາກຂໍ້ມູນທີ່ຢູ່ໃນຮູບແບບ bytes.
ຕົວຢ່າງ:
- ເນື່ອງຈາກເຮົາບໍ່ມີຂໍ້ມູນທີ່ຢູ່ໃນຮູບແບບ bytes ເຮົາຈຶ່ງຈະມາ load ຮູບພາບມາຈາກ assets folder ກ່ອນ.
Future<ByteData> loadAsset() async {
return Future.delayed(const Duration(seconds: 3), () async {
return await rootBundle.load('assets/images/flutter.png');
});
}
2. ໃນຕົວຢ່າງນີ້, ເຮົາຈະມາໃຊ້ FutureBuilder
ໃນການສະແດງ widget ຈາກຂໍ້ມູນທີ່ເຮົາຈະໄດ້ຈາກ future ຫຼື ໝາຍເຖິງຂໍ້ມູນທີ່ຈະໄດ້ຈາກອະນາຄົດ.
return FutureBuilder(
future: loadAsset(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container();
} else {
return const Center(child: CircularProgressIndicator());
}
});
3. ກ່ອນທີ່ຈະສະແດງຮູບພາບໂດຍໃຊ້ Image.memory
ເຮົາຈະຕ້ອງແປງຂໍ້ມູນທີ່ໄດ້ມາ ໃຫ້ຢູ່ໃນຮູບແບບ Uint8List
ກ່ອນ ແລ້ວຈຶ່ງເອົາຂໍ້ມູນທີ່ແປງແລ້ວໄປສະແດງດ້ວຍ Image.memory
return FutureBuilder(
future: loadAsset(),
builder: (context, snapshot) {
if (snapshot.hasData) {
Uint8List bytes = snapshot.data!.buffer.asUint8List();
return Center(child: Image.memory(bytes));
} else {
return const Center(child: CircularProgressIndicator());
}
});
Code ທັງໝົດ:
class MemoryImageWidget extends StatelessWidget {
const MemoryImageWidget({super.key});
Future<ByteData> loadAsset() async {
return Future.delayed(const Duration(seconds: 3), () async {
return await rootBundle.load('assets/images/flutter.png');
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: loadAsset(),
builder: (context, snapshot) {
if (snapshot.hasData) {
Uint8List bytes = snapshot.data!.buffer.asUint8List();
return Center(child: Image.memory(bytes));
} else {
return const Center(child: CircularProgressIndicator());
}
});
}
}
ຜົນທີ່ໄດ້:
Image
ແມ່ນ default constructor ທີ່ໃຊ້ສະແດງຮູບພາບຈາກ
ImageProvider
.
ສົມມຸດວ່າ ຖ້າຢາກສະແດງຮູບພາບຈາກ network ເຮົາກໍສາມາດໃຊ້ Image
ແລະ ສະແດງຮູບພາບຈາກ ImageProvider
ປະເພດ NetworkImage
ແທນການສະແດງຮູບພາບ Image.network
ໄດ້ເຊັ່ນກັນ.
ນອກຈາກ NetworkImage
ແລ້ວ, Flutter ຍັງມີ ImageProvider
ປະເພດອື່ນໆອີກ ເຊັ່ນ: AssetImage
, FileImage
, ແລະ MemoryImage
- ຕົວຢ່າງການສະແດງຮູບພາບໂດຍໃຊ້
Image.network
Image.network('https://rb.gy/elmdc')
- ຕົວຢ່າງການສະແດງຮູບພາບໂດຍໃຊ້
ImageProvider
ປະເພດNetworkImage
Image(image: NetworkImage('https://rb.gy/elmdc'))
ນອກຈາກການນຳເອົາຮູບພາບມາສະແດງແລ້ວ, ເຮົາຍັງສາມາດປັບແຕ່ງຮູບພາບທີ່ຢູ່ໃນ Image ດ້ວຍ parameter ຕ່າງໆ ເຊັ່ນ:
width
: ກຳນົດຄວາມກວ້າງຮູບພາບ
height
: ກຳນົດຄວາມສູງຮູບພາບ
fit
: ກຳນົດວ່າຮູບພາບຄວນຖືກສະແດງແບບໃດໃນ container.
BoxFit.contain
: ເພີ່ມຂະໜາດຂອງຮູບພາບໃຫ້ໃຫຍ່ສຸດເທົ່າທີ່ຈະໃຫຍ່ໄດ້ ແລະ ກໍຕ້ອງຢູ່ພາຍໃນ container ແລະ ຮັກສາອັດຕາສ່ວນຂອງຮູບພາບໄວ້.BoxFit.cover
: ປັບຂະໜາດໃຫ້ຮູບພາບເຕັມ container ໂດຍຮັກສາອັດຕາສ່ວນໄວ້, ແຕ່ຖ້າສ່ວນໃດເກີນ container ກໍຈະຖືກຕັດອອກ.BoxFit.fill
: ຢືດຮູບພາບເພື່ອໃຫ້ພໍດີກັບ container ໂດຍອາດຈະມີການບິດເບືອນອັດຕາສ່ວນຂອງຮູບພາບນຳ.BoxFit.fitHeight
: ຢືດຮູບພາບໃຫ້ພໍດີກັບລວງສູງຂອງ container ເຖິງແມ່ນວ່າລວງນອນຈະເກີນ container ກໍຕາມ.BoxFit.fitWidth
: ຢືດຮູບພາບໃຫ້ພໍດີກັບລວງກວ້າງຂອງ container ເຖິງແມ່ນວ່າລວງສູງຈະເກີນ container ກໍຕາມ.BoxFit.none
: ຈັດຮູບພາບພາຍໃນ container (ຕາມ default ແມ່ນຈັດຢູ່ເຄິ່ງກາງ) ແລະ ຕັດຮູບພາບສ່ວນທີ່ເກີນອອກຈາກ container. ຮູບພາບຈະບໍ່ຖືກປ່ຽນຂະໜາດ.BoxFit.scaleDown
: ຫຍໍ້ຮູບພາບໃຫ້ນ້ອຍລົງເພື່ອໃຫ້ພໍດີກັບ container ແລະ ຮັກສາອັດຕາສ່ວນຂອງຮູບພາບໄວ້.
ຕົວຢ່າງ:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Container(
width: 300,
height: 350,
color: Colors.black,
child: Image.network(
'https://rb.gy/elmdc',
width: 150,
height: 200,
fit: BoxFit.contain,
),
),
),
],
);
ຜົນທີ່ໄດ້:
Conclusion
ຈົບໄປແລ້ວກັບບົດຄວາມ part ທີ 1 ປະເພດ widget ຂອງ Flutter ທີ່ຖືກໃຊ້ເປັນປະຈຳ ເຊິ່ງເຮົາໄດ້ເວົ້າເຖິງ widget ຢູ່ 3 ປະເພດໄດ້ແກ່: Text fields, Buttons ແລະ Image.
ໃນ part ທີ 2 ເຮົາຈະມາເວົ້າເຖິງ widget ອີກ 2 ປະເພດກໍຄື Navigation widget ແລະ Layout widget, ຖ້າໃຜຢາກອ່ານຕໍ່ກໍສາມາດ click ໄດ້ໃນ link ທາງລຸ່ມນີ້ເລີຍ.
Comet ຫວັງວ່າບົດຄວາມຂອງເຮົາຈະມີປະໂຫຍດ ແລະ ຊ່ວຍໃຫ້ທຸກຄົນສາມາດເຂົ້າໃຈ ແລະ ນຳໃຊ້ບັນດາ widget ໃນ Flutter ໄດ້ງ່າຍຂຶ້ນ.
ສາມາດຕິດຕາມຂ່າວສານອື່ນໆທີ່ໜ້າສົນໃຈຈາກ Comet ໄດ້ທີ່:
Facebook: https://www.facebook.com/CometDigitalAgency/
Instagram: https://www.instagram.com/cometdigitalagency/?hl=en