ຮວບຮວມ Widgets ຂອງ Flutter ທີ່ຖືກໃຊ້ເປັນປະຈຳ (Part 1)

Comet Digital Agency
9 min readApr 7, 2024

--

ສະບາຍດີ! ໃນບົດຄວາມນີ້ 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: ເປັນການກຳນົດການເຮັດຕົວໜັງສືເປັນຕົວພິມໃຫຍ່. ຕົວຢ່າງ: ເຮັດໃຫ້ຕົວພິມໃຫຍ່ສະເພາະຕົວທຳອິດຂອງປະໂຫຍກ ຫຼື ຕົວທຳອິດຂອງຄຳ.
TextFormField

ການປັບແຕ່ງ 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)),
),
)
TextField with decoration
  • prefixIcon: ກຳນົດ icon ທີ່ສະແດງກ່ອນບ່ອນ input ຂອງ TextField
  • labelText: ຕົວໜັງສືທີ່ສະແດງໃນບ່ອນຂໍ້ມູນ, ໃນເວລາທີ່ 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”.

  1. ສ້າງ 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.

ຜົນທີ່ໄດ້:

Retrieving value from text field

ການເຮັດ validation ໃນ TextFormField

Validation ແມ່ນການກວດສອບວ່າຜູ້ໃຊ້ໄດ້ປ້ອນຂໍ້ມູນຄົບຖ້ວນບໍ່ ຫຼື ຂໍ້ມູນທີ່ຜູ້ໃຊ້ປ້ອນມານັ້ນຖືກຕ້ອງຕາມທີ່ກຳນົດໄວ້ບໍ່.

  1. ສ້າງ 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')),
],
));
}
}

ຜົນທີ່ໄດ້:

TextFormField with validation

II. Buttons

Button ເປັນໜຶ່ງໃນ widget ທີ່ນິຍົມໃຊ້ຫຼາຍທີ່ສຸດ ແລະ ເປັນ widget ທີ່ທຸກໆ application ຕ້ອງມີ.

Flutter ມີ button ຢູ່ຫຼາຍປະເພດ ແຕ່ເຮົາຈະຂໍນຳສະເໜີ 5 ປະເພດຂອງ button ທີ່ຖືກໃຊ້ເປັນປະຈຳ ເຊັ່ນ:

  1. TextButton
  2. ElevatedButton
  3. OutlinedButton
  4. IconButton
  5. 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'),
);

ຜົນທີ່ໄດ້:

Example of TextButton

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'))

ຜົນທີ່ໄດ້:

Example of ElevatedButton

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

ຜົນທີ່ໄດ້:

Example of OutlinedButton

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

ຜົນທີ່ໄດ້:

Example of IconButton

ToggleButtons

ແມ່ນ widget ທີ່ເຮັດໃຫ້ເຮົາສາມາດສ້າງກຸ່ມຂອງປຸ່ມທີ່ສາມາດເລືອກໄດ້ຫຼາຍຕົວເລືອກໄດ້.

ToggleButtons ຈະສະແດງກຸ່ມຂອງປຸ່ມຕາມລວງທີ່ກຳນົດ (ລວງຕັ້ງ ຫຼື ລວງນອນ). State ຂອງແຕ່ລະປຸ່ມແມ່ນຖືກຄວບຄຸມໂດຍ isSelected ເຊິ່ງເປັນ List ຂອງ boolean ທີ່ເປັນໂຕພິຈາລະນາວ່າ state ຂອງປຸ່ມປັດຈຸບັນແມ່ນກຳລັງຖືກເລືອກ ຫຼື ບໍ່.

ຕົວຢ່າງ: ຖ້າ boolean ໃນ index ທຳອິດຂອງ isSelected ແມ່ນ true, ໝາຍເຖິງ widget ທຳອິດໃນ children ກຳລັງຖືກເລືອກຢູ່.

ຕົວຢ່າງການໃຊ້:

  1. ສ້າງ 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)
]),
);
}
}

ຜົນທີ່ໄດ້:

Example of ToggleButtons

III. Image

ເປັນ widget ທີ່ໃຊ້ໃນການສະແດງຮູບພາບ

ບົດຄວາມນີ້ຈະອະທິບາຍ constructor ຂອງ Image 5 ແບບທີ່ນິຍົມໃຊ້ສະແດງຮູບພາບ ເຊັ່ນ:

  1. Image.asset
  2. Image.network
  3. Image.file
  4. Image.memory
  5. Image

Image ສາມາດຮອງຮັບຮູບພາບໄດ້ຫຼາຍ format ເຊັ່ນ: JPEG, PNG, GIF, Animated GIF, WebP, Animated WebP, BMP, ແລະ WBMP

Image.asset

ໃຊ້ໃນການສະແດງຮູບພາບຈາກ assets, ເຊິ່ງເຮັດໃຫ້ການສະແດງຮູບພາບເຮັດໄດ້ໄວ ເນື່ອງຈາກເປັນການສະແດງຮູບພາບຈາກ local.

  1. ສ້າງ folder assets ໃນ root ຂອງ project
  2. ສ້າງ folder images ທາງໃນ folder assets (ອາດຈະຕັ້ງຊື່ເປັນ pictures, photos ຫຼື ຊື່ອື່ນກໍໄດ້)
  3. ເພີ່ມຮູບພາບເຂົ້າໄປໃນ 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',
),
),
],
)

ຜົນທີ່ໄດ້:

Example of Image.asset

Image.network

ໃຊ້ໃນການສະແດງຮູບພາບຈາກ url ໂດຍຜູ້ຂຽນຈະຕ້ອງເພີ່ມ url ຂອງຮູບພາບໄວ້ໃນ Image.network.

ຕົວຢ່າງ:

Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.network( // ໃສ່ url ຂອງຮູບພາບ
'https://rb.gy/elmdc',
),
],
)

ຜົນທີ່ໄດ້:

Example of Image.network

Image.file

ໃຊ້ໃນການສະແດງຮູບພາບຈາກ File ຈາກ device ຂອງຜູ້ໃຊ້ງານ.

ໃນຕົວຢ່າງການໃຊ້ງານ Image.File ເຮົາຈະໃຊ້ package ທີ່ຊື່ວ່າ file_picker ເພື່ອໃຊ້ເລືອກຮູບພາບໃນ device ຂອງເຮົາ.

  1. ເພີ່ມ package file_picker ໂດຍໃຊ້ຄຳສັ່ງ flutter pub add file_picker
  2. 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,
))
],
),
);
}
}
Example of Image.file

Image.memory

ໃຊ້ໃນການສະແດງຮູບພາບທີ່ໄດ້ຈາກຂໍ້ມູນທີ່ຢູ່ໃນຮູບແບບ bytes.

ຕົວຢ່າງ:

  1. ເນື່ອງຈາກເຮົາບໍ່ມີຂໍ້ມູນທີ່ຢູ່ໃນຮູບແບບ 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());
}
});
}
}

ຜົນທີ່ໄດ້:

Example of Image.memory

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,
),
),
),
],
);

ຜົນທີ່ໄດ້:

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

--

--

Comet Digital Agency
Comet Digital Agency

Written by Comet Digital Agency

Welcome to Comet sharing space :) enjoy our pool of knowledge. We are a mobile app development agency in Laos with a focus on user experience and creativity.

No responses yet