<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Blog Học lập trình Online]]></title><description><![CDATA[Blog học lập trình Online tại laptrinh-online.vn chia sẻ kiến thức lập trình Web và Mobile, từ Java core, Java Web đến Android, Flutter, React Native.]]></description><link>https://laptrinh-online.vn/blog/</link><image><url>https://laptrinh-online.vn/blog/favicon.png</url><title>Blog Học lập trình Online</title><link>https://laptrinh-online.vn/blog/</link></image><generator>Ghost 5.29</generator><lastBuildDate>Sun, 19 Apr 2026 17:06:01 GMT</lastBuildDate><atom:link href="https://laptrinh-online.vn/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Hướng dẫn Xuất Project Flutter, Chạy App & Đồng Bộ GitHub]]></title><description><![CDATA[Bài viết hướng dẫn cách xuất project Flutter từ Firebase Studio, chạy ứng dụng trên web hoặc Android, và đồng bộ mã nguồn qua GitHub để làm việc với Android Studio. ]]></description><link>https://laptrinh-online.vn/blog/huong-dan-xuat-project-flutter-chay-app-dong-bo-github/</link><guid isPermaLink="false">6839699a14958c001e7ac001</guid><category><![CDATA[Flutter]]></category><category><![CDATA[xuất project Flutter]]></category><category><![CDATA[chạy app Flutter]]></category><category><![CDATA[Firebase Studio]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Fri, 30 May 2025 08:32:44 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/maxresdefault-848x548.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/maxresdefault-848x548.jpg" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub"><p><strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">Flutter</a></strong> hi&#x1EC7;n l&#xE0; m&#x1ED9;t trong nh&#x1EEF;ng framework ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t &#x111;&#x1EC3; ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng, &#x111;&#x1B0;&#x1EE3;c Google h&#x1ED7; tr&#x1EE3; v&#xE0; c&#x1ED9;ng &#x111;&#x1ED3;ng s&#x1EED; d&#x1EE5;ng r&#x1ED9;ng r&#xE3;i. Tuy nhi&#xEA;n, vi&#x1EC7;c b&#x1EAF;t &#x111;&#x1EA7;u m&#x1ED9;t project Flutter t&#x1EEB; &#x111;&#x1EA7;u &#x111;&#xF4;i khi m&#x1EA5;t kh&#xE1; nhi&#x1EC1;u th&#x1EDD;i gian, &#x111;&#x1EB7;c bi&#x1EC7;t n&#x1EBF;u b&#x1EA1;n ch&#x1B0;a c&#xF3; UI/UX c&#x1EE5; th&#x1EC3; ho&#x1EB7;c logic chi ti&#x1EBF;t. Firebase Studio &#x2013; m&#x1ED9;t c&#xF4;ng c&#x1EE5; AI h&#x1ED7; tr&#x1EE3; t&#x1EA1;o prototype v&#xE0; sinh m&#xE3; Flutter &#x2013; &#x111;ang m&#x1EDF; ra h&#x1B0;&#x1EDB;ng &#x111;i m&#x1EDB;i cho l&#x1EAD;p tr&#xEC;nh vi&#xEA;n hi&#x1EC7;n &#x111;&#x1EA1;i.</p><p>B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n b&#x1EA1;n chi ti&#x1EBF;t c&#xE1;ch:</p><ul><li>Xu&#x1EA5;t m&#xE3; ngu&#x1ED3;n Flutter t&#x1EEB; Firebase Studio.</li><li>Ch&#x1EA1;y &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n tr&#xEC;nh duy&#x1EC7;t web ho&#x1EB7;c thi&#x1EBF;t b&#x1ECB; Android.</li><li>&#x110;&#x1ED3;ng b&#x1ED9; code gi&#x1EEF;a Firebase Studio v&#xE0; Android Studio qua GitHub.</li><li>C&#xF9;ng v&#x1EDB;i &#x111;&#xF3; l&#xE0; ph&#xE2;n t&#xED;ch &#x1B0;u &#x2013; nh&#x1B0;&#x1EE3;c &#x111;i&#x1EC3;m khi s&#x1EED; d&#x1EE5;ng Firebase Studio &#x111;&#x1EC3; sinh code app Flutter.</li></ul><h2 id="1-xu%E1%BA%A5t-m%C3%A3-ngu%E1%BB%93n-flutter-t%E1%BB%AB-firebase-studio">1. Xu&#x1EA5;t m&#xE3; ngu&#x1ED3;n Flutter t&#x1EEB; Firebase Studio</h2><h3 id="b%C6%B0%E1%BB%9Bc-1-ch%E1%BB%8Dn-d%E1%BB%B1-%C3%A1n-%C4%91%C3%A3-t%E1%BA%A1o">B&#x1B0;&#x1EDB;c 1: Ch&#x1ECD;n d&#x1EF1; &#xE1;n &#x111;&#xE3; t&#x1EA1;o</h3><p>Sau khi prototype ho&#xE0;n t&#x1EA5;t, b&#x1EA1;n s&#x1EBD; th&#x1EA5;y l&#x1EF1;a ch&#x1ECD;n &quot;Export to Flutter&quot; trong trang qu&#x1EA3;n l&#xFD; d&#x1EF1; &#xE1;n. &#x110;&#xE2;y l&#xE0; b&#x1B0;&#x1EDB;c kh&#x1EDF;i &#x111;&#x1EA7;u &#x111;&#x1EC3; chuy&#x1EC3;n giao di&#x1EC7;n m&#xF4; ph&#x1ECF;ng th&#xE0;nh m&#xE3; ngu&#x1ED3;n <strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">Flutter</a></strong> &#x111;&#x1EA7;y &#x111;&#x1EE7;, g&#x1ED3;m c&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c, logic v&#xE0; giao di&#x1EC7;n.</p><h3 id="b%C6%B0%E1%BB%9Bc-2-export-project-flutter">B&#x1B0;&#x1EDB;c 2: Export Project Flutter</h3><p>Firebase Studio s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng &#x111;&#xF3;ng g&#xF3;i m&#xE3; ngu&#x1ED3;n th&#xE0;nh m&#x1ED9;t file <code>.zip</code> ch&#x1EE9;a &#x111;&#x1EA7;y &#x111;&#x1EE7; c&#x1EA5;u tr&#xFA;c chu&#x1EA9;n:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-12.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="290" height="292"></figure><p>Sau khi t&#x1EA3;i v&#x1EC1;:</p><ul><li>Gi&#x1EA3;i n&#xE9;n th&#x1B0; m&#x1EE5;c</li><li>M&#x1EDF; b&#x1EB1;ng Android Studio ho&#x1EB7;c VS Code &#x111;&#xE3; c&#xE0;i plugin Flutter</li><li>B&#x1EA1;n c&#xF3; th&#x1EC3; ch&#x1EA1;y tr&#x1EF1;c ti&#x1EBF;p b&#x1EB1;ng l&#x1EC7;nh terminal: </li></ul><p><em>flutter pub get<br>flutter run</em></p><h2 id="2-ch%E1%BA%A1y-%E1%BB%A9ng-d%E1%BB%A5ng-flutter-tr%C3%AAn-n%E1%BB%81n-web">2. Ch&#x1EA1;y &#x1EE9;ng d&#x1EE5;ng Flutter tr&#xEA;n n&#x1EC1;n web</h2><p>M&#x1ED9;t trong nh&#x1EEF;ng &#x1B0;u &#x111;i&#x1EC3;m c&#x1EE7;a <a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban"><strong>Flutter</strong></a> l&#xE0; h&#x1ED7; tr&#x1EE3; build &#x1EE9;ng d&#x1EE5;ng web m&#xE0; kh&#xF4;ng c&#x1EA7;n s&#x1EED;a &#x111;&#x1ED5;i nhi&#x1EC1;u.</p><h3 id="b%C6%B0%E1%BB%9Bc-1-ch%E1%BA%A1y-tr%E1%BB%B1c-ti%E1%BA%BFp-tr%C3%AAn-firebase-studio">B&#x1B0;&#x1EDB;c 1: Ch&#x1EA1;y tr&#x1EF1;c ti&#x1EBF;p tr&#xEA;n Firebase Studio</h3><p>Sau khi export, Firebase Studio cung c&#x1EA5;p tu&#x1EF3; ch&#x1ECD;n <strong>&quot;Run Web App&quot;</strong>. Nh&#x1EA5;n v&#xE0;o &#x111;&#xE2;y &#x111;&#x1EC3; kh&#x1EDF;i &#x111;&#x1ED9;ng b&#x1EA3;n build Flutter tr&#xEA;n tr&#xEC;nh duy&#x1EC7;t. &#x110;&#xE2;y l&#xE0; phi&#xEA;n b&#x1EA3;n m&#xE3; th&#x1EAD;t, kh&#xF4;ng c&#xF2;n l&#xE0; prototype ReactJS.</p><h3 id="b%C6%B0%E1%BB%9Bc-2-so-s%C3%A1nh-v%E1%BB%9Bi-prototype">B&#x1B0;&#x1EDB;c 2: So s&#xE1;nh v&#x1EDB;i prototype</h3><p>Kh&#xE1;c bi&#x1EC7;t &#x111;&#xE1;ng ch&#xFA; &#xFD;:</p><!--kg-card-begin: html--><table data-start="2896" data-end="3461" class="w-fit min-w-(--thread-content-width)"><thead data-start="2896" data-end="2987"><tr data-start="2896" data-end="2987"><th data-start="2896" data-end="2921" data-col-size="sm">&#x110;&#x1EB7;c &#x111;i&#x1EC3;m</th><th data-start="2921" data-end="2953" data-col-size="sm">Prototype ReactJS</th><th data-start="2953" data-end="2987" data-col-size="sm">&#x1EE8;ng d&#x1EE5;ng Flutter th&#x1EF1;c t&#x1EBF;</th></tr></thead><tbody data-start="3081" data-end="3461"><tr data-start="3081" data-end="3172"><td data-start="3081" data-end="3106" data-col-size="sm">Ng&#xF4;n ng&#x1EEF;</td><td data-start="3106" data-end="3138" data-col-size="sm">JavaScript (React)</td><td data-start="3138" data-end="3172" data-col-size="sm">Dart (Flutter)</td></tr><tr data-start="3173" data-end="3269"><td data-start="3173" data-end="3198" data-col-size="sm">Logic x&#x1EED; l&#xFD;</td><td data-start="3198" data-end="3230" data-col-size="sm">M&#xF4; ph&#x1ECF;ng b&#x1EB1;ng UI</td><td data-start="3230" data-end="3269" data-col-size="sm">C&#xF3; ch&#x1EE9;c n&#x103;ng th&#x1EAD;t, thao t&#xE1;c d&#x1EEF; li&#x1EC7;u</td></tr><tr data-start="3270" data-end="3368"><td data-start="3270" data-end="3295" data-col-size="sm">T&#x1ED1;c &#x111;&#x1ED9; ph&#x1EA3;n h&#x1ED3;i</td><td data-start="3295" data-end="3327" data-col-size="sm">R&#x1EA5;t nhanh</td><td data-start="3327" data-end="3368" data-col-size="sm">T&#xF9;y thu&#x1ED9;c c&#x1EA5;u h&#xEC;nh m&#xE1;y v&#xE0; tr&#xEC;nh duy&#x1EC7;t</td></tr><tr data-start="3369" data-end="3461"><td data-start="3369" data-end="3394" data-col-size="sm">&#x110;&#x1ED9; tu&#x1EF3; bi&#x1EBF;n</td><td data-start="3394" data-end="3427" data-col-size="sm">H&#x1EA1;n ch&#x1EBF;</td><td data-start="3427" data-end="3461" data-col-size="sm">To&#xE0;n quy&#x1EC1;n ch&#x1EC9;nh s&#x1EED;a widget</td></tr></tbody></table><!--kg-card-end: html--><h3 id="ki%E1%BB%83m-tra-t%C3%ADnh-n%C4%83ng-crud">Ki&#x1EC3;m tra t&#xED;nh n&#x103;ng CRUD</h3><p>Trong v&#xED; d&#x1EE5; app Ghi Ch&#xFA; Th&#xF4;ng Minh, b&#x1EA1;n c&#xF3; th&#x1EC3; ki&#x1EC3;m tra:</p><p><strong>Th&#xEA;m ghi ch&#xFA;</strong>:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-13.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="630" height="316"></figure><p><strong>Xo&#xE1; ghi ch&#xFA;</strong>:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-14.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="417" height="187"></figure><p><strong>&#x110;&#xE1;nh d&#x1EA5;u ho&#xE0;n th&#xE0;nh</strong>:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-15.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="487" height="264"></figure><p>T&#x1EA5;t c&#x1EA3; logic x&#x1EED; l&#xFD; CRUD &#x111;&#x1EC1;u &#x111;&#x1B0;&#x1EE3;c sinh t&#x1EF1; &#x111;&#x1ED9;ng khi export t&#x1EEB; Firebase Studio.</p><h2 id="3-%C4%91%E1%BB%93ng-b%E1%BB%99-m%C3%A3-ngu%E1%BB%93n-flutter-qua-github-%C4%91%E1%BB%83-ch%E1%BA%A1y-tr%C3%AAn-android">3. &#x110;&#x1ED3;ng b&#x1ED9; m&#xE3; ngu&#x1ED3;n Flutter qua GitHub &#x111;&#x1EC3; ch&#x1EA1;y tr&#xEA;n Android</h2><p>&#x110;&#x1EC3; ch&#x1EA1;y &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n Android, b&#x1EA1;n c&#x1EA7;n l&#xE0;m vi&#x1EC7;c v&#x1EDB;i m&#xE3; ngu&#x1ED3;n <strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">Flutter</a></strong> th&#x1EF1;c t&#x1EBF;. Firebase Studio h&#x1ED7; tr&#x1EE3; &#x111;&#x1EA9;y m&#xE3; tr&#x1EF1;c ti&#x1EBF;p l&#xEA;n GitHub, sau &#x111;&#xF3; clone v&#x1EC1; Android Studio &#x111;&#x1EC3; build.</p><h3 id="b%C6%B0%E1%BB%9Bc-1-k%E1%BA%BFt-n%E1%BB%91i-firebase-studio-v%E1%BB%9Bi-github">B&#x1B0;&#x1EDB;c 1: K&#x1EBF;t n&#x1ED1;i Firebase Studio v&#x1EDB;i GitHub</h3><ul><li>V&#xE0;o <strong>Settings</strong> trong Firebase Studio.</li><li>Ch&#x1ECD;n <strong>GitHub Integration</strong>.</li><li>Cho ph&#xE9;p quy&#x1EC1;n truy c&#x1EAD;p repo c&#xE1; nh&#xE2;n.</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-2-push-m%C3%A3-ngu%E1%BB%93n-flutter-l%C3%AAn-github">B&#x1B0;&#x1EDB;c 2: Push m&#xE3; ngu&#x1ED3;n Flutter l&#xEA;n GitHub</h3><p>Sau khi k&#x1EBF;t n&#x1ED1;i:</p><ul><li>Trong project, ch&#x1ECD;n <strong>Push to GitHub</strong></li><li>Nh&#x1EAD;p commit message</li><li>Ch&#x1ECD;n repository &#x111;&#xED;ch</li><li>Nh&#x1EA5;n &quot;Push&quot;</li></ul><p>L&#xFA;c n&#xE0;y m&#xE3; Flutter &#x111;&#xE3; s&#x1EB5;n s&#xE0;ng tr&#xEA;n GitHub.</p><h3 id="b%C6%B0%E1%BB%9Bc-3-clone-v%C3%A0-ch%E1%BA%A1y-b%E1%BA%B1ng-android-studio">B&#x1B0;&#x1EDB;c 3: Clone v&#xE0; ch&#x1EA1;y b&#x1EB1;ng Android Studio</h3><p>Tr&#xEA;n m&#xE1;y c&#xE1; nh&#xE2;n:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-16.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="621" height="59"></figure><ul><li>M&#x1EDF; Android Studio &#x2192; File &#x2192; Open &#x2192; tr&#x1ECF; &#x111;&#x1EBF;n th&#x1B0; m&#x1EE5;c v&#x1EEB;a clone</li><li>Android Studio s&#x1EBD; nh&#x1EAD;n di&#x1EC7;n &#x111;&#xE2;y l&#xE0; project Flutter</li></ul><p>Ch&#x1EA1;y l&#x1EC7;nh:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-17.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub" loading="lazy" width="424" height="97"></figure><ul><li>Ch&#x1ECD;n thi&#x1EBF;t b&#x1ECB; th&#x1EAD;t ho&#x1EB7;c emulator Android &#x111;&#x1EC3; test</li></ul><p>C&#xF3; th&#x1EC3; th&#x1EA5;y Firebase Studio mang &#x111;&#x1EBF;n tr&#x1EA3;i nghi&#x1EC7;m t&#x1EA1;o &#x1EE9;ng d&#x1EE5;ng Flutter ho&#xE0;n to&#xE0;n m&#x1EDB;i &#x2013; nhanh ch&#xF3;ng, tr&#x1EF1;c quan v&#xE0; t&#xED;ch h&#x1EE3;p AI sinh m&#xE3;. D&#xF9; v&#x1EAB;n c&#xF2;n m&#x1ED9;t s&#x1ED1; h&#x1EA1;n ch&#x1EBF; v&#x1EC1; &#x111;&#x1ED9; ph&#x1EE9;c t&#x1EA1;p v&#xE0; hi&#x1EC7;u n&#x103;ng emulator, nh&#x1B0;ng v&#x1EDB;i c&#xE1;c project c&#x1A1; b&#x1EA3;n v&#xE0; trung b&#xEC;nh, c&#xF4;ng c&#x1EE5; n&#xE0;y th&#x1EF1;c s&#x1EF1; l&#xE0; m&#x1ED9;t gi&#x1EA3;i ph&#xE1;p t&#x103;ng t&#x1ED1;c ph&#xE1;t tri&#x1EC3;n ph&#x1EA7;n m&#x1EC1;m hi&#x1EC7;u qu&#x1EA3;.</p><p>K&#x1EBF;t h&#x1EE3;p v&#x1EDB;i GitHub v&#xE0; Android Studio, b&#x1EA1;n c&#xF3; th&#x1EC3; x&#xE2;y d&#x1EF1;ng quy tr&#xEC;nh CI/CD cho app <strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">Flutter</a></strong> m&#x1ED9;t c&#xE1;ch chuy&#xEA;n nghi&#x1EC7;p h&#x1A1;n.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/UZJnabBCT64?start=1&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="T&#x1EA1;o Flutter Todo App v&#x1EDB;i Firebase Studio &#x2013; Ph&#x1EA7;n 2: Xu&#x1EA5;t Project Flutter, Ch&#x1EA1;y App &amp; &#x110;&#x1ED3;ng B&#x1ED9; GitHub"></iframe></figure><p>N&#x1ED9;i dung b&#xE0;i vi&#x1EBF;t &#x111;&#x1B0;&#x1EE3;c chia s&#x1EBB; b&#x1EDF;i Th&#x1EA7;y Duy &#x2013; Th&#x1EA1;c s&#x129; C&#xF4;ng ngh&#x1EC7; Th&#xF4;ng tin t&#x1EA1;i &#x110;&#x1EA1;i h&#x1ECD;c B&#xE1;ch Khoa H&#xE0; N&#x1ED9;i, ng&#x1B0;&#x1EDD;i c&#xF3; nhi&#x1EC1;u n&#x103;m kinh nghi&#x1EC7;m trong gi&#x1EA3;ng d&#x1EA1;y v&#xE0; nghi&#xEA;n c&#x1EE9;u l&#x1EAD;p tr&#xEC;nh. N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n s&#xE2;u v&#x1EC1; ph&#xE1;t tri&#x1EC3;n web, &#x1EE9;ng d&#x1EE5;ng Flutter ho&#x1EB7;c c&#xE1;ch t&#x1EAD;n d&#x1EE5;ng AI &#x111;&#x1EC3; h&#x1ED7; tr&#x1EE3; l&#x1EAD;p tr&#xEC;nh, &#x111;&#x1EEB;ng b&#x1ECF; l&#x1EE1; c&#xE1;c k&#xEA;nh chia s&#x1EBB; h&#x1ECD;c li&#x1EC7;u t&#x1EEB; Th&#x1EA7;y. B&#x1EA1;n c&#xF3; th&#x1EC3; c&#x1EAD;p nh&#x1EAD;t nh&#x1EEF;ng video h&#x1B0;&#x1EDB;ng d&#x1EAB;n v&#xE0; t&#xE0;i nguy&#xEA;n h&#x1ECD;c t&#x1EAD;p m&#x1EDB;i nh&#x1EA5;t qua:</p><ul><li><em>K&#xEA;nh YouTube: <a href="https://www.youtube.com/@LeHongDuyCNTT">https://www.youtube.com/@LeHongDuyCNTT</a></em></li><li><em>GitHub c&#xE1; nh&#xE2;n: <a href="https://github.com/DuyLeHong">https://github.com/DuyLeHong</a></em></li></ul><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: 0813188668 , 0332026803 (Zalo / Call)</p>]]></content:encoded></item><item><title><![CDATA[Thực hành code Web Portfolio với HTML5, CSS3, Bootstrap 5 và ChatGPT]]></title><description><![CDATA[Bài viết này hướng dẫn bạn tạo một website portfolio cá nhân đơn giản, hiện đại và responsive bằng HTML5, CSS3 và Bootstrap 5. Điều đặc biệt: bạn sẽ đồng hành cùng ChatGPT để tối ưu thời gian viết mã. ]]></description><link>https://laptrinh-online.vn/blog/thuc-hanh-code-web-portfolio-oi-html5-css3-bootstrap-5-va-chatgpt/</link><guid isPermaLink="false">6830a9ec14958c001e7abf81</guid><category><![CDATA[Lập trình web]]></category><category><![CDATA[HTML5, CSS3, Bootstrap 5]]></category><category><![CDATA[ChatGPT]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Fri, 23 May 2025 17:33:24 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/maxresdefault--2-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/maxresdefault--2-.jpg" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT"><p>B&#xE0;i vi&#x1EBF;t n&#xE0;y h&#x1B0;&#x1EDB;ng d&#x1EAB;n b&#x1EA1;n t&#x1EA1;o m&#x1ED9;t website portfolio c&#xE1; nh&#xE2;n &#x111;&#x1A1;n gi&#x1EA3;n, hi&#x1EC7;n &#x111;&#x1EA1;i v&#xE0; responsive b&#x1EB1;ng <strong><a href="https://codenhanh.vn/thiet-ke-web-voi-html5-css3-ai-chatgpt-copilot">HTML5, CSS3 v&#xE0; Bootstrap 5</a></strong>. &#x110;i&#x1EC1;u &#x111;&#x1EB7;c bi&#x1EC7;t: b&#x1EA1;n s&#x1EBD; &#x111;&#x1ED3;ng h&#xE0;nh c&#xF9;ng ChatGPT &#x111;&#x1EC3; t&#x1ED1;i &#x1B0;u th&#x1EDD;i gian vi&#x1EBF;t m&#xE3;. M&#x1ED7;i b&#x1B0;&#x1EDB;c &#x111;&#x1EC1;u c&#xF3; ph&#x1EA7;n h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#x1EE5; th&#x1EC3;, prompt m&#x1EAB;u cho ChatGPT, &#x111;o&#x1EA1;n m&#xE3; minh h&#x1ECD;a v&#xE0; ph&#xE2;n t&#xED;ch t&#x1EEB;ng d&#xF2;ng &#x111;&#x1EC3; ng&#x1B0;&#x1EDD;i h&#x1ECD;c hi&#x1EC3;u r&#xF5; kh&#xF4;ng ch&#x1EC9; <em>c&#xE1;ch l&#xE0;m</em>, m&#xE0; c&#xF2;n <em>v&#xEC; sao ph&#x1EA3;i l&#xE0;m nh&#x1B0; v&#x1EAD;y</em>.</p><h2 id="ki%E1%BA%BFn-th%E1%BB%A9c-n%E1%BB%81n-t%E1%BA%A3ng-%E2%80%93-c%C3%B4ng-c%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng">Ki&#x1EBF;n th&#x1EE9;c n&#x1EC1;n t&#x1EA3;ng &#x2013; C&#xF4;ng c&#x1EE5; s&#x1EED; d&#x1EE5;ng</h2><ul><li><strong>HTML5</strong>: Ng&#xF4;n ng&#x1EEF; &#x111;&#xE1;nh d&#x1EA5;u d&#xF9;ng &#x111;&#x1EC3; t&#x1EA1;o c&#x1EA5;u tr&#xFA;c trang web. C&#xE1;c th&#x1EBB; nh&#x1B0; <code>section</code>, <code>header</code>, <code>nav</code>, <code>footer</code> gi&#xFA;p n&#x1ED9;i dung r&#xF5; r&#xE0;ng, d&#x1EC5; &#x111;&#x1ECB;nh v&#x1ECB; v&#xE0; th&#xE2;n thi&#x1EC7;n SEO.</li><li><strong>CSS3</strong>: Ng&#xF4;n ng&#x1EEF; &#x111;&#x1ECB;nh ki&#x1EC3;u cho HTML. Cho ph&#xE9;p b&#x1EA1;n &#x111;&#x1ECB;nh ngh&#x129;a m&#xE0;u s&#x1EAF;c, kho&#x1EA3;ng c&#xE1;ch, b&#x1ED1; c&#x1EE5;c&#x2026; m&#x1ED9;t c&#xE1;ch linh ho&#x1EA1;t, s&#x1EED; d&#x1EE5;ng k&#x1EF9; thu&#x1EAD;t Flexbox, Grid &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng layout hi&#x1EC7;n &#x111;&#x1EA1;i.</li><li><strong>Bootstrap 5</strong>: Framework CSS ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t hi&#x1EC7;n nay, cung c&#x1EA5;p s&#x1EB5;n h&#x1EC7; th&#x1ED1;ng l&#x1B0;&#x1EDB;i v&#xE0; h&#xE0;ng tr&#x103;m class ti&#x1EC7;n &#xED;ch &#x111;&#x1EC3; t&#x1EA1;o layout responsive nhanh ch&#xF3;ng m&#xE0; kh&#xF4;ng c&#x1EA7;n vi&#x1EBF;t CSS t&#x1EEB; &#x111;&#x1EA7;u.</li><li><strong>ChatGPT</strong>: Tr&#x1EE3; l&#xFD; AI gi&#xFA;p b&#x1EA1;n sinh code m&#x1EAB;u, gi&#x1EA3;i th&#xED;ch &#x111;o&#x1EA1;n m&#xE3; v&#xE0; &#x111;&#x1EC1; xu&#x1EA5;t c&#x1EA3;i ti&#x1EBF;n. N&#x1EBF;u bi&#x1EBF;t &#x111;&#x1EB7;t c&#xE2;u h&#x1ECF;i &#x111;&#xFA;ng (prompt), b&#x1EA1;n c&#xF3; th&#x1EC3; ti&#x1EBF;t ki&#x1EC7;m 50-70% th&#x1EDD;i gian code.</li></ul><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/z6632891244902_093b7dd9187a1bc9f4452671f09201e9.jpg" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="750" height="422"></figure><h2 id="c%C3%A1c-b%C6%B0%E1%BB%9Bc-th%E1%BB%B1c-h%C3%A0nh-%E2%80%93-x%C3%A2y-d%E1%BB%B1ng-web-portfolio">C&#xE1;c b&#x1B0;&#x1EDB;c th&#x1EF1;c h&#xE0;nh &#x2013; X&#xE2;y d&#x1EF1;ng Web Portfolio</h2><h3 id="b%C6%B0%E1%BB%9Bc-1-kh%E1%BB%9Fi-t%E1%BA%A1o-d%E1%BB%B1-%C3%A1n-v%C3%A0-c%E1%BA%A5u-tr%C3%BAc-file-c%C6%A1-b%E1%BA%A3n">B&#x1B0;&#x1EDB;c 1: Kh&#x1EDF;i t&#x1EA1;o d&#x1EF1; &#xE1;n v&#xE0; c&#x1EA5;u tr&#xFA;c file c&#x1A1; b&#x1EA3;n</h3><p><strong>M&#x1EE5;c ti&#xEA;u:</strong> T&#x1EA1;o c&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c chu&#x1EA9;n v&#xE0; file <strong><a href="https://codenhanh.vn/thiet-ke-web-voi-html5-css3-ai-chatgpt-copilot">HTML5</a></strong> c&#x1A1; b&#x1EA3;n.</p><p><strong>Prompt m&#x1EAB;u cho ChatGPT:</strong></p><p><em>T&#xF4;i mu&#x1ED1;n b&#x1EAF;t &#x111;&#x1EA7;u d&#x1EF1; &#xE1;n portfolio v&#x1EDB;i HTML5. H&#xE3;y gi&#xFA;p t&#xF4;i t&#x1EA1;o m&#x1ED9;t file index.html c&#xF3; c&#x1EA5;u tr&#xFA;c c&#x1A1; b&#x1EA3;n, bao g&#x1ED3;m th&#x1EBB; head &#x111;&#x1EA7;y &#x111;&#x1EE7; v&#xE0; k&#x1EBF;t n&#x1ED1;i v&#x1EDB;i file style.css.</em></p><p><strong>Code m&#x1EAB;u:</strong></p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-7.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="923" height="402"></figure><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><ul><li><code>&lt;!DOCTYPE html&gt;</code>: Khai b&#xE1;o chu&#x1EA9;n HTML5.</li><li><code>meta viewport</code>: Gi&#xFA;p giao di&#x1EC7;n responsive tr&#xEA;n thi&#x1EBF;t b&#x1ECB; di &#x111;&#x1ED9;ng.</li><li><code>link style.css</code>: Li&#xEA;n k&#x1EBF;t file &#x111;&#x1ECB;nh d&#x1EA1;ng ri&#xEA;ng.</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-2-t%C3%ADch-h%E1%BB%A3p-bootstrap-v%C3%A0-google-fonts">B&#x1B0;&#x1EDB;c 2: T&#xED;ch h&#x1EE3;p Bootstrap v&#xE0; Google Fonts</h3><p><strong>M&#x1EE5;c ti&#xEA;u:</strong> Gi&#xFA;p giao di&#x1EC7;n hi&#x1EC7;n &#x111;&#x1EA1;i, responsive v&#xE0; c&#xF3; font &#x111;&#x1EB9;p.</p><p><strong>Prompt m&#x1EAB;u:</strong></p><p><em>H&#xE3;y gi&#xFA;p t&#xF4;i th&#xEA;m Google Fonts &apos;Poppins&apos; v&#xE0; t&#xED;ch h&#x1EE3;p Bootstrap 5 qua CDN v&#xE0;o file HTML.</em></p><p><strong>Code m&#x1EAB;u:</strong></p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-8.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="929" height="200"></figure><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><ul><li>Google Fonts gi&#xFA;p font ch&#x1EEF; m&#x1B0;&#x1EE3;t m&#xE0;, th&#x1EA9;m m&#x1EF9; h&#x1A1;n.</li><li>Bootstrap 5 gi&#xFA;p b&#x1EA1;n t&#x1EA1;o layout v&#xE0; c&#xE1;c th&#xE0;nh ph&#x1EA7;n UI nhanh, chu&#x1EA9;n responsive.</li></ul><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/hFHIguyA4ko?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="TH&#x1EF0;C H&#xC0;NH CODE WEB PORTFOLIO v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT | Mr. Quang &#x2013; Mentor CodeNhanh"></iframe><figcaption>Th&#x1EF1;c h&#xE0;nh t&#x1EA1;o <strong>WEB PORTFOLIO v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT</strong></figcaption></figure><h3 id="b%C6%B0%E1%BB%9Bc-3-t%E1%BA%A1o-thanh-%C4%91i%E1%BB%81u-h%C6%B0%E1%BB%9Bng-navbar">B&#x1B0;&#x1EDB;c 3: T&#x1EA1;o thanh &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng (Navbar)</h3><p><strong>M&#x1EE5;c ti&#xEA;u:</strong> T&#x1EA1;o thanh menu c&#x1ED1; &#x111;&#x1ECB;nh tr&#xEA;n &#x111;&#x1EA7;u trang, ph&#x1EA3;n h&#x1ED3;i t&#x1ED1;t v&#x1EDB;i c&#xE1;c thi&#x1EBF;t b&#x1ECB; kh&#xE1;c nhau.</p><p><strong>Prompt m&#x1EAB;u:</strong></p><p><em>H&#xE3;y t&#x1EA1;o m&#x1ED9;t navbar Bootstrap c&#xF3; logo v&#xE0; 4 li&#xEA;n k&#x1EBF;t: Trang ch&#x1EE7;, Gi&#x1EDB;i thi&#x1EC7;u, D&#x1EF1; &#xE1;n, Li&#xEA;n h&#x1EC7;. Khi thu nh&#x1ECF; tr&#xEC;nh duy&#x1EC7;t, menu s&#x1EBD; chuy&#x1EC3;n sang bi&#x1EC3;u t&#x1B0;&#x1EE3;ng hamburger.</em></p><p><strong>Code m&#x1EAB;u:</strong></p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-9.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="921" height="507"></figure><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><ul><li><code>navbar-expand-lg</code>: Navbar co gi&#xE3;n theo &#x111;&#x1ED9; r&#x1ED9;ng thi&#x1EBF;t b&#x1ECB;.</li><li><code>ms-auto</code>: C&#x103;n ph&#x1EA3;i menu.</li><li><code>collapse</code> v&#xE0; <code>navbar-toggler</code>: Gi&#xFA;p &#x1EA9;n/hi&#x1EC7;n menu tr&#xEA;n mobile.</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-4-d%E1%BB%B1ng-ph%E1%BA%A7n-hero-section-v%E1%BB%9Bi-chatgpt">B&#x1B0;&#x1EDB;c 4: D&#x1EF1;ng ph&#x1EA7;n Hero Section v&#x1EDB;i ChatGPT</h3><p><strong>M&#x1EE5;c ti&#xEA;u:</strong> Hi&#x1EC3;n th&#x1ECB; l&#x1EDD;i ch&#xE0;o + n&#xFA;t CTA &#x201C;Xem d&#x1EF1; &#xE1;n&#x201D; v&#x1EDB;i thi&#x1EBF;t k&#x1EBF; hi&#x1EC7;n &#x111;&#x1EA1;i.</p><p><strong>Prompt m&#x1EAB;u:</strong></p><p><em>T&#x1EA1;o m&#x1ED9;t Hero Section b&#x1EB1;ng Bootstrap 5 v&#x1EDB;i chi&#x1EC1;u cao 100vh, c&#x103;n gi&#x1EEF;a n&#x1ED9;i dung v&#xE0; n&#xFA;t &quot;Xem d&#x1EF1; &#xE1;n&quot;.</em></p><p><strong>Code m&#x1EAB;u:</strong></p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-10.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="921" height="230"></figure><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><ul><li><code>vh-100</code>: Chi&#x1EC1;u cao 100% khung h&#xEC;nh.</li><li><code>d-flex</code>, <code>align-items-center</code>, <code>justify-content-center</code>: C&#x103;n gi&#x1EEF;a n&#x1ED9;i dung.</li><li><code>text-center</code>: Canh gi&#x1EEF;a ch&#x1EEF;.</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-5-t%E1%BB%91i-%C6%B0u-form-li%C3%AAn-h%E1%BB%87-v%C3%A0-ki%E1%BB%83m-tra-responsive">B&#x1B0;&#x1EDB;c 5: T&#x1ED1;i &#x1B0;u form li&#xEA;n h&#x1EC7; v&#xE0; ki&#x1EC3;m tra responsive</h3><p><strong>Prompt m&#x1EAB;u:</strong></p><p><em>T&#x1EA1;o m&#x1ED9;t form li&#xEA;n h&#x1EC7; &#x111;&#x1A1;n gi&#x1EA3;n b&#x1EB1;ng Bootstrap, g&#x1ED3;m: H&#x1ECD; t&#xEA;n, Email, N&#x1ED9;i dung v&#xE0; n&#xFA;t G&#x1EED;i.</em></p><p><strong>Code m&#x1EAB;u:</strong></p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-11.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh code Web Portfolio v&#x1EDB;i HTML5, CSS3, Bootstrap 5 v&#xE0; ChatGPT" loading="lazy" width="923" height="546"></figure><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><ul><li>D&#xF9;ng class <code>form-control</code>, <code>form-label</code>, <code>btn</code> t&#x1EEB; Bootstrap &#x111;&#x1EC3; &#x111;&#x1EA3;m b&#x1EA3;o t&#xED;nh th&#x1EA9;m m&#x1EF9; v&#xE0; responsive.</li><li>Vi&#x1EC7;c s&#x1EED; d&#x1EE5;ng ChatGPT trong t&#x1EEB;ng b&#x1B0;&#x1EDB;c kh&#xF4;ng thay th&#x1EBF; ho&#xE0;n to&#xE0;n k&#x1EF9; n&#x103;ng l&#x1EAD;p tr&#xEC;nh, nh&#x1B0;ng l&#xE0; c&#xF4;ng c&#x1EE5; <strong>h&#x1ED7; tr&#x1EE3; c&#x1EF1;c m&#x1EA1;nh &#x111;&#x1EC3; ti&#x1EBF;t ki&#x1EC7;m th&#x1EDD;i gian</strong>.</li><li>B&#x1EA1;n c&#xF3; th&#x1EC3; m&#x1EDF; r&#x1ED9;ng giao di&#x1EC7;n th&#xEA;m ph&#x1EA7;n d&#x1EF1; &#xE1;n d&#x1EA1;ng card, hi&#x1EC7;u &#x1EE9;ng cu&#x1ED9;n, ho&#x1EB7;c t&#xED;ch h&#x1EE3;p AOS.js &#x111;&#x1EC3; c&#xF3; animation.</li><li>Quan tr&#x1ECD;ng nh&#x1EA5;t: <strong>hi&#x1EC3;u r&#xF5; c&#x1EA5;u tr&#xFA;c HTML + c&#xE1;ch Bootstrap ho&#x1EA1;t &#x111;&#x1ED9;ng</strong>, kh&#xF4;ng copy m&#xE3; m&#xE0; kh&#xF4;ng hi&#x1EC3;u.</li></ul><p>Nh&#x1B0; v&#x1EAD;y, vi&#x1EC7;c s&#x1EED; d&#x1EE5;ng ChatGPT trong t&#x1EEB;ng b&#x1B0;&#x1EDB;c kh&#xF4;ng thay th&#x1EBF; ho&#xE0;n to&#xE0;n k&#x1EF9; n&#x103;ng l&#x1EAD;p tr&#xEC;nh, nh&#x1B0;ng l&#xE0; c&#xF4;ng c&#x1EE5; <strong>h&#x1ED7; tr&#x1EE3; c&#x1EF1;c m&#x1EA1;nh &#x111;&#x1EC3; ti&#x1EBF;t ki&#x1EC7;m th&#x1EDD;i gian</strong>. B&#x1EA1;n c&#xF3; th&#x1EC3; m&#x1EDF; r&#x1ED9;ng giao di&#x1EC7;n th&#xEA;m ph&#x1EA7;n d&#x1EF1; &#xE1;n d&#x1EA1;ng card, hi&#x1EC7;u &#x1EE9;ng cu&#x1ED9;n, ho&#x1EB7;c t&#xED;ch h&#x1EE3;p AOS.js &#x111;&#x1EC3; c&#xF3; animation. Quan tr&#x1ECD;ng nh&#x1EA5;t: <strong>hi&#x1EC3;u r&#xF5; <a href="https://codenhanh.vn/thiet-ke-web-voi-html5-css3-ai-chatgpt-copilot">c&#x1EA5;u tr&#xFA;c HTML</a> + c&#xE1;ch Bootstrap ho&#x1EA1;t &#x111;&#x1ED9;ng</strong>, kh&#xF4;ng copy m&#xE3; m&#xE0; kh&#xF4;ng hi&#x1EC3;u.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/_Ynt9YJc1d4?start=5&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="TH&#x1EEC; TH&#xC1;CH CODE WEB NHANH x 3 L&#x1EA6;N v&#x1EDB;i AI: L&#xE0;m Trang PORTFOLIO v&#x1EDB;i HTML5, CSS3, Boostrap 5 v&#xE0; ChatGPT"></iframe><figcaption>H&#x1B0;&#x1EDB;ng d&#x1EAB;n t&#x1EA1;o trang Hero Section - D&#x1EF1; &#xE1;n PORTFOLIO C&#xE1; Nh&#xE2;n v&#x1EDB;i HTML5, CSS3, Boostrap 5 v&#xE0; ChatGPT</figcaption></figure><p>N&#x1ED9;i dung tr&#xEA;n &#x111;&#x1B0;&#x1EE3;c bi&#xEA;n so&#x1EA1;n b&#x1EDF;i Th&#x1EA7;y Duy &#x2013; Th&#x1EA1;c s&#x129; CNTT, &#x110;&#x1EA1;i h&#x1ECD;c B&#xE1;ch Khoa, H&#xE0; N&#x1ED9;i. N&#x1EBF;u c&#xE1;c b&#x1EA1;n mu&#x1ED1;n bi&#x1EBF;t th&#xEA;m c&#xE1;c ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; l&#x1EAD;p tr&#xEC;nh web, &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a AI trong l&#x1EAD;p tr&#xEC;nh. &#x110;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i Th&#x1EA7;y qua c&#xE1;c k&#xEA;nh &#x111;&#x1EC3; nh&#x1EAD;n t&#xE0;i li&#x1EC7;u h&#x1ECD;c t&#x1EAD;p - h&#x1EEF;u &#xED;ch cho con &#x111;&#x1B0;&#x1EDD;ng ph&#xE1;t tri&#x1EC3;n ki&#x1EBF;n th&#x1EE9;c l&#x1EAD;p tr&#xEC;nh c&#x1EE7;a b&#x1EA1;n:</p><ul><li><em>K&#xEA;nh YouTube: <a href="https://www.youtube.com/@LeHongDuyCNTT">https://www.youtube.com/@LeHongDuyCNTT</a></em></li><li><em>GitHub c&#xE1; nh&#xE2;n: <a href="https://github.com/DuyLeHong">https://github.com/DuyLeHong</a></em></li></ul><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: 0813188668 , 0332026803 (Zalo / Call)</p>]]></content:encoded></item><item><title><![CDATA[Hướng dẫn sử dụng Xcode để lập trình app iOS]]></title><description><![CDATA[Trong bài viết này sẽ hướng dẫn bạn từng bước làm quen với Xcode – từ cài đặt, tạo project đầu tiên, khám phá cấu trúc thư mục cho đến viết mã và chạy thử ứng dụng iOS trên trình giả lập.]]></description><link>https://laptrinh-online.vn/blog/huong-dan-su-dung-xcode-de-lap-trinh-app-ios/</link><guid isPermaLink="false">68289daa14958c001e7abf2b</guid><category><![CDATA[Lập trình IOS]]></category><category><![CDATA[IOS]]></category><category><![CDATA[XCode]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Sat, 17 May 2025 14:43:32 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/Cai-Dat-Xcode-MacOS-3.png" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/Cai-Dat-Xcode-MacOS-3.png" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS"><p>Xcode l&#xE0; m&#x1ED9;t trong nh&#x1EEF;ng c&#xF4;ng c&#x1EE5; quan tr&#x1ECD;ng v&#xE0; b&#x1EAF;t bu&#x1ED9;c &#x111;&#x1ED1;i v&#x1EDB;i b&#x1EA5;t k&#x1EF3; ai mu&#x1ED1;n ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n h&#x1EC7; sinh th&#xE1;i Apple. B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n b&#x1EA1;n t&#x1EEB;ng b&#x1B0;&#x1EDB;c &#x111;&#x1EC3; l&#xE0;m quen v&#x1EDB;i Xcode &#x2013; t&#x1EEB; c&#xE0;i &#x111;&#x1EB7;t, t&#x1EA1;o project m&#x1EDB;i, &#x111;&#x1EBF;n vi&#x1EC7;c hi&#x1EC3;u c&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c, vi&#x1EBF;t m&#xE3; v&#xE0; ch&#x1EA1;y th&#x1EED; <strong><a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">&#x1EE9;ng d&#x1EE5;ng iOS</a></strong> &#x111;&#x1EA7;u ti&#xEA;n.</p><h2 id="gi%E1%BB%9Bi-thi%E1%BB%87u-v%E1%BB%81-xcode">Gi&#x1EDB;i thi&#x1EC7;u v&#x1EC1; Xcode</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-1.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS" loading="lazy" width="650" height="366"></figure><p>Xcode l&#xE0; m&#x1ED9;t m&#xF4;i tr&#x1B0;&#x1EDD;ng ph&#xE1;t tri&#x1EC3;n t&#xED;ch h&#x1EE3;p (IDE - Integrated Development Environment) &#x111;&#x1B0;&#x1EE3;c ph&#xE1;t tri&#x1EC3;n b&#x1EDF;i Apple. &#x110;&#xE2;y l&#xE0; c&#xF4;ng c&#x1EE5; ch&#xED;nh th&#x1EE9;c d&#xF9;ng &#x111;&#x1EC3; vi&#x1EBF;t &#x1EE9;ng d&#x1EE5;ng cho c&#xE1;c n&#x1EC1;n t&#x1EA3;ng nh&#x1B0; iOS, macOS, watchOS v&#xE0; tvOS. Xcode h&#x1ED7; tr&#x1EE3; c&#x1EA3; Swift v&#xE0; Objective-C, &#x111;&#x1ED3;ng th&#x1EDD;i t&#xED;ch h&#x1EE3;p nhi&#x1EC1;u c&#xF4;ng c&#x1EE5; m&#x1EA1;nh m&#x1EBD; nh&#x1B0; tr&#xEC;nh gi&#x1EA3; l&#x1EAD;p (Simulator), tr&#xEC;nh g&#x1EE1; l&#x1ED7;i (Debugger), v&#xE0; giao di&#x1EC7;n thi&#x1EBF;t k&#x1EBF; tr&#x1EF1;c quan (Interface Builder).</p><h2 id="nh%E1%BB%AFng-t%C3%ADnh-n%C4%83ng-ch%C3%ADnh-c%E1%BB%A7a-xcode">Nh&#x1EEF;ng t&#xED;nh n&#x103;ng ch&#xED;nh c&#x1EE7;a Xcode</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS" loading="lazy" width="825" height="515"></figure><p>Xcode kh&#xF4;ng ch&#x1EC9; &#x111;&#x1A1;n thu&#x1EA7;n l&#xE0; tr&#xEC;nh so&#x1EA1;n th&#x1EA3;o m&#xE3; ngu&#x1ED3;n. D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; c&#xE1;c th&#xE0;nh ph&#x1EA7;n ch&#xED;nh t&#x1EA1;o n&#xEA;n s&#x1EE9;c m&#x1EA1;nh c&#x1EE7;a c&#xF4;ng c&#x1EE5; n&#xE0;y:</p><ul><li><strong>Xcode Editor</strong>: Tr&#xEC;nh bi&#xEA;n t&#x1EAD;p m&#xE3; v&#x1EDB;i t&#xED;nh n&#x103;ng t&#x1EF1; &#x111;&#x1ED9;ng ho&#xE0;n thi&#x1EC7;n, ki&#x1EC3;m tra c&#xFA; ph&#xE1;p v&#xE0; &#x111;&#x1ECB;nh d&#x1EA1;ng m&#xE3; ngu&#x1ED3;n.</li><li><strong>Interface Builder</strong>: Giao di&#x1EC7;n k&#xE9;o-th&#x1EA3; gi&#xFA;p l&#x1EAD;p tr&#xEC;nh vi&#xEA;n x&#xE2;y d&#x1EF1;ng UI m&#xE0; kh&#xF4;ng c&#x1EA7;n vi&#x1EBF;t qu&#xE1; nhi&#x1EC1;u m&#xE3;.</li><li><strong>Simulator</strong>: Cho ph&#xE9;p ch&#x1EA1;y th&#x1EED; &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n nhi&#x1EC1;u lo&#x1EA1;i thi&#x1EBF;t b&#x1ECB; &#x1EA3;o v&#x1EDB;i c&#xE1;c phi&#xEA;n b&#x1EA3;n iOS kh&#xE1;c nhau.</li><li><strong>Debugger v&#xE0; c&#xF4;ng c&#x1EE5; ph&#xE2;n t&#xED;ch hi&#x1EC7;u su&#x1EA5;t</strong>: H&#x1ED7; tr&#x1EE3; ph&#xE1;t hi&#x1EC7;n l&#x1ED7;i logic, theo d&#xF5;i b&#x1ED9; nh&#x1EDB; v&#xE0; t&#x1ED1;i &#x1B0;u h&#xF3;a t&#x1ED1;c &#x111;&#x1ED9; x&#x1EED; l&#xFD;.</li><li><strong>Test Automation</strong>: T&#xED;ch h&#x1EE3;p s&#x1EB5;n c&#xE1;c c&#xF4;ng c&#x1EE5; vi&#x1EBF;t v&#xE0; ch&#x1EA1;y test, gi&#xFA;p &#x111;&#x1EA3;m b&#x1EA3;o ch&#x1EA5;t l&#x1B0;&#x1EE3;ng &#x1EE9;ng d&#x1EE5;ng.</li><li><strong>T&#xED;ch h&#x1EE3;p v&#x1EDB;i Apple Developer Account</strong>: H&#x1ED7; tr&#x1EE3; c&#x1EA5;u h&#xEC;nh, k&#xFD; &#x1EE9;ng d&#x1EE5;ng v&#xE0; g&#x1EED;i app l&#xEA;n App Store nhanh ch&#xF3;ng.</li></ul><h2 id="c%C3%A1ch-c%C3%A0i-%C4%91%E1%BA%B7t-xcode-tr%C3%AAn-m%C3%A1y-mac">C&#xE1;ch c&#xE0;i &#x111;&#x1EB7;t Xcode tr&#xEA;n m&#xE1;y Mac</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-2.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS" loading="lazy" width="690" height="405"></figure><p>&#x110;&#x1EC3; b&#x1EAF;t &#x111;&#x1EA7;u, b&#x1EA1;n c&#x1EA7;n &#x111;&#x1EA3;m b&#x1EA3;o m&#xE1;y Mac &#x111;ang s&#x1EED; d&#x1EE5;ng phi&#xEA;n b&#x1EA3;n macOS t&#x1B0;&#x1A1;ng th&#xED;ch v&#x1EDB;i phi&#xEA;n b&#x1EA3;n Xcode m&#x1EDB;i nh&#x1EA5;t. D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; c&#xE1;c b&#x1B0;&#x1EDB;c c&#x1EE5; th&#x1EC3;:</p><ul><li><strong>B&#x1B0;&#x1EDB;c 1</strong>: Ki&#x1EC3;m tra phi&#xEA;n b&#x1EA3;n h&#x1EC7; &#x111;i&#x1EC1;u h&#xE0;nh<br>Truy c&#x1EAD;p Apple Menu &gt; About This Mac &#x111;&#x1EC3; x&#xE1;c minh phi&#xEA;n b&#x1EA3;n macOS.</li><li><strong>B&#x1B0;&#x1EDB;c 2</strong>: T&#x1EA3;i Xcode t&#x1EEB; App Store<br>M&#x1EDF; App Store, t&#xEC;m ki&#x1EBF;m &#x201C;Xcode&#x201D; v&#xE0; nh&#x1EA5;n T&#x1EA3;i xu&#x1ED1;ng. Dung l&#x1B0;&#x1EE3;ng c&#xF3; th&#x1EC3; l&#xEA;n &#x111;&#x1EBF;n h&#x1A1;n 10GB, v&#xEC; v&#x1EAD;y b&#x1EA1;n n&#xEA;n &#x111;&#x1EA3;m b&#x1EA3;o c&#xF3; &#x111;&#x1EE7; b&#x1ED9; nh&#x1EDB; tr&#x1ED1;ng.</li><li><strong>B&#x1B0;&#x1EDB;c 3</strong>: C&#xE0;i &#x111;&#x1EB7;t Xcode<br>Sau khi t&#x1EA3;i xong, Xcode s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng c&#xE0;i &#x111;&#x1EB7;t v&#xE0;o th&#x1B0; m&#x1EE5;c Applications. Khi m&#x1EDF; l&#x1EA7;n &#x111;&#x1EA7;u, Xcode c&#xF3; th&#x1EC3; y&#xEA;u c&#x1EA7;u b&#x1EA1;n c&#xE0;i th&#xEA;m c&#xF4;ng c&#x1EE5; d&#xF2;ng l&#x1EC7;nh (Command Line Tools).</li><li><strong>B&#x1B0;&#x1EDB;c 4</strong>: &#x110;&#x103;ng nh&#x1EAD;p t&#xE0;i kho&#x1EA3;n Apple Developer<br>B&#x1EA1;n c&#xF3; th&#x1EC3; s&#x1EED; d&#x1EE5;ng t&#xE0;i kho&#x1EA3;n Apple ID th&#xF4;ng th&#x1B0;&#x1EDD;ng &#x111;&#x1EC3; ch&#x1EA1;y &#x1EE9;ng d&#x1EE5;ng th&#x1EED; nghi&#x1EC7;m. N&#x1EBF;u mu&#x1ED1;n xu&#x1EA5;t b&#x1EA3;n l&#xEA;n App Store, c&#x1EA7;n &#x111;&#x103;ng k&#xFD; t&#xE0;i kho&#x1EA3;n Apple Developer.</li></ul><h2 id="t%E1%BA%A1o-project-%C4%91%E1%BA%A7u-ti%C3%AAn-trong-xcode">T&#x1EA1;o project &#x111;&#x1EA7;u ti&#xEA;n trong Xcode</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-5.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS" loading="lazy" width="770" height="404"></figure><p>Sau khi c&#xE0;i &#x111;&#x1EB7;t, b&#x1EA1;n c&#xF3; th&#x1EC3; b&#x1EAF;t &#x111;&#x1EA7;u vi&#x1EBF;t &#x1EE9;ng d&#x1EE5;ng &#x111;&#x1EA7;u ti&#xEA;n nh&#x1B0; sau:</p><ul><li>M&#x1EDF; Xcode v&#xE0; ch&#x1ECD;n &#x201C;Create a new Xcode project&#x201D;.</li><li>Ch&#x1ECD;n template ph&#xF9; h&#x1EE3;p, v&#xED; d&#x1EE5;: App (thu&#x1ED9;c nh&#xF3;m iOS).</li><li>&#x110;&#x1EB7;t t&#xEA;n cho project, ch&#x1ECD;n ng&#xF4;n ng&#x1EEF; Swift, v&#xE0; interface SwiftUI ho&#x1EB7;c UIKit t&#xF9;y &#xFD;.</li><li>Ch&#x1ECD;n n&#x1A1;i l&#x1B0;u tr&#x1EEF; project tr&#xEA;n m&#xE1;y v&#xE0; ho&#xE0;n t&#x1EA5;t vi&#x1EC7;c kh&#x1EDF;i t&#x1EA1;o.</li></ul><h2 id="c%E1%BA%A5u-tr%C3%BAc-th%C6%B0-m%E1%BB%A5c-c%E1%BB%A7a-m%E1%BB%99t-project-ios">C&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c c&#x1EE7;a m&#x1ED9;t project iOS</h2><p>M&#x1ED9;t project iOS &#x111;i&#x1EC3;n h&#xEC;nh bao g&#x1ED3;m c&#xE1;c th&#xE0;nh ph&#x1EA7;n sau:</p><ul><li><strong>AppDelegate.swift</strong>: Qu&#x1EA3;n l&#xFD; v&#xF2;ng &#x111;&#x1EDD;i &#x1EE9;ng d&#x1EE5;ng.</li><li><strong>SceneDelegate.swift</strong> (n&#x1EBF;u c&#xF3;): Qu&#x1EA3;n l&#xFD; c&#xE1;c scene trong &#x1EE9;ng d&#x1EE5;ng (&#x111;&#x1EB7;c bi&#x1EC7;t v&#x1EDB;i iOS 13 tr&#x1EDF; &#x111;i).</li><li><strong>ViewController.swift</strong>: T&#x1EAD;p tin x&#x1EED; l&#xFD; logic hi&#x1EC3;n th&#x1ECB; c&#x1EE7;a m&#xE0;n h&#xEC;nh ch&#xED;nh.</li><li><strong>Main.storyboard</strong> ho&#x1EB7;c <strong>.xib / SwiftUI View</strong>: Giao di&#x1EC7;n ng&#x1B0;&#x1EDD;i d&#xF9;ng.</li><li><strong>Assets.xcassets</strong>: L&#x1B0;u tr&#x1EEF; h&#xEC;nh &#x1EA3;nh, bi&#x1EC3;u t&#x1B0;&#x1EE3;ng &#x1EE9;ng d&#x1EE5;ng.</li><li><strong>Info.plist</strong>: C&#x1EA5;u h&#xEC;nh quy&#x1EC1;n truy c&#x1EAD;p, th&#xF4;ng tin &#x1EE9;ng d&#x1EE5;ng.</li></ul><p>Vi&#x1EC7;c hi&#x1EC3;u r&#xF5; t&#x1EEB;ng ph&#x1EA7;n trong c&#x1EA5;u tr&#xFA;c s&#x1EBD; gi&#xFA;p b&#x1EA1;n d&#x1EC5; d&#xE0;ng &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng v&#xE0; qu&#x1EA3;n l&#xFD; m&#xE3; ngu&#x1ED3;n khi d&#x1EF1; &#xE1;n ph&#xE1;t tri&#x1EC3;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n.</p><h2 id="gi%E1%BB%9Bi-thi%E1%BB%87u-c%C3%A1c-khu-v%E1%BB%B1c-ch%C3%ADnh-trong-giao-di%E1%BB%87n-xcode">Gi&#x1EDB;i thi&#x1EC7;u c&#xE1;c khu v&#x1EF1;c ch&#xED;nh trong giao di&#x1EC7;n Xcode</h2><p>Khi m&#x1EDF; m&#x1ED9;t project, giao di&#x1EC7;n Xcode &#x111;&#x1B0;&#x1EE3;c chia th&#xE0;nh nhi&#x1EC1;u khu v&#x1EF1;c:</p><ul><li><strong>Navigator Area</strong> (b&#xEA;n tr&#xE1;i): Qu&#x1EA3;n l&#xFD; file, c&#x1EA5;u tr&#xFA;c project.</li><li><strong>Editor Area</strong> (gi&#x1EEF;a m&#xE0;n h&#xEC;nh): N&#x1A1;i vi&#x1EBF;t m&#xE3; ngu&#x1ED3;n ho&#x1EB7;c thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n.</li><li><strong>Utilities Area</strong> (b&#xEA;n ph&#x1EA3;i): Ch&#x1EC9;nh s&#x1EED;a thu&#x1ED9;c t&#xED;nh, g&#xE1;n action cho n&#xFA;t, v.v.</li><li><strong>Toolbar v&#xE0; Debug Area</strong> (d&#x1B0;&#x1EDB;i c&#xF9;ng): Ch&#x1EA1;y, d&#x1EEB;ng &#x1EE9;ng d&#x1EE5;ng v&#xE0; theo d&#xF5;i bi&#x1EBF;n trong qu&#xE1; tr&#xEC;nh debug.</li></ul><p>Vi&#x1EC7;c n&#x1EAF;m r&#xF5; c&#xE1;ch s&#x1EED; d&#x1EE5;ng t&#x1EEB;ng khu v&#x1EF1;c s&#x1EBD; gi&#xFA;p b&#x1EA1;n ti&#x1EBF;t ki&#x1EC7;m th&#x1EDD;i gian thao t&#xE1;c v&#xE0; c&#x1EA3;i thi&#x1EC7;n hi&#x1EC7;u qu&#x1EA3; l&#x1EAD;p tr&#xEC;nh.</p><h2 id="m%E1%BB%99t-s%E1%BB%91-ph%C3%ADm-t%E1%BA%AFt-h%E1%BB%AFu-%C3%ADch-trong-xcode">M&#x1ED9;t s&#x1ED1; ph&#xED;m t&#x1EAF;t h&#x1EEF;u &#xED;ch trong Xcode</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/image-6.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n s&#x1EED; d&#x1EE5;ng Xcode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app iOS" loading="lazy" width="1200" height="675"></figure><p>L&#x1EAD;p tr&#xEC;nh hi&#x1EC7;u qu&#x1EA3; h&#x1A1;n nh&#x1EDD; v&#xE0;o vi&#x1EC7;c s&#x1EED; d&#x1EE5;ng c&#xE1;c ph&#xED;m t&#x1EAF;t sau:</p><ul><li><strong>Command + R</strong>: Ch&#x1EA1;y &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n simulator.</li><li><strong>Command + B</strong>: Bi&#xEA;n d&#x1ECB;ch project.</li><li><strong>Command + /</strong>: B&#x1EAD;t/t&#x1EAF;t comment cho &#x111;o&#x1EA1;n m&#xE3;.</li><li><strong>Command + Shift + O</strong>: T&#xEC;m ki&#x1EBF;m nhanh file, class ho&#x1EB7;c function.</li><li><strong>Command + Option + Enter</strong>: M&#x1EDF; ch&#x1EBF; &#x111;&#x1ED9; giao di&#x1EC7;n chia &#x111;&#xF4;i (interface v&#xE0; code song song).</li><li><strong>Command + 0</strong>: Hi&#x1EC7;n/&#x1EA9;n thanh &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng file.</li><li><strong>Command + Shift + K</strong>: X&#xF3;a cache v&#xE0; bi&#xEA;n d&#x1ECB;ch l&#x1EA1;i t&#x1EEB; &#x111;&#x1EA7;u.</li></ul><p>Xcode l&#xE0; m&#x1ED9;t n&#x1EC1;n t&#x1EA3;ng to&#xE0;n di&#x1EC7;n v&#xE0; m&#x1EA1;nh m&#x1EBD; &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng trong h&#x1EC7; sinh th&#xE1;i Apple. T&#x1EEB; vi&#x1EC7;c thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n, vi&#x1EBF;t m&#xE3; logic, cho &#x111;&#x1EBF;n ki&#x1EC3;m th&#x1EED; v&#xE0; xu&#x1EA5;t b&#x1EA3;n l&#xEA;n App Store &#x2013; t&#x1EA5;t c&#x1EA3; &#x111;&#x1EC1;u c&#xF3; th&#x1EC3; th&#x1EF1;c hi&#x1EC7;n ngay trong Xcode. Hy v&#x1ECD;ng qua b&#xE0;i vi&#x1EBF;t n&#xE0;y, b&#x1EA1;n &#x111;&#xE3; hi&#x1EC3;u c&#xE1;ch c&#xE0;i &#x111;&#x1EB7;t v&#xE0; s&#x1EED; d&#x1EE5;ng Xcode, c&#x169;ng nh&#x1B0; s&#x1EB5;n s&#xE0;ng &#x111;&#x1EC3; b&#x1EAF;t &#x111;&#x1EA7;u h&#xE0;nh tr&#xEC;nh <strong><a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">l&#x1EAD;p tr&#xEC;nh iOS</a></strong> m&#x1ED9;t c&#xE1;ch chuy&#xEA;n nghi&#x1EC7;p.</p><p>Tr&#xEA;n &#x111;&#xE2;y l&#xE0; nh&#x1EEF;ng h&#x1B0;&#x1EDB;ng d&#x1EAB;n chi ti&#x1EBF;t v&#x1EC1; c&#xE1;ch s&#x1EED; d&#x1EE5;ng XCode &#x111;&#x1EC3; l&#x1EAD;p tr&#xEC;nh app IOS &#x111;&#x1EBF;n t&#x1EEB; th&#x1EA7;y Duy - Th&#x1EA1;c s&#x129; CNTT, &#x110;&#x1EA1;i h&#x1ECD;c B&#xE1;ch Khoa H&#xE0; N&#x1ED9;i. N&#x1EBF;u mu&#x1ED1;n ti&#x1EBF;p t&#x1EE5;c theo d&#xF5;i th&#x1EA7;y &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t c&#xE1;c khi&#x1EBF;n th&#x1EF1;c v&#x1EC1; L&#x1EAD;p tr&#xEC;nh IOS n&#xF3;i ri&#xEA;ng hay c&#xE1;c ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; l&#x1EAD;p tr&#xEC;nh kh&#xE1;c n&#xF3;i chung, c&#xE1;c b&#x1EA1;n c&#xF3; th&#x1EC3; theo d&#xF5;i th&#x1EA7;y qua:</p><ul><li><em>K&#xEA;nh YouTube: <a href="https://www.youtube.com/@LeHongDuyCNTT">https://www.youtube.com/@LeHongDuyCNTT</a></em></li><li><em>GitHub c&#xE1; nh&#xE2;n: <a href="https://github.com/DuyLeHong">https://github.com/DuyLeHong</a></em></li></ul><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/oo6P8AEG5R4?list=PLc1iBK01_exe60CjOjo797k4QZzwbJHmx" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>Cu&#x1ED1;i c&#xF9;ng, &#x111;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <strong><strong><a href="https://laptrinh-online.vn/blog/thuc-hanh-ios-swift-cach-lam-chu-uilabel-va-uibutton-trong-viewcontroller/codefresher.vn">CodeFresher</a></strong></strong> &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t nh&#x1EEF;ng th&#xF4;ng tin v&#x1EC1; l&#x1EAD;p tr&#xEC;nh, kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh. B&#x1EA1;n c&#xF3; th&#x1EC3; &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c IOS t&#x1EA1;i link: <a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">https://laptrinh-online.vn/course/lap-trinh-ios-swift</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: 0813188668 , 0332026803 (Zalo / Call)</p>]]></content:encoded></item><item><title><![CDATA[Thực hành iOS Swift: Cách làm chủ UILabel và UIButton trong ViewController]]></title><description><![CDATA[Bài viết này hướng dẫn chi tiết cách sử dụng hai thành phần giao diện cơ bản trong lập trình iOS bằng Swift: UILabel và UIButton. Nội dung bao gồm cách tạo project iOS mới, thêm UI Components vào Storyboard, ánh xạ chúng vào ViewController, và xử lý sự kiện tương tác. Bạn cũng sẽ học cách khởi tạo UILabel và UIButton bằng mã Swift thay vì sử dụng giao diện đồ họa (Storyboard).]]></description><link>https://laptrinh-online.vn/blog/thuc-hanh-ios-swift-cach-lam-chu-uilabel-va-uibutton-trong-viewcontroller/</link><guid isPermaLink="false">681a16c014958c001e7abe88</guid><category><![CDATA[Lập trình IOS]]></category><category><![CDATA[UIButton]]></category><category><![CDATA[UILabel]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Tue, 06 May 2025 14:35:26 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/hq720--2-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/hq720--2-.jpg" alt="Th&#x1EF1;c h&#xE0;nh iOS Swift: C&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController"><p>Trong ph&#xE1;t tri&#x1EC3;n<strong><a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift"> &#x1EE9;ng d&#x1EE5;ng iOS</a></strong>, vi&#x1EC7;c t&#x1EA1;o v&#xE0; x&#x1EED; l&#xFD; c&#xE1;c th&#xE0;nh ph&#x1EA7;n giao di&#x1EC7;n l&#xE0; m&#x1ED9;t ph&#x1EA7;n kh&#xF4;ng th&#x1EC3; thi&#x1EBF;u. C&#xE1;c th&#xE0;nh ph&#x1EA7;n c&#x1A1; b&#x1EA3;n nh&#x1B0; <strong>UILabel</strong> (&#x111;&#x1EC3; hi&#x1EC3;n th&#x1ECB; v&#x103;n b&#x1EA3;n) v&#xE0; <strong>UIButton</strong> (&#x111;&#x1EC3; t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i ng&#x1B0;&#x1EDD;i d&#xF9;ng) l&#xE0; nh&#x1EEF;ng kh&#x1ED1;i x&#xE2;y d&#x1EF1;ng quan tr&#x1ECD;ng cho m&#x1ECD;i &#x1EE9;ng d&#x1EE5;ng.</p><p>Swift v&#xE0; Xcode cung c&#x1EA5;p hai c&#xE1;ch &#x111;&#x1EC3; t&#x1EA1;o giao di&#x1EC7;n:</p><ul><li>S&#x1EED; d&#x1EE5;ng Storyboard v&#xE0; Interface Builder</li><li>T&#x1EA1;o th&#xE0;nh ph&#x1EA7;n giao di&#x1EC7;n b&#x1EB1;ng code</li></ul><p>C&#x1EA3; hai c&#xE1;ch &#x111;&#x1EC1;u c&#xF3; &#x1B0;u v&#xE0; nh&#x1B0;&#x1EE3;c &#x111;i&#x1EC3;m ri&#xEA;ng. Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, Th&#x1EA7;y Duy - Th&#x1EA1;c s&#x129; C&#xF4;ng Ngh&#x1EC7; Th&#xF4;ng Tin, &#x110;&#x1EA1;i h&#x1ECD;c B&#xE1;ch Khoa H&#xE0; N&#x1ED9;i s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;c b&#x1EA1;n c&#xE1;ch s&#x1EED; d&#x1EE5;ng c&#x1EA3; hai ph&#x1B0;&#x1A1;ng ph&#xE1;p &#x111;&#x1EC3; hi&#x1EC3;u r&#xF5; c&#x1A1; ch&#x1EBF; ho&#x1EA1;t &#x111;&#x1ED9;ng v&#xE0; linh ho&#x1EA1;t h&#x1A1;n trong ph&#xE1;t tri&#x1EC3;n. C&#xF9;ng theo d&#xF5;i nh&#xE9;!</p><h2 id="uilabel-l%C3%A0-g%C3%AC">UILabel l&#xE0; g&#xEC;?</h2><p><strong>UILabel</strong> l&#xE0; m&#x1ED9;t th&#xE0;nh ph&#x1EA7;n UI d&#xF9;ng &#x111;&#x1EC3; hi&#x1EC3;n th&#x1ECB; v&#x103;n b&#x1EA3;n t&#x129;nh tr&#xEA;n m&#xE0;n h&#xEC;nh. B&#x1EA1;n c&#xF3; th&#x1EC3; t&#xF9;y bi&#x1EBF;n font ch&#x1EEF;, k&#xED;ch th&#x1B0;&#x1EDB;c, m&#xE0;u s&#x1EAF;c, s&#x1ED1; d&#xF2;ng, v&#xE0; c&#x103;n ch&#x1EC9;nh v&#x103;n b&#x1EA3;n.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/CodeFresher_IOS.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh iOS Swift: C&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController" loading="lazy" width="342" height="147"></figure><h3 id="c%C3%A1c-thu%E1%BB%99c-t%C3%ADnh-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-uilabel">C&#xE1;c thu&#x1ED9;c t&#xED;nh c&#x1A1; b&#x1EA3;n c&#x1EE7;a UILabel:</h3><!--kg-card-begin: html--><table data-start="2158" data-end="2640" class="w-fit min-w-(--thread-content-width)"><thead data-start="2158" data-end="2226"><tr data-start="2158" data-end="2226"><th data-start="2158" data-end="2175" data-col-size="sm">Thu&#x1ED9;c t&#xED;nh</th><th data-start="2175" data-end="2226" data-col-size="md">M&#xF4; t&#x1EA3;</th></tr></thead><tbody data-start="2296" data-end="2640"><tr data-start="2296" data-end="2364"><td data-start="2296" data-end="2313" data-col-size="sm"><code data-start="2298" data-end="2304">text</code></td><td data-col-size="md" data-start="2313" data-end="2364">N&#x1ED9;i dung v&#x103;n b&#x1EA3;n hi&#x1EC3;n th&#x1ECB;</td></tr><tr data-start="2365" data-end="2433"><td data-start="2365" data-end="2382" data-col-size="sm"><code data-start="2367" data-end="2378">textColor</code></td><td data-col-size="md" data-start="2382" data-end="2433">M&#xE0;u ch&#x1EEF;</td></tr><tr data-start="2434" data-end="2502"><td data-start="2434" data-end="2451" data-col-size="sm"><code data-start="2436" data-end="2442">font</code></td><td data-col-size="md" data-start="2451" data-end="2502">Ki&#x1EC3;u v&#xE0; k&#xED;ch th&#x1B0;&#x1EDB;c ch&#x1EEF;</td></tr><tr data-start="2503" data-end="2571"><td data-start="2503" data-end="2520" data-col-size="sm"><code data-start="2505" data-end="2520">numberOfLines</code></td><td data-col-size="md" data-start="2520" data-end="2571">S&#x1ED1; d&#xF2;ng &#x111;&#x1B0;&#x1EE3;c hi&#x1EC3;n th&#x1ECB; (0 l&#xE0; kh&#xF4;ng gi&#x1EDB;i h&#x1EA1;n)</td></tr><tr data-start="2572" data-end="2640"><td data-start="2572" data-end="2589" data-col-size="sm"><code data-start="2574" data-end="2589">textAlignment</code></td><td data-col-size="md" data-start="2589" data-end="2640">C&#x103;n ch&#x1EC9;nh v&#x103;n b&#x1EA3;n (tr&#xE1;i, ph&#x1EA3;i, gi&#x1EEF;a, v.v.)</td></tr></tbody></table><!--kg-card-end: html--><h2 id="t%E1%BA%A1o-uilabel-b%E1%BA%B1ng-storyboard">T&#x1EA1;o UILabel b&#x1EB1;ng Storyboard</h2><h3 id="b%C6%B0%E1%BB%9Bc-1-th%C3%AAm-uilabel-v%C3%A0o-storyboard">B&#x1B0;&#x1EDB;c 1: Th&#xEA;m UILabel v&#xE0;o Storyboard</h3><ul><li>M&#x1EDF; file <code>Main.storyboard</code></li><li>K&#xE9;o m&#x1ED9;t UILabel t&#x1EEB; Library (Cmd + Shift + L) v&#xE0;o m&#xE0;n h&#xEC;nh</li><li>Thay &#x111;&#x1ED5;i thu&#x1ED9;c t&#xED;nh t&#x1EA1;i <strong>Inspector</strong> (text, font size, alignment&#x2026;)</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-2-%C3%A1nh-x%E1%BA%A1-uilabel-v%C3%A0o-viewcontrollerswift">B&#x1B0;&#x1EDB;c 2: &#xC1;nh x&#x1EA1; UILabel v&#xE0;o ViewController.swift</h3><p>M&#x1EDF; file <code>ViewController.swift</code> v&#xE0; th&#xEA;m IBOutlet:</p><pre><code>import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        myLabel.text = &quot;Ch&#xE0;o m&#x1EEB;ng &#x111;&#x1EBF;n v&#x1EDB;i iOS!&quot;
        myLabel.textColor = .systemBlue
        myLabel.font = UIFont.systemFont(ofSize: 24, weight: .bold)
    }
}
</code></pre><p>Nh&#x1EDB; k&#x1EBF;t n&#x1ED1;i UILabel trong Storyboard v&#x1EDB;i <code>myLabel</code> b&#x1EB1;ng c&#xE1;ch gi&#x1EEF; Ctrl v&#xE0; k&#xE9;o v&#xE0;o file code ho&#x1EB7;c d&#xF9;ng Connection Inspector.</p><h2 id="t%E1%BA%A1o-uilabel-b%E1%BA%B1ng-code">T&#x1EA1;o UILabel b&#x1EB1;ng code</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/Screen-Shot.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh iOS Swift: C&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController" loading="lazy" width="1149" height="800"></figure><p>B&#x1EA1;n c&#x169;ng c&#xF3; th&#x1EC3; t&#x1EA1;o UILabel m&#xE0; kh&#xF4;ng c&#x1EA7;n storyboard:</p><pre><code>override func viewDidLoad() {
    super.viewDidLoad()

    let label = UILabel()
    label.text = &quot;&#x110;&#xE2;y l&#xE0; UILabel t&#x1EA1;o b&#x1EB1;ng code&quot;
    label.textColor = .darkGray
    label.font = UIFont.systemFont(ofSize: 20)
    label.textAlignment = .center
    label.numberOfLines = 0
    label.frame = CGRect(x: 20, y: 100, width: view.frame.width - 40, height: 60)

    view.addSubview(label)
}</code></pre><p>Vi&#x1EC7;c t&#x1EA1;o b&#x1EB1;ng code gi&#xFA;p b&#x1EA1;n ki&#x1EC3;m so&#xE1;t &#x111;&#x1ED9;ng UI, r&#x1EA5;t h&#x1EEF;u &#xED;ch khi giao di&#x1EC7;n thay &#x111;&#x1ED5;i theo d&#x1EEF; li&#x1EC7;u.</p><hr><h2 id="uibutton-l%C3%A0-g%C3%AC">UIButton l&#xE0; g&#xEC;?</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/button1.jpg" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh iOS Swift: C&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController" loading="lazy" width="1500" height="822"></figure><p><strong>UIButton</strong> l&#xE0; m&#x1ED9;t th&#xE0;nh ph&#x1EA7;n t&#x1B0;&#x1A1;ng t&#xE1;c, cho ph&#xE9;p ng&#x1B0;&#x1EDD;i d&#xF9;ng nh&#x1EA5;n v&#xE0;o &#x111;&#x1EC3; k&#xED;ch ho&#x1EA1;t m&#x1ED9;t h&#xE0;nh &#x111;&#x1ED9;ng nh&#x1B0; m&#x1EDF; m&#xE0;n h&#xEC;nh m&#x1EDB;i, g&#x1EED;i d&#x1EEF; li&#x1EC7;u ho&#x1EB7;c thay &#x111;&#x1ED5;i giao di&#x1EC7;n.</p><h3 id="c%C3%A1c-ki%E1%BB%83u-n%C3%BAt-uibutton-th%C6%B0%E1%BB%9Dng-d%C3%B9ng">C&#xE1;c ki&#x1EC3;u n&#xFA;t UIButton th&#x1B0;&#x1EDD;ng d&#xF9;ng:</h3><!--kg-card-begin: html--><table data-start="4244" data-end="4536" class="w-fit min-w-(--thread-content-width)"><thead data-start="4244" data-end="4300"><tr data-start="4244" data-end="4300"><th data-start="4244" data-end="4260" data-col-size="sm">Lo&#x1EA1;i</th><th data-start="4260" data-end="4300" data-col-size="sm">M&#xF4; t&#x1EA3;</th></tr></thead><tbody data-start="4360" data-end="4536"><tr data-start="4360" data-end="4419"><td data-start="4360" data-end="4376" data-col-size="sm"><code data-start="4362" data-end="4371">.system</code></td><td data-col-size="sm" data-start="4376" data-end="4419">Giao di&#x1EC7;n &#x111;&#x1A1;n gi&#x1EA3;n m&#x1EB7;c &#x111;&#x1ECB;nh c&#x1EE7;a iOS</td></tr><tr data-start="4420" data-end="4479"><td data-start="4420" data-end="4436" data-col-size="sm"><code data-start="4422" data-end="4431">.custom</code></td><td data-col-size="sm" data-start="4436" data-end="4479">T&#xF9;y ch&#x1EC9;nh ho&#xE0;n to&#xE0;n giao di&#x1EC7;n</td></tr><tr data-start="4480" data-end="4536"><td data-start="4480" data-end="4502" data-col-size="sm"><code data-start="4482" data-end="4501">.detailDisclosure</code></td><td data-col-size="sm" data-start="4502" data-end="4536">D&#xF9;ng trong cell ho&#x1EB7;c danh s&#xE1;ch</td></tr></tbody></table><!--kg-card-end: html--><h2 id="t%E1%BA%A1o-uibutton-b%E1%BA%B1ng-storyboard">T&#x1EA1;o UIButton b&#x1EB1;ng Storyboard</h2><h3 id="b%C6%B0%E1%BB%9Bc-1-th%C3%AAm-uibutton-v%C3%A0o-giao-di%E1%BB%87n">B&#x1B0;&#x1EDB;c 1: Th&#xEA;m UIButton v&#xE0;o giao di&#x1EC7;n</h3><ul><li>K&#xE9;o m&#x1ED9;t UIButton t&#x1EEB; Library v&#xE0;o m&#xE0;n h&#xEC;nh</li><li>&#x110;&#x1EB7;t ti&#xEA;u &#x111;&#x1EC1; (title) t&#x1EA1;i <strong>Attributes Inspector</strong></li><li>T&#xF9;y bi&#x1EBF;n m&#xE0;u s&#x1EAF;c, font, h&#xEC;nh &#x1EA3;nh (n&#x1EBF;u c&#x1EA7;n)</li></ul><h3 id="b%C6%B0%E1%BB%9Bc-2-%C3%A1nh-x%E1%BA%A1-iboutlet-v%C3%A0-x%E1%BB%AD-l%C3%BD-onclick">B&#x1B0;&#x1EDB;c 2: &#xC1;nh x&#x1EA1; IBOutlet v&#xE0; x&#x1EED; l&#xFD; onClick</h3><p>Trong <code>ViewController.swift</code>, t&#x1EA1;o IBOutlet v&#xE0; IBAction nh&#x1B0; sau:</p><pre><code>@IBOutlet weak var myButton: UIButton!

@IBAction func buttonTapped(_ sender: UIButton) {
    myLabel.text = &quot;B&#x1EA1;n &#x111;&#xE3; nh&#x1EA5;n n&#xFA;t!&quot;
}
</code></pre><p>&#x110;&#x1EA3;m b&#x1EA3;o k&#x1EBF;t n&#x1ED1;i n&#xFA;t v&#x1EDB;i action th&#xF4;ng qua Connection Inspector ho&#x1EB7;c k&#xE9;o t&#x1EEB; n&#xFA;t v&#xE0;o file code.</p><h2 id="t%E1%BA%A1o-uibutton-b%E1%BA%B1ng-code">T&#x1EA1;o UIButton b&#x1EB1;ng code</h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/05/Screen-Shot-1.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh iOS Swift: C&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController" loading="lazy" width="1165" height="800"></figure><pre><code>override func viewDidLoad() {
    super.viewDidLoad()

    let button = UIButton(type: .system)
    button.setTitle(&quot;Nh&#x1EA5;n t&#xF4;i&quot;, for: .normal)
    button.setTitleColor(.white, for: .normal)
    button.backgroundColor = .systemGreen
    button.frame = CGRect(x: 50, y: 200, width: 200, height: 50)
    button.layer.cornerRadius = 8
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

    view.addSubview(button)
}

@objc func buttonAction() {
    print(&quot;N&#xFA;t &#x111;&#xE3; &#x111;&#x1B0;&#x1EE3;c nh&#x1EA5;n!&quot;)
}</code></pre><p>T&#x1EA1;o b&#x1EB1;ng code th&#x1B0;&#x1EDD;ng &#x111;&#x1B0;&#x1EE3;c d&#xF9;ng trong c&#xE1;c &#x1EE9;ng d&#x1EE5;ng dynamic, kh&#xF4;ng ph&#x1EE5; thu&#x1ED9;c Storyboard.</p><h2 id="k%E1%BA%BFt-h%E1%BB%A3p-uilabel-v%C3%A0-uibutton-%E2%80%93-t%E1%BA%A1o-tr%E1%BA%A3i-nghi%E1%BB%87m-t%C6%B0%C6%A1ng-t%C3%A1c">K&#x1EBF;t h&#x1EE3;p UILabel v&#xE0; UIButton &#x2013; T&#x1EA1;o tr&#x1EA3;i nghi&#x1EC7;m t&#x1B0;&#x1A1;ng t&#xE1;c</h2><p>M&#x1ED9;t v&#xED; d&#x1EE5; &#x111;i&#x1EC3;n h&#xEC;nh l&#xE0; khi ng&#x1B0;&#x1EDD;i d&#xF9;ng nh&#x1EA5;n v&#xE0;o n&#xFA;t, n&#x1ED9;i dung UILabel s&#x1EBD; thay &#x111;&#x1ED5;i:</p><pre><code>@IBOutlet weak var messageLabel: UILabel!
@IBAction func updateMessage(_ sender: UIButton) {
    messageLabel.text = &quot;C&#x1EA3;m &#x1A1;n b&#x1EA1;n &#x111;&#xE3; t&#x1B0;&#x1A1;ng t&#xE1;c!&quot;
}</code></pre><p>Ho&#x1EB7;c n&#x1EBF;u b&#x1EA1;n kh&#xF4;ng d&#xF9;ng storyboard:</p><pre><code>override func viewDidLoad() {
    super.viewDidLoad()

    let label = UILabel()
    label.frame = CGRect(x: 20, y: 100, width: 300, height: 40)
    label.text = &quot;Ban &#x111;&#x1EA7;u&quot;
    label.tag = 1001
    view.addSubview(label)

    let button = UIButton(type: .system)
    button.frame = CGRect(x: 20, y: 160, width: 150, height: 50)
    button.setTitle(&quot;C&#x1EAD;p nh&#x1EAD;t&quot;, for: .normal)
    button.addTarget(self, action: #selector(updateLabel), for: .touchUpInside)
    view.addSubview(button)
}

@objc func updateLabel() {
    if let label = view.viewWithTag(1001) as? UILabel {
        label.text = &quot;&#x110;&#xE3; c&#x1EAD;p nh&#x1EAD;t th&#xE0;nh c&#xF4;ng&quot;
    }
}
</code></pre><p>Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, b&#x1EA1;n &#x111;&#xE3; h&#x1ECD;c c&#xE1;ch s&#x1EED; d&#x1EE5;ng UILabel v&#xE0; UIButton &#x2013; hai th&#xE0;nh ph&#x1EA7;n c&#x1A1; b&#x1EA3;n trong l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n ng&#x1B0;&#x1EDD;i d&#xF9;ng v&#x1EDB;i <strong><a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">iOS Swift</a></strong>. B&#x1EA1;n c&#xF3; th&#x1EC3; kh&#x1EDF;i t&#x1EA1;o ch&#xFA;ng b&#x1EB1;ng Storyboard ho&#x1EB7;c code, &#xE1;nh x&#x1EA1; v&#xE0;o <code>ViewController</code>, v&#xE0; x&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n nh&#x1B0; onClick th&#xF4;ng qua IBAction ho&#x1EB7;c <code>addTarget</code>.</p><h3 id="h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-c%C3%A1ch-t%E1%BA%A1o-m%E1%BB%99t-project-ios-m%E1%BB%9Bi"><em>H&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;ch t&#x1EA1;o m&#x1ED9;t project iOS m&#x1EDB;i</em></h3><p><em>&#x110;&#x1EC3; b&#x1EAF;t &#x111;&#x1EA7;u, m&#x1EDF; <strong>Xcode</strong> v&#xE0; t&#x1EA1;o m&#x1ED9;t project m&#x1EDB;i:</em></p><ul><li><em>Ch&#x1ECD;n <strong>File &gt; New &gt; Project</strong></em></li><li><em>Ch&#x1ECD;n template <strong>App (iOS)</strong></em></li><li><em>&#x110;&#x1EB7;t t&#xEA;n d&#x1EF1; &#xE1;n, v&#xED; d&#x1EE5;: <code>UILabelUIButtonDemo</code></em></li><li><em>Ch&#x1ECD;n <strong>Swift</strong> l&#xE0; ng&#xF4;n ng&#x1EEF; l&#x1EAD;p tr&#xEC;nh, <strong>Storyboard</strong> l&#xE0; c&#xF4;ng c&#x1EE5; giao di&#x1EC7;n</em></li></ul><p>Vi&#x1EC7;c hi&#x1EC3;u r&#xF5; c&#xE1;ch ho&#x1EA1;t &#x111;&#x1ED9;ng c&#x1EE7;a UILabel v&#xE0; UIButton gi&#xFA;p b&#x1EA1;n d&#x1EC5; d&#xE0;ng t&#x1EA1;o ra c&#xE1;c m&#xE0;n h&#xEC;nh t&#x1B0;&#x1A1;ng t&#xE1;c trong &#x1EE9;ng d&#x1EE5;ng iOS, &#x111;&#x1EB7;t n&#x1EC1;n t&#x1EA3;ng v&#x1EEF;ng ch&#x1EAF;c cho nh&#x1EEF;ng th&#xE0;nh ph&#x1EA7;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n nh&#x1B0; UITableView, UICollectionView hay Navigation Controller trong t&#x1B0;&#x1A1;ng lai.</p><p>Nh&#x1B0; v&#x1EAD;y, qua b&#xE0;i vi&#x1EBF;t n&#xE0;y, th&#x1EA7;y Duy &#x111;&#xE3; h&#x1B0;&#x1EDB;ng d&#x1EAB;n cho ch&#xFA;ng ta c&#xE1;ch l&#xE0;m ch&#x1EE7; UILabel v&#xE0; UIButton trong ViewController. &#x110;&#x1EC3; theo d&#xF5;i th&#xEA;m c&#xE1;c ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; <strong><a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">l&#x1EAD;p tr&#xEC;nh IOS</a></strong> hay t&#xE0;i li&#x1EC7;u h&#x1ECD;c t&#x1EAD;p, c&#xE1;c b&#x1EA1;n c&#xF3; th&#x1EC3; theo d&#xF5;i th&#x1EA7;y qua c&#xE1;c k&#xEA;nh: </p><ul><li><em>K&#xEA;nh YouTube: <a href="https://www.youtube.com/@LeHongDuyCNTT">https://www.youtube.com/@LeHongDuyCNTT</a></em></li><li><em>GitHub c&#xE1; nh&#xE2;n: <a href="https://github.com/DuyLeHong">https://github.com/DuyLeHong</a></em></li></ul><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/oJNDViZokuA?list=PLc1iBK01_exe60CjOjo797k4QZzwbJHmx" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>Cu&#x1ED1;i c&#xF9;ng, &#x111;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <strong><a href="codefresher.vn">CodeFresher</a></strong> &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t nh&#x1EEF;ng th&#xF4;ng tin v&#x1EC1; l&#x1EAD;p tr&#xEC;nh, kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh. B&#x1EA1;n c&#xF3; th&#x1EC3; &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c IOS t&#x1EA1;i link: <a href="https://laptrinh-online.vn/course/lap-trinh-ios-swift">https://laptrinh-online.vn/course/lap-trinh-ios-swift</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: 0813188668 , 0332026803 (Zalo / Call)</p>]]></content:encoded></item><item><title><![CDATA[Hướng dẫn Gọi API và Hiển thị dữ liệu JSON lên FlatList trong React Native]]></title><description><![CDATA[<p>Trong qu&#xE1; tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng di &#x111;&#x1ED9;ng, <strong><a href="https://codefresher.vn/cai-dat-moi-truong-react-native-va-chay-ung-dung-bang-expo/">vi&#x1EC7;c l&#x1EA5;y d&#x1EEF; li&#x1EC7;u t&#x1EEB; server v&#xE0; hi&#x1EC3;n th&#x1ECB;</a></strong> ra giao di&#x1EC7;n l&#xE0; m&</p>]]></description><link>https://laptrinh-online.vn/blog/huong-dan-goi-api-va-hien-thi-du-lieu-json-len-flatlist-trong-react-native/</link><guid isPermaLink="false">680f8a3d14958c001e7abe2d</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Mon, 28 Apr 2025 14:17:53 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/zeVnUHd.png" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/zeVnUHd.png" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n G&#x1ECD;i API v&#xE0; Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u JSON l&#xEA;n FlatList trong React Native"><p>Trong qu&#xE1; tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng di &#x111;&#x1ED9;ng, <strong><a href="https://codefresher.vn/cai-dat-moi-truong-react-native-va-chay-ung-dung-bang-expo/">vi&#x1EC7;c l&#x1EA5;y d&#x1EEF; li&#x1EC7;u t&#x1EEB; server v&#xE0; hi&#x1EC3;n th&#x1ECB;</a></strong> ra giao di&#x1EC7;n l&#xE0; m&#x1ED9;t k&#x1EF9; n&#x103;ng n&#x1EC1;n t&#x1EA3;ng. M&#x1ED9;t trong nh&#x1EEF;ng tr&#x1B0;&#x1EDD;ng h&#x1EE3;p ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t l&#xE0; g&#x1ECD;i API l&#x1EA5;y d&#x1EEF; li&#x1EC7;u JSON v&#xE0; tr&#xEC;nh b&#xE0;y n&#xF3; trong m&#x1ED9;t danh s&#xE1;ch cu&#x1ED9;n &#x2014; s&#x1EED; d&#x1EE5;ng <code>FlatList</code> trong React Native.</p><p>B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n b&#x1EA1;n c&#xE1;ch th&#x1EF1;c hi&#x1EC7;n b&#xE0;i b&#x1EA3;n v&#xE0; r&#xF5; r&#xE0;ng.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-56.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n G&#x1ECD;i API v&#xE0; Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u JSON l&#xEA;n FlatList trong React Native" loading="lazy" width="958" height="488"></figure><h2 id="hi%E1%BB%83u-v%E1%BB%81-api-v%C3%A0-json">Hi&#x1EC3;u v&#x1EC1; API v&#xE0; JSON</h2><ul><li><strong>API (Application Programming Interface)</strong>: L&#xE0; giao di&#x1EC7;n giao ti&#x1EBF;p gi&#x1EEF;a &#x1EE9;ng d&#x1EE5;ng v&#xE0; server, cho ph&#xE9;p l&#x1EA5;y ho&#x1EB7;c g&#x1EED;i d&#x1EEF; li&#x1EC7;u.</li><li><strong>JSON (JavaScript Object Notation)</strong>: L&#xE0; &#x111;&#x1ECB;nh d&#x1EA1;ng d&#x1EEF; li&#x1EC7;u ph&#x1ED5; bi&#x1EBF;n, nh&#x1EB9; v&#xE0; d&#x1EC5; thao t&#xE1;c, th&#x1B0;&#x1EDD;ng d&#xF9;ng trong c&#xE1;c ph&#x1EA3;n h&#x1ED3;i API.</li></ul><h2 id="c%C3%A1c-b%C6%B0%E1%BB%9Bc-th%E1%BB%B1c-hi%E1%BB%87n">C&#xE1;c b&#x1B0;&#x1EDB;c th&#x1EF1;c hi&#x1EC7;n</h2><h3 id="1-g%E1%BB%8Di-api-%C4%91%E1%BB%83-l%E1%BA%A5y-d%E1%BB%AF-li%E1%BB%87u">1. G&#x1ECD;i API &#x111;&#x1EC3; l&#x1EA5;y d&#x1EEF; li&#x1EC7;u</h3><p>Vi&#x1EC7;c g&#x1ECD;i API th&#x1B0;&#x1EDD;ng th&#x1EF1;c hi&#x1EC7;n b&#xEA;n trong <code><a href="https://laptrinh-online.vn/blog/huong-dan-dung-hooks-trong-react-native-usestate-useeffect-usememo-usecallback/"><strong>useEffect</strong></a></code> nh&#x1EB1;m &#x111;&#x1EA3;m b&#x1EA3;o y&#xEA;u c&#x1EA7;u &#x111;&#x1B0;&#x1EE3;c g&#x1EED;i khi component &#x111;&#x1B0;&#x1EE3;c mount.</p><p><code>useEffect(() =&gt; { </code></p><p>&#x2003;<code>fetch(&apos;https://api.example.com/data&apos;) </code></p><p>&#x2003;&#x2003;<code>.then(response =&gt; response.json()) </code></p><p>&#x2003;&#x2003;<code>.then(json =&gt; setData(json)) </code></p><p>&#x2003;&#x2003;<code>.catch(error =&gt; console.error(error)); </code></p><p><code>}, []);</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch</strong>:</p><ul><li><code>fetch</code> g&#x1EED;i y&#xEA;u c&#x1EA7;u GET &#x111;&#x1EBF;n API.</li><li><code>response.json()</code> chuy&#x1EC3;n &#x111;&#x1ED5;i ph&#x1EA3;n h&#x1ED3;i th&#xE0;nh &#x111;&#x1ECB;nh d&#x1EA1;ng JSON.</li><li><code>setData(json)</code> l&#x1B0;u d&#x1EEF; li&#x1EC7;u v&#xE0;o state &#x111;&#x1EC3; s&#x1EED; d&#x1EE5;ng trong giao di&#x1EC7;n.</li></ul><h3 id="2-hi%E1%BB%83n-th%E1%BB%8B-d%E1%BB%AF-li%E1%BB%87u-b%E1%BA%B1ng-flatlist">2. Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u b&#x1EB1;ng FlatList</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-57.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n G&#x1ECD;i API v&#xE0; Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u JSON l&#xEA;n FlatList trong React Native" loading="lazy" width="1958" height="1074"></figure><p><code>FlatList</code> s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng render t&#x1EEB;ng item t&#x1EEB; m&#x1EA3;ng d&#x1EEF; li&#x1EC7;u.</p><p><code>&lt;FlatList &#xA0;</code></p><p>&#x2003;<code>data={data} </code></p><p>&#x2003;<code>keyExtractor={item =&gt; item.id.toString()} </code></p><p>&#x2003;<code>renderItem={({ item }) =&gt; ( </code></p><p>&#x2003;&#x2003;<code>&lt;Text&gt;{item.title}&lt;/Text&gt; </code></p><p>&#x2003;<code>)} </code></p><p><code>/&gt;</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch</strong>:</p><ul><li><code>data</code>: ngu&#x1ED3;n d&#x1EEF; li&#x1EC7;u l&#xE0; m&#x1EA3;ng JSON.</li><li><code>keyExtractor</code>: gi&#xFA;p FlatList nh&#x1EAD;n di&#x1EC7;n t&#x1EEB;ng ph&#x1EA7;n t&#x1EED; duy nh&#x1EA5;t.</li><li><code>renderItem</code>: x&#xE1;c &#x111;&#x1ECB;nh c&#xE1;ch m&#x1ED7;i item &#x111;&#x1B0;&#x1EE3;c hi&#x1EC3;n th&#x1ECB;.</li></ul><h2 id="m%E1%BB%99t-s%E1%BB%91-l%C6%B0u-%C3%BD-quan-tr%E1%BB%8Dng">M&#x1ED9;t s&#x1ED1; l&#x1B0;u &#xFD; quan tr&#x1ECD;ng</h2><ul><li><strong>X&#x1EED; l&#xFD; l&#x1ED7;i</strong>: B&#x1EAF;t l&#x1ED7;i khi fetch API &#x111;&#x1EC3; tr&#xE1;nh crash &#x1EE9;ng d&#x1EE5;ng.</li><li><strong>Loading Indicator</strong>: Hi&#x1EC3;n th&#x1ECB; tr&#x1EA1;ng th&#xE1;i t&#x1EA3;i d&#x1EEF; li&#x1EC7;u gi&#xFA;p c&#x1EA3;i thi&#x1EC7;n tr&#x1EA3;i nghi&#x1EC7;m ng&#x1B0;&#x1EDD;i d&#xF9;ng.</li><li><strong>T&#x1ED1;i &#x1B0;u FlatList</strong>: V&#x1EDB;i d&#x1EEF; li&#x1EC7;u l&#x1EDB;n, n&#xEA;n ch&#xFA; tr&#x1ECD;ng t&#x1ED1;i &#x1B0;u h&#xF3;a &#x111;&#x1EC3; tr&#xE1;nh t&#x1EE5;t hi&#x1EC7;u su&#x1EA5;t.</li></ul><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/ardKBRB3zno?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="L&#x1EAD;p tr&#xEC;nh React Native - B&#xE0;i 6 - G&#x1ECD;i API l&#x1EA5;y d&#x1EEF; li&#x1EC7;u JSON v&#x1EC1; hi&#x1EC3;n th&#x1ECB; l&#xEA;n FlastList"></iframe></figure><h2 id="k%E1%BA%BFt-lu%E1%BA%ADn">K&#x1EBF;t lu&#x1EAD;n</h2><p>Vi&#x1EC7;c th&#xE0;nh th&#x1EA1;o quy tr&#xEC;nh <strong>g&#x1ECD;i API</strong> v&#xE0; <strong>hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u l&#xEA;n FlatList</strong> kh&#xF4;ng ch&#x1EC9; ph&#x1EE5;c v&#x1EE5; nhu c&#x1EA7;u hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch &#x111;&#x1A1;n gi&#x1EA3;n m&#xE0; c&#xF2;n l&#xE0; n&#x1EC1;n t&#x1EA3;ng &#x111;&#x1EC3; b&#x1EA1;n ph&#xE1;t tri&#x1EC3;n nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng di &#x111;&#x1ED9;ng ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n nh&#x1B0;: chat realtime, m&#x1EA1;ng x&#xE3; h&#x1ED9;i, th&#x1B0;&#x1A1;ng m&#x1EA1;i &#x111;i&#x1EC7;n t&#x1EED;, v.v.</p><p>Tuy nhi&#xEA;n, trong th&#x1EF1;c t&#x1EBF;, c&#xE1;c b&#xE0;i to&#xE1;n th&#x1B0;&#x1EDD;ng ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n:</p><ul><li>API c&#xF3; &#x111;&#x1ED9; tr&#x1EC5; cao, c&#x1EA7;n cache d&#x1EEF; li&#x1EC7;u</li><li>C&#x1EA7;n ph&#xE2;n trang (pagination) cho danh s&#xE1;ch l&#x1EDB;n</li><li>X&#x1EED; l&#xFD; c&#xE1;c t&#xEC;nh hu&#x1ED1;ng l&#x1ED7;i m&#x1EA1;ng, m&#x1EA5;t k&#x1EBF;t n&#x1ED1;i</li><li>T&#x1ED1;i &#x1B0;u hi&#x1EC7;u su&#x1EA5;t khi d&#x1EEF; li&#x1EC7;u c&#xF3; h&#xE0;ng ng&#xE0;n b&#x1EA3;n ghi</li></ul><p>&#x110;&#x1EC3; gi&#x1EA3;i quy&#x1EBF;t t&#x1ED1;t nh&#x1EEF;ng v&#x1EA5;n &#x111;&#x1EC1; &#x111;&#xF3;, c&#x1EA7;n m&#x1ED9;t l&#x1ED9; tr&#xEC;nh h&#x1ECD;c b&#xE0;i b&#x1EA3;n v&#xE0; th&#x1EF1;c chi&#x1EBF;n.</p><h2 id="kho%C3%A1-h%E1%BB%8Dc-react-nativet%E1%BB%AB-c%C6%A1-b%E1%BA%A3n-%C4%91%E1%BA%BFn-tri%E1%BB%83n-khai-th%E1%BB%B1c-t%E1%BA%BF">Kho&#xE1; h&#x1ECD;c: &#xA0;&quot;React Native - T&#x1EEB; C&#x1A1; B&#x1EA3;n &#x111;&#x1EBF;n Tri&#x1EC3;n Khai Th&#x1EF1;c T&#x1EBF;&quot;</h2><p>N&#x1EBF;u b&#x1EA1;n mu&#x1ED1;n:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-58.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng d&#x1EAB;n G&#x1ECD;i API v&#xE0; Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u JSON l&#xEA;n FlatList trong React Native" loading="lazy" width="848" height="548"></figure><ul><li>N&#x1EAF;m v&#x1EEF;ng c&#xE1;ch <strong>t&#x1ED1;i &#x1B0;u h&#xF3;a vi&#x1EC7;c g&#x1ECD;i API</strong> (v&#x1EDB;i Axios, React Query)</li><li>X&#xE2;y d&#x1EF1;ng c&#xE1;c <strong>FlatList l&#x1EDB;n m&#x1B0;&#x1EE3;t m&#xE0;</strong>, ph&#xE2;n trang t&#x1EF1; &#x111;&#x1ED9;ng, pull-to-refresh</li><li>Qu&#x1EA3;n l&#xFD; <strong>state ph&#x1EE9;c t&#x1EA1;p</strong> (Context, Redux, Zustand)</li><li>L&#xE0;m ch&#x1EE7; quy tr&#xEC;nh <strong>ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF;</strong>, tri&#x1EC3;n khai l&#xEA;n App Store, Google Play</li></ul><p>Th&#xEC; kho&#xE1; h&#x1ECD;c <strong>&quot;React Native - T&#x1EEB; C&#x1A1; B&#x1EA3;n &#x111;&#x1EBF;n Tri&#x1EC3;n Khai Th&#x1EF1;c T&#x1EBF;&quot;</strong> s&#x1EBD; l&#xE0; m&#x1ED9;t l&#x1EF1;a ch&#x1ECD;n ph&#xF9; h&#x1EE3;p.</p><p>Kho&#xE1; h&#x1ECD;c kh&#xF4;ng ch&#x1EC9; d&#x1EA1;y l&#xFD; thuy&#x1EBF;t m&#xE0; c&#xF2;n h&#x1B0;&#x1EDB;ng d&#x1EAB;n th&#x1EF1;c h&#xE0;nh c&#xE1;c d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF; nh&#x1B0;:</p><ul><li>&#x1EE8;ng d&#x1EE5;ng m&#x1EA1;ng x&#xE3; h&#x1ED9;i mini</li><li>&#x1EE8;ng d&#x1EE5;ng b&#xE1;n h&#xE0;ng tr&#x1EF1;c tuy&#x1EBF;n</li><li>H&#x1EC7; th&#x1ED1;ng qu&#x1EA3;n l&#xFD; &#x111;&#x1A1;n h&#xE0;ng</li></ul><p>Ngo&#xE0;i ra, kh&#xF3;a h&#x1ECD;c c&#xF2;n &#x111;i k&#xE8;m h&#x1B0;&#x1EDB;ng d&#x1EAB;n k&#x1EF9; thu&#x1EAD;t tri&#x1EC3;n khai API backend ri&#xEA;ng &#x111;&#x1EC3; b&#x1EA1;n th&#x1EF1;c s&#x1EF1; l&#xE0;m ch&#x1EE7; quy tr&#xEC;nh x&#xE2;y d&#x1EF1;ng m&#x1ED9;t s&#x1EA3;n ph&#x1EA9;m ho&#xE0;n ch&#x1EC9;nh.</p><p><strong>Quan tr&#x1ECD;ng nh&#x1EA5;t</strong>, sau kh&#xF3;a h&#x1ECD;c, b&#x1EA1;n s&#x1EBD; c&#xF3; th&#x1EC3; t&#x1EF1; tin tri&#x1EC3;n khai &#x1EE9;ng d&#x1EE5;ng mobile ho&#xE0;n ch&#x1EC9;nh t&#x1EEB; &#x111;&#x1EA7;u &#x111;&#x1EBF;n cu&#x1ED1;i.</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/course/lap-trinh-react-native">https://laptrinh-online.vn/course/lap-trinh-react-native</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Hướng Dẫn Dùng Hooks Trong React Native | useState, useEffect, useMemo, useCallback]]></title><description><![CDATA[<p><strong>Hooks</strong> l&#xE0; m&#x1ED9;t trong nh&#x1EEF;ng t&#xED;nh n&#x103;ng quan tr&#x1ECD;ng v&#xE0; m&#x1EA1;nh m&#x1EBD; nh&#x1EA5;t trong h&#x1EC7; sinh th&#xE1;i React Native. N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m</p>]]></description><link>https://laptrinh-online.vn/blog/huong-dan-dung-hooks-trong-react-native-usestate-useeffect-usememo-usecallback/</link><guid isPermaLink="false">680e278614958c001e7abd7a</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Sun, 27 Apr 2025 13:11:16 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/snapshots-with-memo.png" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/snapshots-with-memo.png" alt="H&#x1B0;&#x1EDB;ng D&#x1EAB;n D&#xF9;ng Hooks Trong React Native | useState, useEffect, useMemo, useCallback"><p><strong>Hooks</strong> l&#xE0; m&#x1ED9;t trong nh&#x1EEF;ng t&#xED;nh n&#x103;ng quan tr&#x1ECD;ng v&#xE0; m&#x1EA1;nh m&#x1EBD; nh&#x1EA5;t trong h&#x1EC7; sinh th&#xE1;i React Native. N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m c&#xE1;ch n&#xE2;ng cao hi&#x1EC7;u qu&#x1EA3; l&#x1EAD;p tr&#xEC;nh, t&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC7;u su&#x1EA5;t &#x1EE9;ng d&#x1EE5;ng v&#xE0; vi&#x1EBF;t m&#xE3; s&#x1EA1;ch h&#x1A1;n, vi&#x1EC7;c n&#x1EAF;m v&#x1EEF;ng Hooks l&#xE0; b&#x1B0;&#x1EDB;c &#x111;i kh&#xF4;ng th&#x1EC3; thi&#x1EBF;u.</p><p>Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; &#x111;i th&#x1EB3;ng v&#xE0;o tr&#x1ECD;ng t&#xE2;m: hi&#x1EC3;u v&#xE0; &#xE1;p d&#x1EE5;ng c&#xE1;c Hook ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t g&#x1ED3;m <code>useState</code>, <code>useEffect</code>, <code>useMemo</code> v&#xE0; <code>useCallback</code> trong React Native.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-53.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng D&#x1EAB;n D&#xF9;ng Hooks Trong React Native | useState, useEffect, useMemo, useCallback" loading="lazy" width="800" height="536"></figure><h2 id="1-usestate-%E2%80%93-qu%E1%BA%A3n-l%C3%BD-tr%E1%BA%A1ng-th%C3%A1i-trong-component">1. useState &#x2013; Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i trong component</h2><p><code>useState</code> cho ph&#xE9;p b&#x1EA1;n khai b&#xE1;o state ngay trong m&#x1ED9;t functional component. &#x110;&#xE2;y l&#xE0; &#x111;i&#x1EC3;m kh&#xE1;c bi&#x1EC7;t l&#x1EDB;n so v&#x1EDB;i c&#xE1;ch s&#x1EED; d&#x1EE5;ng <code>this.state</code> trong class component tr&#x1B0;&#x1EDB;c &#x111;&#xE2;y.</p><p><strong>C&#xE1;ch s&#x1EED; d&#x1EE5;ng:</strong></p><p><code>import React, { useState } from &apos;react&apos;; </code></p><p><code>import { View, Button, Text } from &apos;react-native&apos;; </code></p><p><code>export default function Counter() { </code></p><p>&#x2003;<code>const [count, setCount] = useState(0); </code></p><p>&#x2003;<code>return ( </code></p><p>&#x2003;&#x2003;<code>&lt;View&gt; </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>&lt;Text&gt;{count}&lt;/Text&gt; </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>&lt;Button title=&quot;T&#x103;ng&quot; onPress={() =&gt; setCount(count + 1)} /&gt; </code></p><p>&#x2003;&#x2003;<code>&lt;/View&gt; </code></p><p>&#x2003;<code>); </code></p><p><code>}</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><p><code>useState(0)</code> kh&#x1EDF;i t&#x1EA1;o gi&#xE1; tr&#x1ECB; ban &#x111;&#x1EA7;u c&#x1EE7;a <code>count</code> l&#xE0; <code>0</code>.</p><p><code>setCount</code> l&#xE0; h&#xE0;m d&#xF9;ng &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t gi&#xE1; tr&#x1ECB; <code>count</code>.</p><p><code>useState</code> gi&#xFA;p functional component linh ho&#x1EA1;t h&#x1A1;n, d&#x1EC5; d&#xE0;ng m&#x1EDF; r&#x1ED9;ng v&#xE0; duy tr&#xEC;.</p><h2 id="2-useeffect-%E2%80%93-x%E1%BB%AD-l%C3%BD-side-effects">2. useEffect &#x2013; X&#x1EED; l&#xFD; side effects</h2><p><code>useEffect</code> &#x111;&#x1B0;&#x1EE3;c d&#xF9;ng &#x111;&#x1EC3; x&#x1EED; l&#xFD; c&#xE1;c t&#xE1;c v&#x1EE5; nh&#x1B0; fetch d&#x1EEF; li&#x1EC7;u, &#x111;&#x103;ng k&#xFD; s&#x1EF1; ki&#x1EC7;n, ho&#x1EB7;c thay &#x111;&#x1ED5;i DOM (n&#x1EBF;u c&#x1EA7;n thi&#x1EBF;t).</p><p><code>import React, { useState, useEffect } from &apos;react&apos;; </code></p><p><code>import { View, Text } from &apos;react-native&apos;; </code></p><p><code>export default function Timer() { </code></p><p>&#x2003;<code>const [seconds, setSeconds] = useState(0); </code></p><p>&#x2003;<code>useEffect(() =&gt; { </code></p><p>&#x2003;&#x2003;<code>const interval = setInterval(() =&gt; { </code></p><p>&#x2003;&#x2003;&#x2003;<code>setSeconds(prev =&gt; prev + 1); </code></p><p>&#x2003;&#x2003;<code>}, 1000); </code></p><p>&#x2003;<code>return () =&gt; clearInterval(interval); </code></p><p>&#x2003;<code>}, []); </code></p><p><code>return (</code></p><p>&#x2003;<code> &lt;View&gt; </code></p><p>&#x2003;&#x2003;<code>&lt;Text&gt;Th&#x1EDD;i gian: {seconds} gi&#xE2;y&lt;/Text&gt; </code></p><p>&#x2003;<code>&lt;/View&gt; </code>&#x2003;</p><p>&#x2003;<code>); </code></p><p><code>}</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><p><code>useEffect</code> v&#x1EDB;i dependency array <code>[]</code> s&#x1EBD; ch&#x1EA1;y m&#x1ED9;t l&#x1EA7;n khi component mount.</p><p>H&#xE0;m return trong <code>useEffect</code> l&#xE0; cleanup function, r&#x1EA5;t c&#x1EA7;n thi&#x1EBF;t &#x111;&#x1EC3; tr&#xE1;nh r&#xF2; r&#x1EC9; b&#x1ED9; nh&#x1EDB;.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng c&#xF3; nhi&#x1EC1;u y&#xEA;u c&#x1EA7;u t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i server ho&#x1EB7;c s&#x1EF1; ki&#x1EC7;n th&#x1EDD;i gian th&#x1EF1;c, <code>useEffect</code> l&#xE0; c&#xF4;ng c&#x1EE5; kh&#xF4;ng th&#x1EC3; thi&#x1EBF;u.</p><h2 id="3-usememo-%E2%80%93-t%E1%BB%91i-%C6%B0u-h%C3%B3a-hi%E1%BB%87u-su%E1%BA%A5t-t%C3%ADnh-to%C3%A1n">3. useMemo &#x2013; T&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC7;u su&#x1EA5;t t&#xED;nh to&#xE1;n</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-54.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng D&#x1EAB;n D&#xF9;ng Hooks Trong React Native | useState, useEffect, useMemo, useCallback" loading="lazy" width="1200" height="630"></figure><p><code>useMemo</code> gi&#xFA;p ghi nh&#x1EDB; k&#x1EBF;t qu&#x1EA3; c&#x1EE7;a m&#x1ED9;t ph&#xE9;p t&#xED;nh ph&#x1EE9;c t&#x1EA1;p, ch&#x1EC9; t&#xED;nh l&#x1EA1;i khi dependencies thay &#x111;&#x1ED5;i. &#x110;i&#x1EC1;u n&#xE0;y c&#x1EF1;c k&#x1EF3; quan tr&#x1ECD;ng v&#x1EDB;i c&#xE1;c &#x1EE9;ng d&#x1EE5;ng c&#x1EA7;n t&#x1ED1;i &#x1B0;u h&#xF3;a t&#x1ED1;c &#x111;&#x1ED9;.</p><p><strong>C&#xE1;ch s&#x1EED; d&#x1EE5;ng:</strong></p><p><code>import React, { useState, useMemo } from &apos;react&apos;; </code></p><p><code>import { View, Button, Text } from &apos;react-native&apos;; </code></p><p><code>export default function ExpensiveCalculation() { </code></p><p>&#x2003;<code>const [count, setCount] = useState(0); </code></p><p>&#x2003;<code>const [other, setOther] = useState(false); </code></p><p>&#x2003;<code>const expensiveValue = useMemo(() =&gt; { </code></p><p>&#x2003;&#x2003;<code>let result = 0; </code></p><p>&#x2003;&#x2003;<code>for (let i = 0; i &lt; 100000000; i++) { </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>result += i; </code></p><p>&#x2003;&#x2003;<code>} </code></p><p>&#x2003;&#x2003;<code>return result + count; </code></p><p>&#x2003;<code>}, [count]); </code></p><p>&#x2003;<code>return ( </code></p><p>&#x2003;&#x2003;<code>&lt;View&gt; </code></p><p>&#x2003;&#x2003;&#x2003;<code>&lt;Text&gt;T&#xED;nh to&#xE1;n: {expensiveValue}&lt;/Text&gt; </code></p><p>&#x2003;&#x2003;&#x2003;<code>&lt;Button title=&quot;T&#x103;ng&quot; onPress={() =&gt; setCount(count + 1)} /&gt; </code></p><p>&#x2003;&#x2003;&#x2003;<code>&lt;Button title=&quot;Thay &#x111;&#x1ED5;i kh&#xE1;c&quot; onPress={() =&gt; setOther(!other)} /&gt; &#xA0;&lt;/View&gt; </code></p><p>&#x2003;&#x2003;<code>); </code></p><p><code>}</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><p>N&#x1EBF;u kh&#xF4;ng c&#xF3; <code>useMemo</code>, ph&#xE9;p t&#xED;nh t&#x1ED1;n k&#xE9;m s&#x1EBD; ch&#x1EA1;y l&#x1EA1;i m&#x1ED7;i khi b&#x1EA5;t k&#x1EF3; state n&#xE0;o thay &#x111;&#x1ED5;i.</p><p><code>useMemo</code> gi&#xFA;p ch&#x1EC9; t&#xED;nh l&#x1EA1;i khi <code>count</code> thay &#x111;&#x1ED5;i, t&#x1ED1;i &#x1B0;u hi&#x1EC7;u su&#x1EA5;t r&#x1EA5;t r&#xF5; r&#x1EC7;t.</p><p>Trong c&#xE1;c &#x1EE9;ng d&#x1EE5;ng React Native, n&#x1A1;i hi&#x1EC7;u su&#x1EA5;t v&#xE0; t&#x1ED1;c &#x111;&#x1ED9; ph&#x1EA3;n h&#x1ED3;i r&#x1EA5;t quan tr&#x1ECD;ng, <code>useMemo</code> gi&#xFA;p b&#x1EA1;n ki&#x1EC3;m so&#xE1;t t&#xE0;i nguy&#xEA;n hi&#x1EC7;u qu&#x1EA3; h&#x1A1;n.</p><h2 id="4-usecallback-%E2%80%93-t%E1%BB%91i-%C6%B0u-h%C3%B3a-callback-function">4. useCallback &#x2013; T&#x1ED1;i &#x1B0;u h&#xF3;a callback function</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-55.png" class="kg-image" alt="H&#x1B0;&#x1EDB;ng D&#x1EAB;n D&#xF9;ng Hooks Trong React Native | useState, useEffect, useMemo, useCallback" loading="lazy" width="1024" height="576"></figure><p><code>useCallback</code> ghi nh&#x1EDB; m&#x1ED9;t h&#xE0;m v&#xE0; ch&#x1EC9; t&#xE1;i t&#x1EA1;o l&#x1EA1;i khi dependencies thay &#x111;&#x1ED5;i. &#x110;i&#x1EC1;u n&#xE0;y c&#x1EF1;c k&#x1EF3; h&#x1EEF;u &#xED;ch khi b&#x1EA1;n truy&#x1EC1;n callback xu&#x1ED1;ng nhi&#x1EC1;u component con.</p><p><strong>C&#xE1;ch s&#x1EED; d&#x1EE5;ng:</strong></p><p><code>import React, { useState, useCallback } from &apos;react&apos;; </code></p><p><code>import { View, Button, Text } from &apos;react-native&apos;; </code></p><p><code>function Child({ onClick }) { </code></p><p>&#x2003;&#x2003;<code>return &lt;Button title=&quot;G&#x1ECD;i h&#xE0;m cha&quot; onPress={onClick} /&gt;; </code></p><p><code>} </code></p><p><code>export default function Parent() { </code></p><p>&#x2003;&#x2003;<code>const [count, setCount] = useState(0); </code></p><p>&#x2003;&#x2003;<code>const handleClick = useCallback(() =&gt; { </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>console.log(&apos;&#x110;&#xE3; click&apos;); </code></p><p>&#x2003;<code>}, []); </code></p><p>&#x2003;<code>return ( </code></p><p>&#x2003;&#x2003;<code>&lt;View&gt; </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>&lt;Text&gt;{count}&lt;/Text&gt; </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>&lt;Button title=&quot;T&#x103;ng&quot; onPress={() =&gt; setCount(count + 1)} /&gt; &lt;Child onClick={handleClick} /&gt; </code></p><p>&#x2003;&#x2003;<code>&lt;/View&gt; </code></p><p>&#x2003;&#x2003;<code>); </code></p><p><code>}</code></p><p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p><p>Kh&#xF4;ng d&#xF9;ng <code>useCallback</code>, m&#x1ED7;i l&#x1EA7;n render, h&#xE0;m <code>handleClick</code> s&#x1EBD; &#x111;&#x1B0;&#x1EE3;c t&#x1EA1;o l&#x1EA1;i, g&#xE2;y t&#x1ED1;n t&#xE0;i nguy&#xEA;n v&#xE0; &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n t&#x1ED1;i &#x1B0;u h&#xF3;a rendering.</p><p>V&#x1EDB;i <code>useCallback</code>, React bi&#x1EBF;t r&#x1EB1;ng <code>handleClick</code> kh&#xF4;ng thay &#x111;&#x1ED5;i n&#x1EBF;u dependencies kh&#xF4;ng thay &#x111;&#x1ED5;i.</p><p>Khi &#x1EE9;ng d&#x1EE5;ng c&#xF3; nhi&#x1EC1;u component l&#x1ED3;ng nhau, <code>useCallback</code> gi&#xFA;p gi&#x1EA3;m rendering kh&#xF4;ng c&#x1EA7;n thi&#x1EBF;t, c&#x1EA3;i thi&#x1EC7;n hi&#x1EC7;u su&#x1EA5;t r&#xF5; r&#x1EC7;t.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/lBoZAbUlSKA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="H&#x1B0;&#x1EDB;ng D&#x1EAB;n D&#xF9;ng Hooks Trong React Native | UseState, UseEffect, UseMemo, UseCallback"></iframe></figure><h1 id="k%E1%BA%BFt-lu%E1%BA%ADn">K&#x1EBF;t lu&#x1EAD;n</h1><p><strong>Hooks</strong> l&#xE0; n&#x1EC1;n t&#x1EA3;ng quan tr&#x1ECD;ng trong vi&#x1EC7;c ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng React Native hi&#x1EC7;n &#x111;&#x1EA1;i. Ch&#xFA;ng mang l&#x1EA1;i c&#xFA; ph&#xE1;p g&#x1ECD;n g&#xE0;ng, kh&#x1EA3; n&#x103;ng t&#xE1;i s&#x1EED; d&#x1EE5;ng logic cao h&#x1A1;n v&#xE0; t&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC7;u su&#x1EA5;t v&#x1B0;&#x1EE3;t tr&#x1ED9;i.</p><ul><li><code>useState</code>: Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i &#x111;&#x1A1;n gi&#x1EA3;n.</li><li><code>useEffect</code>: Qu&#x1EA3;n l&#xFD; side effects chuy&#xEA;n nghi&#x1EC7;p.</li><li><code>useMemo</code>: Gi&#x1EA3;m chi ph&#xED; t&#xED;nh to&#xE1;n n&#x1EB7;ng.</li><li><code>useCallback</code>: Gi&#x1EA3;m t&#xE1;i t&#x1EA1;o h&#xE0;m kh&#xF4;ng c&#x1EA7;n thi&#x1EBF;t.</li></ul><p>N&#x1EAF;m v&#x1EEF;ng c&#xE1;ch d&#xF9;ng Hooks ch&#xED;nh l&#xE0; b&#x1B0;&#x1EDB;c &#x111;&#x1EA7;u ti&#xEA;n &#x111;&#x1EC3; b&#x1EA1;n ti&#x1EBF;n s&#xE2;u h&#x1A1;n v&#xE0;o th&#x1EBF; gi&#x1EDB;i React Native chuy&#xEA;n nghi&#x1EC7;p.</p><p>N&#x1EBF;u <strong>b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m l&#x1ED9; tr&#xEC;nh b&#xE0;i b&#x1EA3;n, th&#x1EF1;c h&#xE0;nh d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF;</strong>, h&#xE3;y c&#xE2;n nh&#x1EAF;c tham gia c&#xE1;c <strong><a href="https://laptrinh-online.vn/course/lap-trinh-react-native">kho&#xE1; h&#x1ECD;c chuy&#xEA;n s&#xE2;u v&#x1EC1; React Native</a></strong>. Vi&#x1EC7;c h&#x1ECD;c &#x111;&#xFA;ng c&#xE1;ch ngay t&#x1EEB; &#x111;&#x1EA7;u s&#x1EBD; gi&#xFA;p b&#x1EA1;n ti&#x1EBF;t ki&#x1EC7;m h&#xE0;ng tr&#x103;m gi&#x1EDD; t&#x1EF1; m&#xF2; m&#x1EAB;m v&#xE0; r&#xFA;t ng&#x1EAF;n &#x111;&#xE1;ng k&#x1EC3; th&#x1EDD;i gian tr&#x1EDF; th&#xE0;nh l&#x1EAD;p tr&#xEC;nh vi&#xEA;n mobile chuy&#xEA;n nghi&#x1EC7;p.</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/course/lap-trinh-react-native">https://laptrinh-online.vn/course/lap-trinh-react-native</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Tạo Chuyển Trang Trong ReactJS với react-router, useHistory và useParams]]></title><description><![CDATA[Việc điều hướng giữa các trang trong ứng dụng web là một kỹ năng quan trọng đối với lập trình viên React. Thư viện react-router-dom giúp triển khai hệ thống định tuyến (routing) trong ứng dụng React một cách linh hoạt và hiệu quả. Bài viết này sẽ hướng dẫn chi tiết cách sử dụng React Router, cách định nghĩa tuyến đường, cũng như cách khai thác các hook như useHistory và useParams.]]></description><link>https://laptrinh-online.vn/blog/tao-chuyen-trang-trong-reactjs-voi-react-router-usehistory-va-useparams/</link><guid isPermaLink="false">6808c02114958c001e7abcfe</guid><category><![CDATA[khóa học lập trình ReactJS]]></category><category><![CDATA[Lập trình với ReactJS]]></category><category><![CDATA[ReactJS]]></category><category><![CDATA[ứng dụng ReactJS]]></category><category><![CDATA[useParams]]></category><category><![CDATA[useHistory]]></category><category><![CDATA[react-router]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Wed, 23 Apr 2025 10:40:47 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault--1-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault--1-.jpg" alt="T&#x1EA1;o Chuy&#x1EC3;n Trang Trong ReactJS v&#x1EDB;i react-router, useHistory v&#xE0; useParams"><p>Vi&#x1EC7;c &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng gi&#x1EEF;a c&#xE1;c trang trong &#x1EE9;ng d&#x1EE5;ng web l&#xE0; m&#x1ED9;t k&#x1EF9; n&#x103;ng quan tr&#x1ECD;ng &#x111;&#x1ED1;i v&#x1EDB;i <strong><a href="https://codenhanh.vn/lap-trinh-web-reactjs-voi-chatgpt-copilot-full">l&#x1EAD;p tr&#xEC;nh vi&#xEA;n React</a></strong>. Th&#x1B0; vi&#x1EC7;n <code>react-router-dom</code> gi&#xFA;p tri&#x1EC3;n khai h&#x1EC7; th&#x1ED1;ng &#x111;&#x1ECB;nh tuy&#x1EBF;n (routing) trong &#x1EE9;ng d&#x1EE5;ng React m&#x1ED9;t c&#xE1;ch linh ho&#x1EA1;t v&#xE0; hi&#x1EC7;u qu&#x1EA3;. B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n chi ti&#x1EBF;t c&#xE1;ch s&#x1EED; d&#x1EE5;ng React Router, c&#xE1;ch &#x111;&#x1ECB;nh ngh&#x129;a tuy&#x1EBF;n &#x111;&#x1B0;&#x1EDD;ng, c&#x169;ng nh&#x1B0; c&#xE1;ch khai th&#xE1;c c&#xE1;c hook nh&#x1B0; <code>useHistory</code> v&#xE0; <code>useParams</code>.</p><h2 id="1-gi%E1%BB%9Bi-thi%E1%BB%87u-v%E1%BB%81-react-router-%E2%80%93-%C4%91i%E1%BB%81u-h%C6%B0%E1%BB%9Bng-trong-spa"><strong>1. Gi&#x1EDB;i thi&#x1EC7;u v&#x1EC1; React Router &#x2013; &#x110;i&#x1EC1;u h&#x1B0;&#x1EDB;ng trong SPA</strong></h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-50.png" class="kg-image" alt="T&#x1EA1;o Chuy&#x1EC3;n Trang Trong ReactJS v&#x1EDB;i react-router, useHistory v&#xE0; useParams" loading="lazy" width="1280" height="720"></figure><p>React Router l&#xE0; th&#x1B0; vi&#x1EC7;n gi&#xFA;p b&#x1EA1;n t&#x1EA1;o h&#x1EC7; th&#x1ED1;ng &#x111;&#x1ECB;nh tuy&#x1EBF;n (routing system) cho c&#xE1;c <strong><a href="https://codenhanh.vn/lap-trinh-web-reactjs-voi-chatgpt-copilot-full">&#x1EE9;ng d&#x1EE5;ng React</a></strong>. Thay v&#xEC; chuy&#x1EC3;n h&#x1B0;&#x1EDB;ng b&#x1EB1;ng HTML truy&#x1EC1;n th&#x1ED1;ng, React Router cho ph&#xE9;p b&#x1EA1;n &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng trong n&#x1ED9;i b&#x1ED9; &#x1EE9;ng d&#x1EE5;ng, gi&#xFA;p tr&#x1EA3;i nghi&#x1EC7;m m&#x1B0;&#x1EE3;t m&#xE0; h&#x1A1;n.</p><h3 id="c%C3%A0i-%C4%91%E1%BA%B7t"><strong>C&#xE0;i &#x111;&#x1EB7;t:</strong></h3><pre><code>npm install react-router-dom
</code></pre><p>Sau &#x111;&#xF3; b&#x1EA1;n c&#x1EA7;n b&#x1ECD;c to&#xE0;n b&#x1ED9; &#x1EE9;ng d&#x1EE5;ng b&#x1EB1;ng <code>&lt;BrowserRouter&gt;</code>:</p><pre><code>import { BrowserRouter } from &apos;react-router-dom&apos;;

&lt;BrowserRouter&gt;
  &lt;App /&gt;
&lt;/BrowserRouter&gt;
</code></pre><h2 id="2-t%E1%BA%A1o-router-v%C3%A0-li%C3%AAn-k%E1%BA%BFt-b%E1%BA%B1ng-link"><strong>2. T&#x1EA1;o Router v&#xE0; li&#xEA;n k&#x1EBF;t b&#x1EB1;ng Link</strong></h2><p>B&#x1EA1;n c&#xF3; th&#x1EC3; &#x111;&#x1ECB;nh ngh&#x129;a c&#xE1;c tuy&#x1EBF;n &#x111;&#x1B0;&#x1EDD;ng b&#x1EB1;ng <code>Route</code> v&#xE0; t&#x1EA1;o li&#xEA;n k&#x1EBF;t b&#x1EB1;ng <code>Link</code>.</p><p>V&#xED; d&#x1EE5; c&#x1A1; b&#x1EA3;n:</p><pre><code>import { Route, Switch, Link } from &apos;react-router-dom&apos;;

function App() {
  return (
    &lt;div&gt;
      &lt;Link to=&quot;/about&quot;&gt;Gi&#x1EDB;i thi&#x1EC7;u&lt;/Link&gt;
      &lt;Switch&gt;
        &lt;Route exact path=&quot;/&quot; component={HomePage} /&gt;
        &lt;Route path=&quot;/about&quot; component={AboutPage} /&gt;
      &lt;/Switch&gt;
    &lt;/div&gt;
  );
}
</code></pre><ul><li><code>Switch</code> gi&#xFA;p &#x111;&#x1EA3;m b&#x1EA3;o ch&#x1EC9; c&#xF3; m&#x1ED9;t <code>Route</code> &#x111;&#x1B0;&#x1EE3;c render.</li><li><code>exact</code> l&#xE0; t&#xF9;y ch&#x1ECD;n gi&#xFA;p kh&#x1EDB;p ch&#xED;nh x&#xE1;c &#x111;&#x1B0;&#x1EDD;ng d&#x1EAB;n.</li></ul><h2 id="3-t%E1%BA%A1o-route-%C4%91%E1%BB%99ng-v%E1%BB%9Bi-useparams"><strong>3. T&#x1EA1;o route &#x111;&#x1ED9;ng v&#x1EDB;i useParams</strong></h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-51.png" class="kg-image" alt="T&#x1EA1;o Chuy&#x1EC3;n Trang Trong ReactJS v&#x1EDB;i react-router, useHistory v&#xE0; useParams" loading="lazy" width="1400" height="689"></figure><p>V&#x1EDB;i route &#x111;&#x1ED9;ng, b&#x1EA1;n c&#xF3; th&#x1EC3; truy&#x1EC1;n tham s&#x1ED1; tr&#xEA;n URL nh&#x1B0; <code>/user/:id</code>. Hook <code>useParams</code> s&#x1EBD; gi&#xFA;p b&#x1EA1;n l&#x1EA5;y gi&#xE1; tr&#x1ECB; &#x111;&#xF3;.</p><p>V&#xED; d&#x1EE5;:</p><pre><code>import { useParams } from &apos;react-router-dom&apos;;

function UserDetail() {
  const { id } = useParams();
  return &lt;p&gt;Chi ti&#x1EBF;t ng&#x1B0;&#x1EDD;i d&#xF9;ng c&#xF3; ID: {id}&lt;/p&gt;;
}
</code></pre><p>URL <code>/user/123</code> s&#x1EBD; hi&#x1EC3;n th&#x1ECB; <code>Chi ti&#x1EBF;t ng&#x1B0;&#x1EDD;i d&#xF9;ng c&#xF3; ID: 123</code>.</p><h2 id="4-%C4%91i%E1%BB%81u-h%C6%B0%E1%BB%9Bng-th%E1%BB%A7-c%C3%B4ng-b%E1%BA%B1ng-usehistory"><strong>4. &#x110;i&#x1EC1;u h&#x1B0;&#x1EDB;ng th&#x1EE7; c&#xF4;ng b&#x1EB1;ng useHistory </strong></h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-52.png" class="kg-image" alt="T&#x1EA1;o Chuy&#x1EC3;n Trang Trong ReactJS v&#x1EDB;i react-router, useHistory v&#xE0; useParams" loading="lazy" width="1596" height="1038"></figure><p>Hook <code>useHistory</code> cung c&#x1EA5;p cho b&#x1EA1;n kh&#x1EA3; n&#x103;ng &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng th&#x1EE7; c&#xF4;ng trong code, v&#xED; d&#x1EE5; sau khi ng&#x1B0;&#x1EDD;i d&#xF9;ng nh&#x1EA5;n n&#xFA;t ho&#x1EB7;c ho&#xE0;n th&#xE0;nh form.</p><pre><code>import { useHistory } from &apos;react-router-dom&apos;;

function Login() {
  const history = useHistory();

  const handleLogin = () =&gt; {
    // X&#x1EED; l&#xFD; &#x111;&#x103;ng nh&#x1EAD;p
    history.push(&apos;/dashboard&apos;);
  };

  return &lt;button onClick={handleLogin}&gt;&#x110;&#x103;ng nh&#x1EAD;p&lt;/button&gt;;
}</code></pre><p>B&#x1EA1;n c&#xF3; th&#x1EC3; chuy&#x1EC3;n h&#x1B0;&#x1EDB;ng t&#x1EDB;i b&#x1EA5;t k&#x1EF3; route n&#xE0;o v&#x1EDB;i <code>history.push()</code>.</p><p>Nh&#x1B0; v&#x1EAD;y, <strong><a href="https://laptrinh-online.vn/courses/tat-ca-khoa-hoc">CodeFresher</a></strong> &#x111;&#xE3; chia s&#x1EBB; cho b&#x1EA1;n c&#xE1;ch s&#x1EED; d&#x1EE5;ng th&#x1B0; vi&#x1EC7;n <code>react-router-dom</code> &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng h&#x1EC7; th&#x1ED1;ng &#x111;&#x1ECB;nh tuy&#x1EBF;n cho &#x1EE9;ng d&#x1EE5;ng React. C&#xE1;c kh&#xE1;i ni&#x1EC7;m nh&#x1B0; kh&#x1EDF;i t&#x1EA1;o router, &#x111;&#x1ECB;nh ngh&#x129;a tuy&#x1EBF;n &#x111;&#x1B0;&#x1EDD;ng, t&#x1EA1;o li&#xEA;n k&#x1EBF;t &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng, s&#x1EED; d&#x1EE5;ng route &#x111;&#x1ED9;ng v&#xE0; khai th&#xE1;c c&#xE1;c hook nh&#x1B0; <code>useParams</code> v&#xE0; <code>useHistory</code> &#x111;&#x1EC1;u r&#x1EA5;t c&#x1EA7;n thi&#x1EBF;t khi x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng web hi&#x1EC7;n &#x111;&#x1EA1;i. Vi&#x1EC7;c th&#xE0;nh th&#x1EA1;o c&#xE1;c c&#xF4;ng c&#x1EE5; n&#xE0;y s&#x1EBD; gi&#xFA;p b&#x1EA1;n ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng React theo h&#x1B0;&#x1EDB;ng chuy&#xEA;n nghi&#x1EC7;p v&#xE0; hi&#x1EC7;u qu&#x1EA3; h&#x1A1;n.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/5Nx1M9Yt5wI?list=PLc1iBK01_excmSsQukvoQvg_Zb3tGjqzx" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>&#x110;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <a href="https://codefresher.vn/"><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> </a>&#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t th&#xF4;ng tin m&#x1EDB;i nh&#x1EA5;t v&#x1EC1; c&#xE1;c kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh!</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/courses/tat-ca-khoa-hoc">https://laptrinh-online.vn/courses/tat-ca-khoa-hoc</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Tối ưu hóa hiển thị danh sách lớn trong ReactJS với React-window và React-virtualized]]></title><description><![CDATA[Trong bài viết này, CodeFresher sẽ hướng dẫn bạn cách hiển thị danh sách cơ bản và tối ưu hiệu suất bằng cách sử dụng hai thư viện mạnh mẽ: React-window và React-virtualized.]]></description><link>https://laptrinh-online.vn/blog/untitled/</link><guid isPermaLink="false">6808b9b214958c001e7abc55</guid><category><![CDATA[React-virtualized]]></category><category><![CDATA[React-window]]></category><category><![CDATA[ReactJS]]></category><category><![CDATA[Lập trình với ReactJS]]></category><category><![CDATA[khóa học lập trình ReactJS]]></category><category><![CDATA[ứng dụng ReactJS]]></category><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Wed, 23 Apr 2025 10:16:30 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault-2.jpg" alt="T&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch l&#x1EDB;n trong ReactJS v&#x1EDB;i React-window v&#xE0; React-virtualized"><p>Trong qu&#xE1; tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n <a href="https://laptrinh-online.vn/course/lap-trinh-react-native"><strong>&#x1EE9;ng d&#x1EE5;ng ReactJS</strong></a> , c&#xF4;ng vi&#x1EC7;c x&#x1EED; l&#xFD; v&#xE0; hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch d&#x1EEF; li&#x1EC7;u l&#xE0; m&#x1ED9;t t&#xE1;c v&#x1EE5; r&#x1EA5;t ph&#x1ED5; bi&#x1EBF;n. Tuy nhi&#xEA;n, v&#x1EDB;i danh s&#xE1;ch c&#xF3; s&#x1ED1; l&#x1B0;&#x1EE3;ng ph&#x1EA7;n t&#x1EED; l&#x1EDB;n (h&#xE0;ng tr&#x103;m, h&#xE0;ng s&#x1EA3;n ph&#x1EA9;m), hi&#x1EC7;u su&#x1EA5;t xu&#x1EA5;t kh&#x1EA9;u s&#x1EBD; &#x111;&#x1B0;&#x1EE3;c hi&#x1EC3;n th&#x1ECB; ho&#xE0;n h&#x1EA3;o n&#x1EBF;u kh&#xF4;ng &#x111;&#x1B0;&#x1EE3;c t&#x1ED1;i &#x1B0;u h&#xF3;a.</p><p>Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, <a href="https://laptrinh-online.vn/"><strong>CodeFresher</strong></a> s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n b&#x1EA1;n c&#xE1;ch hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch c&#x1A1; b&#x1EA3;n v&#xE0; hi&#x1EC7;u su&#x1EA5;t t&#x1ED1;i &#x1B0;u b&#x1EB1;ng c&#xE1;ch s&#x1EED; d&#x1EE5;ng hai th&#x1B0; m&#x1EA1;nh m&#x1EBD;: React-window v&#xE0; React-virtualized.</p><h2 id="hi%E1%BB%83n-th%E1%BB%8B-danh-s%C3%A1ch-trong-reactjs"><strong>Hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch trong ReactJS</strong></h2><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-48.png" class="kg-image" alt="T&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch l&#x1EDB;n trong ReactJS v&#x1EDB;i React-window v&#xE0; React-virtualized" loading="lazy" width="928" height="390"></figure><p>ReactJS cung c&#x1EA5;p kh&#x1EA3; n&#x103;ng hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch th&#xF4;ng tin qua h&#xE0;m map(). &#x110;&#xE2;y l&#xE0; c&#xE1;ch ti&#x1EBF;p c&#x1EAD;n ph&#x1ED5; bi&#x1EBF;n v&#xE0; &#x111;&#x1A1;n gi&#x1EA3;n &#x111;&#x1EC3; hi&#x1EC3;n th&#x1ECB; nhi&#x1EC1;u ph&#x1EA7;n t&#x1EED; d&#x1EF1;a tr&#xEA;n m&#x1ED9;t d&#x1EEF; li&#x1EC7;u m&#x1EA3;ng.</p><pre><code>const data = [&apos;A&apos;, &apos;B&apos;, &apos;C&apos;];
return (
  &lt;ul&gt;
    {data.map((item, index) =&gt; (
      &lt;li key={index}&gt;{item}&lt;/li&gt;
    ))}
  &lt;/ul&gt;
);</code></pre><p>C&#xE1;ch n&#xE0;y ho&#x1EA1;t &#x111;&#x1ED9;ng t&#x1ED1;t v&#x1EDB;i danh s&#xE1;ch nh&#x1ECF;. Tuy nhi&#xEA;n, n&#x1EBF;u danh s&#xE1;ch l&#xEA;n &#x111;&#x1EBF;n h&#xE0;ng ng&#xE0;n m&#x1EE5;c, React ph&#x1EA3;i render to&#xE0;n b&#x1ED9; DOM c&#xE2;y. &#x110;i&#x1EC1;u n&#xE0;y g&#xE2;y &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n t&#x1ED1;c &#x111;&#x1ED9; t&#x1EA3;i v&#xE0; t&#x1B0;&#x1A1;ng t&#xE1;c.</p><h2 id="gi%E1%BB%9Bi-thi%E1%BB%87u-th%C6%B0-vi%E1%BB%87n-react-window-v%C3%A0-react-virtualized"><strong>Gi&#x1EDB;i thi&#x1EC7;u th&#x1B0; vi&#x1EC7;n React-window v&#xE0; React-virtualized</strong></h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-49.png" class="kg-image" alt="T&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch l&#x1EDB;n trong ReactJS v&#x1EDB;i React-window v&#xE0; React-virtualized" loading="lazy" width="1280" height="720"></figure><p>&#x110;&#x1EC3; gi&#x1EA3;i quy&#x1EBF;t v&#x1EA5;n &#x111;&#x1EC1; t&#xED;nh to&#xE1;n khi x&#x1EED; l&#xFD; danh s&#xE1;ch l&#x1EDB;n, b&#x1EA1;n n&#xEA;n s&#x1EED; d&#x1EE5;ng th&#x1B0; vi&#x1EC7;n h&#x1ED7; tr&#x1EE3; <strong>k&#x1EF9; thu&#x1EAD;t s&#x1ED1; k&#x1EF9; thu&#x1EAD;t cu&#x1ED9;n</strong> &#x2013; ch&#x1EC9; hi&#x1EC3;n th&#x1ECB; c&#xE1;c ph&#x1EA7;n t&#x1EED; &#x111;ang hi&#x1EC3;n th&#x1ECB; &#x1EDF; ch&#x1EBF; &#x111;&#x1ED9; xem ch&#x1EBF; &#x111;&#x1ED9;. Hai th&#x1B0; vi&#x1EC7;n ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t l&#xE0;:</p><h3 id="1-react-window"><strong>1. </strong>React-window</h3><p>&#x110;&#xE2;y l&#xE0; m&#x1ED9;t th&#x1B0; vi&#x1EC7;n th&#x1B0; gi&#xE3;n &#x111;&#x1B0;&#x1EE3;c ph&#xE1;t tri&#x1EC3;n b&#x1EDF;i ch&#xED;nh t&#xE1;c gi&#x1EA3; c&#x1EE7;a React-virtualized. React-window r&#x1EA5;t d&#x1EC5; s&#x1EED; d&#x1EE5;ng v&#xE0; ph&#xF9; h&#x1EE3;p v&#x1EDB;i h&#x1EA7;u h&#x1EBF;t c&#xE1;c use case hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch &#x111;&#x1A1;n gi&#x1EA3;n.</p><p>V&#xED; d&#x1EE5; s&#x1EED; d&#x1EE5;ng:</p><pre><code>import { FixedSizeList as List } from &apos;react-window&apos;;

const MyList = () =&gt; (
  &lt;List height={300} itemCount={1000} itemSize={35} width={300}&gt;
    {({ index, style }) =&gt; &lt;div style={style}&gt;Item {index}&lt;/div&gt;}
  &lt;/List&gt;
);</code></pre><p>Ch&#x1EC9; hi&#x1EC3;n th&#x1ECB; nh&#x1EEF;ng m&#x1EE5;c n&#xE0;y trong khung nh&#xEC;n m&#x1EDB;i &#x111;&#x1B0;&#x1EE3;c hi&#x1EC3;n th&#x1ECB;. &#x110;i&#x1EC1;u n&#xE0;y gi&#xFA;p &#x1EE9;ng d&#x1EE5;ng ho&#x1EA1;t &#x111;&#x1ED9;ng m&#x1B0;&#x1EE3;t m&#xE0; h&#x1A1;n &#x111;&#xE1;ng k&#x1EC3;.</p><h3 id="2-react-virtualized"><strong>2. </strong>React-virtualized</h3><p>&#x110;&#xE2;y l&#xE0; phi&#xEA;n b&#x1EA3;n &#x111;&#x1EA7;y &#x111;&#x1EE7; v&#xE0; linh ho&#x1EA1;t h&#x1A1;n. N&#xF3; h&#x1ED7; tr&#x1EE3; nhi&#x1EC1;u lo&#x1EA1;i d&#x1EEF; li&#x1EC7;u nh&#x1B0; Grid, Table v&#xE0; c&#xF3; nhi&#x1EC1;u t&#xF9;y ch&#x1ECD;n m&#x1EDF; r&#x1ED9;ng h&#x1A1;n React-window.</p><p>V&#xED; d&#x1EE5; s&#x1EED; d&#x1EE5;ng:</p><pre><code>import { List } from &apos;react-virtualized&apos;;

const rowRenderer = ({ index, key, style }) =&gt; (
  &lt;div key={key} style={style}&gt;Item {index}&lt;/div&gt;
);

const MyList = () =&gt; (
  &lt;List
    width={300}
    height={300}
    rowHeight={35}
    rowCount={1000}
    rowRenderer={rowRenderer}
  /&gt;
);</code></pre><p>D&#xF9; c&#xF3; ph&#x1EA7;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n, React-&#x1EA3;o h&#xF3;a l&#x1EA1;i c&#x1EF1;c k&#x1EF3; h&#x1EEF;u d&#x1EE5;ng trong c&#xE1;c d&#x1EF1; &#xE1;n l&#x1EDB;n, n&#x1A1;i c&#x1EA7;n ki&#x1EC3;m so&#xE1;t nhi&#x1EC1;u lo&#x1EA1;i danh s&#xE1;ch, b&#x1EA3;ng d&#x1EEF; li&#x1EC7;u c&#xF3; ti&#xEA;u &#x111;&#x1EC1; c&#x1ED1; &#x111;&#x1ECB;nh ho&#x1EB7;c nhi&#x1EC1;u c&#x1ED9;t.</p><h2 id="hi%E1%BB%83n-th%E1%BB%8B-c%C3%B3-%C4%91i%E1%BB%81u-ki%E1%BB%87n-%E2%80%93-hi%E1%BB%83n-th%E1%BB%8B-c%C3%B3-%C4%91i%E1%BB%81u-ki%E1%BB%87n"><strong>Hi&#x1EC3;n th&#x1ECB; c&#xF3; &#x111;i&#x1EC1;u ki&#x1EC7;n &#x2013; Hi&#x1EC3;n th&#x1ECB; c&#xF3; &#x111;i&#x1EC1;u ki&#x1EC7;n</strong></h2><p>Trong th&#x1EF1;c t&#x1EBF;, kh&#xF4;ng ph&#x1EA3;i l&#xFA;c n&#xE0;o b&#x1EA1;n c&#x169;ng hi&#x1EC3;n th&#x1ECB; to&#xE0;n b&#x1ED9; d&#x1EEF; li&#x1EC7;u. H&#x1ED7; tr&#x1EE3; h&#x1ED7; tr&#x1EE3; <strong>xu&#x1EA5;t</strong> &#x111;i&#x1EC1;u ki&#x1EC7;n React, cho ph&#xE9;p b&#x1EA1;n ki&#x1EC3;m so&#xE1;t hi&#x1EC3;n th&#x1ECB; th&#xF4;ng tin v&#x1EC1; logic &#x111;i&#x1EC1;u ki&#x1EC7;n.</p><p>V&#xED; d&#x1EE5;:</p><pre><code>{isLoading ? &lt;p&gt;&#x110;ang t&#x1EA3;i d&#x1EEF; li&#x1EC7;u...&lt;/p&gt; : &lt;ListComponent /&gt;}
</code></pre><p>K&#x1EBF;t h&#x1EE3;p v&#x1EDB;i cu&#x1ED9;n &#x1EA3;o, b&#x1EA1;n c&#xF3; th&#x1EC3; thi&#x1EBF;t l&#x1EAD;p hi&#x1EC7;u &#x1EE9;ng t&#x1EA3;i ho&#x1EB7;c l&#x1B0;&#x1EDD;i t&#x1EA3;i c&#x1EF1;c k&#x1EF3; hi&#x1EC7;u qu&#x1EA3;.</p><p>T&#xF3;m l&#x1EA1;i, vi&#x1EC7;c hi&#x1EC3;n th&#x1ECB; danh s&#xE1;ch l&#x1EDB;n trong <a href="https://codenhanh.vn/lap-trinh-web-reactjs-voi-chatgpt-copilot-full"><strong>ReactJS</strong></a> kh&#xF4;ng c&#xF2;n l&#xE0; v&#x1EA5;n &#x111;&#x1EC1; kh&#xF3; kh&#x103;n n&#x1EBF;u b&#x1EA1;n &#xE1;p d&#x1EE5;ng &#x111;&#xFA;ng k&#x1EF9; thu&#x1EAD;t. Vui l&#xF2;ng s&#x1EED; d&#x1EE5;ng th&#x1B0; vi&#x1EC7;n React-window ho&#x1EB7;c React-virtualized khi c&#x1EA7;n:</p><ul><li>&#x1AF;u ti&#xEA;n t&#x1ED1;i &#x111;a khi danh s&#xE1;ch d&#xE0;i.</li><li>Tr&#xE1;nh hi&#x1EC3;n th&#x1ECB; to&#xE0;n b&#x1ED9; DOM kh&#xF4;ng c&#x1EA7;n thi&#x1EBF;t.</li><li>C&#x1EA3;i thi&#x1EC7;n tr&#x1EA3;i nghi&#x1EC7;m ng&#x1B0;&#x1EDD;i d&#xF9;ng v&#x1EDB;i t&#x1ED1;c &#x111;&#x1ED9; m&#x1B0;&#x1EE3;t m&#xE0; h&#x1A1;n.</li></ul><p>B&#x1EA1;n n&#xEA;n b&#x1EAF;t &#x111;&#x1EA7;u v&#x1EDB;i React-window &#x111;&#x1EC3; l&#xE0;m quen v&#xE0; chuy&#x1EC3;n sang React-virtualized khi c&#x1EA7;n x&#x1EED; l&#xFD; ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n. Ngo&#xE0;i ra, h&#xE3;y xem c&#xE1;c plugin &#x111;&#x1B0;&#x1EE3;c cung c&#x1EA5;p &#x111;&#x1EC3; <strong>t&#x1EA1;o &#x111;i&#x1EC1;u ki&#x1EC7;n</strong> hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u theo m&#x1ED9;t c&#xE1;ch th&#xF4;ng tin, c&#xF3; Ki&#x1EC3;m so&#xE1;t.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/W2kUJyDN1Ro?list=PLc1iBK01_excmSsQukvoQvg_Zb3tGjqzx" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>&#x110;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <a href="https://codefresher.vn/"><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> </a>&#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t th&#xF4;ng tin m&#x1EDB;i nh&#x1EA5;t v&#x1EC1; c&#xE1;c kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh!</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/courses/tat-ca-khoa-hoc">https://laptrinh-online.vn/courses/tat-ca-khoa-hoc</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Lập trình app Flutter kết nối mạng HTTP với RestAPI, xử lý JSON data]]></title><description><![CDATA[<p>Trong th&#x1EBF; gi&#x1EDB;i ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng hi&#x1EC7;n &#x111;&#x1EA1;i, vi&#x1EC7;c k&#x1EBF;t n&#x1ED1;i v&#xE0; trao &#x111;&#x1ED5;i d&#x1EEF; li&#x1EC7;u gi&#x1EEF;a &#x1EE9;ng d&#x1EE5;</p>]]></description><link>https://laptrinh-online.vn/blog/lap-trinh-app-flutter-ket-noi-mang-http-voi-restapi-xu-ly-json-data/</link><guid isPermaLink="false">6807a78314958c001e7abba7</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Tue, 22 Apr 2025 14:58:25 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault-1.jpg" alt="L&#x1EAD;p tr&#xEC;nh app Flutter k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng HTTP v&#x1EDB;i RestAPI, x&#x1EED; l&#xFD; JSON data"><p>Trong th&#x1EBF; gi&#x1EDB;i ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng hi&#x1EC7;n &#x111;&#x1EA1;i, vi&#x1EC7;c k&#x1EBF;t n&#x1ED1;i v&#xE0; trao &#x111;&#x1ED5;i d&#x1EEF; li&#x1EC7;u gi&#x1EEF;a &#x1EE9;ng d&#x1EE5;ng v&#xE0; m&#xE1;y ch&#x1EE7; g&#x1EA7;n nh&#x1B0; l&#xE0; y&#xEA;u c&#x1EA7;u b&#x1EAF;t bu&#x1ED9;c. V&#x1EDB;i <strong><a href="https://codefresher.vn/flutter-co-the-lam-duoc-gi/">Flutter &#x2013; framework ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng m&#x1EA1;nh m&#x1EBD; c&#x1EE7;a Google</a></strong>, vi&#x1EC7;c t&#xED;ch h&#x1EE3;p m&#x1EA1;ng, g&#x1ECD;i API v&#xE0; x&#x1EED; l&#xFD; d&#x1EEF; li&#x1EC7;u JSON kh&#xF4;ng ch&#x1EC9; c&#x1EA7;n thi&#x1EBF;t m&#xE0; c&#xF2;n l&#xE0; b&#x1B0;&#x1EDB;c n&#x1EC1;n t&#x1EA3;ng &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng c&#xE1;c &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF;, t&#x1EEB; m&#x1EA1;ng x&#xE3; h&#x1ED9;i &#x111;&#x1EBF;n th&#x1B0;&#x1A1;ng m&#x1EA1;i &#x111;i&#x1EC7;n t&#x1EED;.</p><p>B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; h&#x1B0;&#x1EDB;ng d&#x1EAB;n chi ti&#x1EBF;t c&#xE1;ch <strong>k&#x1EBF;t n&#x1ED1;i HTTP, x&#x1EED; l&#xFD; JSON</strong> v&#xE0; t&#x1ED5; ch&#x1EE9;c code m&#x1ED9;t c&#xE1;ch chuy&#xEA;n nghi&#x1EC7;p, gi&#xFA;p b&#x1EA1;n l&#xE0;m ch&#x1EE7; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u m&#x1EA1;ng trong Flutter.</p><h2 id="1-t%E1%BB%95ng-quan-lu%E1%BB%93ng-k%E1%BA%BFt-n%E1%BB%91i-gi%E1%BB%AFa-flutter-v%C3%A0-api">1. T&#x1ED5;ng quan lu&#x1ED3;ng k&#x1EBF;t n&#x1ED1;i gi&#x1EEF;a Flutter v&#xE0; API</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-45.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh app Flutter k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng HTTP v&#x1EDB;i RestAPI, x&#x1EED; l&#xFD; JSON data" loading="lazy" width="1280" height="720"></figure><p>Khi &#x1EE9;ng d&#x1EE5;ng Flutter c&#x1EA7;n l&#x1EA5;y d&#x1EEF; li&#x1EC7;u t&#x1EEB; m&#xE1;y ch&#x1EE7; (server), quy tr&#xEC;nh c&#x1A1; b&#x1EA3;n s&#x1EBD; di&#x1EC5;n ra nh&#x1B0; sau:</p><ul><li>G&#x1EED;i m&#x1ED9;t y&#xEA;u c&#x1EA7;u (HTTP request) &#x111;&#x1EBF;n API.</li><li>Nh&#x1EAD;n l&#x1EA1;i ph&#x1EA3;n h&#x1ED3;i t&#x1EEB; m&#xE1;y ch&#x1EE7; d&#x1B0;&#x1EDB;i d&#x1EA1;ng JSON.</li><li>Gi&#x1EA3;i m&#xE3; d&#x1EEF; li&#x1EC7;u JSON th&#xE0;nh c&#xE1;c &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng Dart.</li><li>S&#x1EED; d&#x1EE5;ng d&#x1EEF; li&#x1EC7;u &#x111;&#xF3; &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t UI.</li></ul><p>V&#x1EDB;i Flutter, th&#x1B0; vi&#x1EC7;n <code>http</code> l&#xE0; l&#x1EF1;a ch&#x1ECD;n ph&#x1ED5; bi&#x1EBF;n &#x111;&#x1EC3; th&#x1EF1;c hi&#x1EC7;n c&#xE1;c thao t&#xE1;c HTTP m&#x1ED9;t c&#xE1;ch nhanh ch&#xF3;ng.</p><h2 id="2-th%C3%AAm-th%C6%B0-vi%E1%BB%87n-http">2. Th&#xEA;m th&#x1B0; vi&#x1EC7;n HTTP</h2><p>Th&#xEA;m v&#xE0;o <code>pubspec.yaml</code>:</p><p><code>dependencies: &#xA0;</code></p><p>&#x2003;&#x2003;<code>http: ^0.13.6</code></p><p>Sau &#x111;&#xF3;, ch&#x1EA1;y:</p><p>&#x2003;<code>flutter pub get</code></p><h2 id="3-g%E1%BB%ADi-http-request-v%C3%A0-nh%E1%BA%ADn-d%E1%BB%AF-li%E1%BB%87u">3. G&#x1EED;i HTTP Request v&#xE0; nh&#x1EAD;n d&#x1EEF; li&#x1EC7;u</h2><p>V&#xED; d&#x1EE5; g&#x1ECD;i &#x111;&#x1EBF;n API tr&#x1EA3; v&#x1EC1; danh s&#xE1;ch ng&#x1B0;&#x1EDD;i d&#xF9;ng:</p><p><code>import &apos;package:http/http.dart&apos; as http; </code></p><p><code>import &apos;dart:convert&apos;; </code></p><p><code>Future&lt;List&lt;User&gt;&gt; fetchUsers() async { </code></p><p> &#xA0; &#xA0; <code>final response = await http.get(Uri.parse(&apos;https://jsonplaceholder.typicode.com/users&apos;)); </code></p><p> &#xA0; &#xA0; <code>if (response.statusCode == 200) { </code></p><p> &#xA0; &#xA0; &#xA0; &#xA0;<code>final List&lt;dynamic&gt; jsonData = json.decode(response.body); </code></p><p> &#xA0; &#xA0; &#xA0; &#xA0;<code>return jsonData.map((item) =&gt; User.fromJson(item)).toList(); </code></p><p><code>} else { </code></p><p> &#xA0; &#xA0; &#xA0; &#xA0;<code>throw Exception(&apos;Failed to load users&apos;); </code></p><p>&#x2003;<code>} </code></p><p><code>}</code></p><h2 id="4-x%E1%BB%AD-l%C3%BD-json-v%C3%A0-t%E1%BA%A1o-model">4. X&#x1EED; l&#xFD; JSON v&#xE0; t&#x1EA1;o Model</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-46.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh app Flutter k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng HTTP v&#x1EDB;i RestAPI, x&#x1EED; l&#xFD; JSON data" loading="lazy" width="700" height="350"></figure><p>Khi d&#x1EEF; li&#x1EC7;u tr&#x1EA3; v&#x1EC1; t&#x1EEB; API l&#xE0; JSON, b&#x1EA1;n c&#x1EA7;n chuy&#x1EC3;n &#x111;&#x1ED5;i n&#xF3; th&#xE0;nh c&#xE1;c class Dart &#x111;&#x1EC3; d&#x1EC5; d&#xE0;ng s&#x1EED; d&#x1EE5;ng.</p><p>V&#xED; d&#x1EE5; v&#x1EDB;i d&#x1EEF; li&#x1EC7;u ng&#x1B0;&#x1EDD;i d&#xF9;ng:</p><p><code>{ &#xA0;</code></p><p>&#x2003;&#x2003;<code>&quot;id&quot;: 1, &#xA0;</code></p><p>&#x2003;&#x2003;<code>&quot;name&quot;: &quot;Leanne Graham&quot;, &#xA0;</code></p><p>&#x2003;&#x2003;<code>&quot;email&quot;: &quot;leanne@example.com&quot;</code></p><p><code>}</code></p><p>T&#x1EA1;o class <code>User</code>:</p><p><code>class User { </code></p><p>&#x2003;<code>final int id; </code></p><p>&#x2003;<code>final String name; </code></p><p>&#x2003;<code>final String email; </code></p><p><code>User({required this.id, required this.name, required this.email});</code></p><p><code>factory User.fromJson(Map&lt;String, dynamic&gt; json) { </code></p><p><code>return User( </code></p><p>&#x2003;&#x2003; &#xA0; <code>id: json[&apos;id&apos;],</code></p><p>&#x2003;&#x2003; &#xA0; <code>name: json[&apos;name&apos;],</code></p><p> &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;<code>email: json[&apos;email&apos;], </code></p><p>&#x2003;&#x2003;<code>); </code></p><p>&#x2003;<code>} </code></p><p><code>}</code></p><h2 id="5-hi%E1%BB%83n-th%E1%BB%8B-d%E1%BB%AF-li%E1%BB%87u-trong-ui">5. Hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u trong UI</h2><p>K&#x1EBF;t h&#x1EE3;p <code>FutureBuilder</code> &#x111;&#x1EC3; g&#x1ECD;i API v&#xE0; c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n:</p><p><code>class UserListScreen extends StatelessWidget { </code></p><p>&#x2003;<code>const UserListScreen({Key? key}) : super(key: key); </code></p><p><code>@override Widget build(BuildContext context) { </code></p><p><code>return Scaffold( </code></p><p>&#x2003;&#x2003;<code>appBar: AppBar(title: Text(&apos;Danh s&#xE1;ch ng&#x1B0;&#x1EDD;i d&#xF9;ng&apos;)),</code></p><p>&#x2003;&#x2003;<code>body: FutureBuilder&lt;List&lt;User&gt;&gt;( </code></p><p>&#x2003;&#x2003;&#x2003;<code>future: fetchUsers(), </code></p><p>&#x2003;&#x2003;&#x2003;<code>builder: (context, snapshot) { </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>if (snapshot.connectionState == ConnectionState.waiting) { </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>return Center(child: CircularProgressIndicator()); </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>} else if (snapshot.hasError) {</code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003; &#xA0; <code>return Center(child: Text(&apos;L&#x1ED7;i: ${snapshot.error}&apos;)); </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>} else if (!snapshot.hasData || snapshot.data!.isEmpty) {</code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003; &#xA0;<code>return Center(child: Text(&apos;Kh&#xF4;ng c&#xF3; d&#x1EEF; li&#x1EC7;u&apos;)); </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>} </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>final users = snapshot.data!; </code></p><p>&#x2003;&#x2003;&#x2003; &#xA0; &#xA0;<code>return ListView.builder( </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>itemCount: users.length, </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>itemBuilder: (context, index) { </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>final user = users[index]; </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>return ListTile( title: Text(user.name), </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>subtitle: Text(user.email), </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>); </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;&#x2003;<code>}, </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>); </code></p><p>&#x2003;&#x2003;&#x2003;&#x2003;<code>}, </code></p><p>&#x2003;&#x2003;&#x2003;<code>), </code></p><p>&#x2003;&#x2003;<code>); </code></p><p>&#x2003;<code>} </code></p><p><code>}</code></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/EThIka8oTm0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="L&#x1EAD;p tr&#xEC;nh app Flutter k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng http v&#x1EDB;i RestAPI, x&#x1EED; l&#xFD; JSON data"></iframe></figure><h2 id="6-l%E1%BB%9Di-khuy%C3%AAn-khi-x%E1%BB%AD-l%C3%BD-m%E1%BA%A1ng-trong-flutter">6. L&#x1EDD;i khuy&#xEA;n khi x&#x1EED; l&#xFD; m&#x1EA1;ng trong Flutter</h2><p><strong>T&#xE1;ch ri&#xEA;ng t&#x1EA7;ng d&#x1EEF; li&#x1EC7;u</strong>: S&#x1EED; d&#x1EE5;ng m&#xF4; h&#xEC;nh nh&#x1B0; <code>Repository</code> &#x111;&#x1EC3; qu&#x1EA3;n l&#xFD; g&#x1ECD;i API.</p><p><strong>S&#x1EED; d&#x1EE5;ng th&#x1B0; vi&#x1EC7;n nh&#x1B0; <code>Dio</code> khi d&#x1EF1; &#xE1;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n</strong>: H&#x1ED7; tr&#x1EE3; interceptor, logging, v&#xE0; token.</p><p><strong>X&#x1EED; l&#xFD; l&#x1ED7;i v&#xE0; timeout r&#xF5; r&#xE0;ng</strong>: Kh&#xF4;ng &#x111;&#x1EC3; &#x1EE9;ng d&#x1EE5;ng treo khi kh&#xF4;ng c&#xF3; internet.</p><p><strong>D&#xF9;ng <code>json_serializable</code> &#x111;&#x1EC3; t&#x1EF1; &#x111;&#x1ED9;ng ho&#xE1; vi&#x1EC7;c mapping JSON &#x2192; Dart</strong>.</p><h2 id="k%E1%BA%BFt-lu%E1%BA%ADn">K&#x1EBF;t lu&#x1EAD;n</h2><p>Vi&#x1EC7;c l&#xE0;m ch&#x1EE7; k&#x1EF9; thu&#x1EAD;t k&#x1EBF;t n&#x1ED1;i HTTP v&#xE0; x&#x1EED; l&#xFD; JSON l&#xE0; b&#x1B0;&#x1EDB;c chuy&#x1EC3;n m&#xEC;nh gi&#xFA;p b&#x1EA1;n t&#x1EEB; l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n c&#x1A1; b&#x1EA3;n sang x&#xE2;y d&#x1EF1;ng nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng Flutter chuy&#xEA;n nghi&#x1EC7;p, c&#xF3; th&#x1EC3; t&#xED;ch h&#x1EE3;p v&#x1EDB;i backend, API, v&#xE0; h&#x1EC7; th&#x1ED1;ng th&#x1EF1;c t&#x1EBF;.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang &#x1EDF; giai &#x111;o&#x1EA1;n mu&#x1ED1;n <strong><a href="https://codefresher.vn/can-chuan-bi-gi-de-hoc-lap-trinh-mobile-flutter/">&#x111;&#x1B0;a k&#x1EF9; n&#x103;ng Flutter l&#xEA;n c&#x1EA5;p &#x111;&#x1ED9; th&#x1EF1;c chi&#x1EBF;n</a></strong>, &#x111;&#xE2;y ch&#xED;nh l&#xE0; n&#x1ED9;i dung b&#x1EA1;n c&#x1EA7;n n&#x1EAF;m th&#x1EAD;t v&#x1EEF;ng. &#x110;&#x1EEB;ng ch&#x1EC9; d&#x1EEB;ng l&#x1EA1;i &#x1EDF; l&#xFD; thuy&#x1EBF;t &#x2013; h&#xE3;y th&#x1EF1;c h&#xE0;nh, vi&#x1EBF;t API ri&#xEA;ng, t&#x1EF1; x&#xE2;y d&#x1EF1;ng m&#xF4; h&#xEC;nh d&#x1EEF; li&#x1EC7;u, v&#xE0; &#x111;&#x1B0;a &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a b&#x1EA1;n ch&#x1EA1;m t&#x1EDB;i ng&#x1B0;&#x1EDD;i d&#xF9;ng th&#x1EAD;t.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-47.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh app Flutter k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng HTTP v&#x1EDB;i RestAPI, x&#x1EED; l&#xFD; JSON data" loading="lazy" width="1280" height="720"></figure><p>N&#x1EBF;u b&#x1EA1;n c&#x1EA3;m th&#x1EA5;y b&#xE0;i vi&#x1EBF;t n&#xE0;y gi&#xFA;p b&#x1EA1;n hi&#x1EC3;u s&#xE2;u h&#x1A1;n v&#x1EC1; k&#x1EBF;t n&#x1ED1;i m&#x1EA1;ng trong Flutter, th&#xEC; ch&#x1B0;&#x1A1;ng tr&#xEC;nh kho&#xE1; h&#x1ECD;c &quot;<strong><em><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">L&#x1EAD;p tr&#xEC;nh Flutter to&#xE0;n t&#x1EAD;p</a></em></strong>&quot; chuy&#xEA;n s&#xE2;u &#x111;ang ch&#x1EDD; b&#x1EA1;n v&#x1EDB;i c&#xE1;c n&#x1ED9;i dung:</p><ul><li>G&#x1ECD;i API ph&#x1EE9;c t&#x1EA1;p c&#xF3; token, refresh token</li><li>Pagination, filter, upload file</li><li>T&#xED;ch h&#x1EE3;p m&#x1EA1;ng v&#xE0;o state management nh&#x1B0; Bloc ho&#x1EB7;c Riverpod</li><li>Ki&#x1EBF;n tr&#xFA;c clean v&#xE0; chuy&#xEA;n nghi&#x1EC7;p cho &#x1EE9;ng d&#x1EE5;ng Flutter k&#x1EBF;t n&#x1ED1;i backend</li></ul><p> <strong>B&#x1EA1;n h&#x1ECD;c &#x111;&#x1EC3; l&#xE0;m ra s&#x1EA3;n ph&#x1EA9;m, kh&#xF4;ng ch&#x1EC9; &#x111;&#x1EC3; hi&#x1EC3;u l&#xFD; thuy&#x1EBF;t.</strong></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <a href="https://codefresher.vn/"><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></a> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Thực hành xây dựng app chat thời gian thực bằng Flutter và Socket.IO]]></title><description><![CDATA[<h2 id="giao-ti%E1%BA%BFp-th%E1%BB%9Di-gian-th%E1%BB%B1c-kh%C3%B4ng-c%C3%B2n-l%C3%A0-%C4%91%E1%BA%B7c-quy%E1%BB%81n-c%E1%BB%A7a-c%C3%A1c-%E1%BB%A9ng-d%E1%BB%A5ng-l%E1%BB%9Bn">Giao ti&#x1EBF;p th&#x1EDD;i gian th&#x1EF1;c kh&#xF4;ng c&#xF2;n l&#xE0; &#x111;&#x1EB7;c quy&#x1EC1;n c&#x1EE7;a c&#xE1;c &#x1EE9;ng d&#x1EE5;ng l&#x1EDB;n</h2><p>N&#x1EBF;u nh&#x1B0; tr&#x1B0;&#x1EDB;c &#x111;&#xE2;</p>]]></description><link>https://laptrinh-online.vn/blog/thuc-hanh-code-app-chat-thoi-gian-thuc-bang-socket-io/</link><guid isPermaLink="false">6806557f14958c001e7abb41</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Mon, 21 Apr 2025 14:58:45 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/1_sOwp2pYcteussE9gV7LX5A.png" medium="image"/><content:encoded><![CDATA[<h2 id="giao-ti%E1%BA%BFp-th%E1%BB%9Di-gian-th%E1%BB%B1c-kh%C3%B4ng-c%C3%B2n-l%C3%A0-%C4%91%E1%BA%B7c-quy%E1%BB%81n-c%E1%BB%A7a-c%C3%A1c-%E1%BB%A9ng-d%E1%BB%A5ng-l%E1%BB%9Bn">Giao ti&#x1EBF;p th&#x1EDD;i gian th&#x1EF1;c kh&#xF4;ng c&#xF2;n l&#xE0; &#x111;&#x1EB7;c quy&#x1EC1;n c&#x1EE7;a c&#xE1;c &#x1EE9;ng d&#x1EE5;ng l&#x1EDB;n</h2><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/1_sOwp2pYcteussE9gV7LX5A.png" alt="Th&#x1EF1;c h&#xE0;nh x&#xE2;y d&#x1EF1;ng app chat th&#x1EDD;i gian th&#x1EF1;c b&#x1EB1;ng Flutter v&#xE0; Socket.IO"><p>N&#x1EBF;u nh&#x1B0; tr&#x1B0;&#x1EDB;c &#x111;&#xE2;y c&#xE1;c &#x1EE9;ng d&#x1EE5;ng nh&#x1B0; Messenger, Zalo, ho&#x1EB7;c Slack s&#x1EDF; h&#x1EEF;u h&#x1EA1; t&#x1EA7;ng real-time ph&#x1EE9;c t&#x1EA1;p, th&#xEC; ng&#xE0;y nay, <strong>b&#x1EA1;n ho&#xE0;n to&#xE0;n c&#xF3; th&#x1EC3; x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng chat c&#x1EE7;a ri&#xEA;ng m&#xEC;nh</strong> b&#x1EB1;ng nh&#x1EEF;ng c&#xF4;ng ngh&#x1EC7; m&#x1EDF; nh&#x1B0; <strong>Flutter</strong> v&#xE0; <strong>Socket.IO</strong>.</p><p>&#x110;i&#x1EC1;u quan tr&#x1ECD;ng l&#xE0;: <strong><a href="https://codefresher.vn/thuc-hanh-code-app-chat-su-dung-thu-vien-socket-io-trong-lap-trinh-flutter/">hi&#x1EC3;u &#x111;&#xFA;ng b&#x1EA3;n ch&#x1EA5;t k&#x1EF9; thu&#x1EAD;t</a></strong> v&#xE0; <strong>bi&#x1EBF;t th&#x1EF1;c h&#xE0;nh &#x111;&#xFA;ng c&#xE1;ch</strong>.</p><h2 id="1-real-time-communication-l%C3%A0-g%C3%AC">1. Real-time Communication l&#xE0; g&#xEC;?</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-41.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh x&#xE2;y d&#x1EF1;ng app chat th&#x1EDD;i gian th&#x1EF1;c b&#x1EB1;ng Flutter v&#xE0; Socket.IO" loading="lazy" width="1920" height="1080"></figure><p><strong>Real-time Communication</strong> (giao ti&#x1EBF;p th&#x1EDD;i gian th&#x1EF1;c) l&#xE0; h&#xEC;nh th&#x1EE9;c giao ti&#x1EBF;p m&#xE0; d&#x1EEF; li&#x1EC7;u &#x111;&#x1B0;&#x1EE3;c truy&#x1EC1;n &#x111;i ngay l&#x1EAD;p t&#x1EE9;c khi ph&#xE1;t sinh s&#x1EF1; ki&#x1EC7;n. Kh&#xF4;ng c&#x1EA7;n &#x111;&#x1EE3;i ng&#x1B0;&#x1EDD;i d&#xF9;ng refresh, kh&#xF4;ng c&#x1EA7;n polling li&#xEA;n t&#x1EE5;c t&#x1EEB; client.</p><p>Trong c&#xE1;c &#x1EE9;ng d&#x1EE5;ng mobile, &#x111;i&#x1EC1;u n&#xE0;y th&#x1B0;&#x1EDD;ng th&#x1EC3; hi&#x1EC7;n qua:</p><ul><li>Tin nh&#x1EAF;n &#x111;&#x1EBF;n hi&#x1EC7;n ngay tr&#xEA;n UI</li><li>Tr&#x1EA1;ng th&#xE1;i &quot;&#x111;ang nh&#x1EAD;p...&quot; ho&#x1EB7;c &quot;online&quot;</li><li>Th&#xF4;ng b&#xE1;o b&#xEC;nh lu&#x1EAD;n, th&#x1EA3; tim t&#x1EE9;c th&#xEC;</li></ul><p>C&#x1ED1;t l&#xF5;i c&#x1EE7;a n&#xF3; l&#xE0; <strong>m&#x1ED9;t k&#x1EBF;t n&#x1ED1;i socket lu&#xF4;n m&#x1EDF; gi&#x1EEF;a client v&#xE0; server</strong>, cho ph&#xE9;p hai b&#xEA;n g&#x1EED;i d&#x1EEF; li&#x1EC7;u b&#x1EA5;t c&#x1EE9; l&#xFA;c n&#xE0;o.</p><h2 id="2-websocket-v%C3%A0-socketio-s%E1%BB%B1-kh%C3%A1c-bi%E1%BB%87t-v%C3%A0-m%E1%BB%91i-li%C3%AAn-h%E1%BB%87">2. WebSocket v&#xE0; Socket.IO: S&#x1EF1; kh&#xE1;c bi&#x1EC7;t v&#xE0; m&#x1ED1;i li&#xEA;n h&#x1EC7;</h2><h3 id="websocket">WebSocket</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-42.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh x&#xE2;y d&#x1EF1;ng app chat th&#x1EDD;i gian th&#x1EF1;c b&#x1EB1;ng Flutter v&#xE0; Socket.IO" loading="lazy" width="663" height="454"></figure><p>L&#xE0; <strong>giao th&#x1EE9;c m&#x1EA1;ng</strong> &#x1EDF; t&#x1EA7;ng th&#x1EA5;p h&#x1A1;n, cho ph&#xE9;p thi&#x1EBF;t l&#x1EAD;p k&#x1EBF;t n&#x1ED1;i TCP hai chi&#x1EC1;u gi&#x1EEF;a client v&#xE0; server. Sau khi k&#x1EBF;t n&#x1ED1;i &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t l&#x1EAD;p, hai b&#xEA;n c&#xF3; th&#x1EC3; trao &#x111;&#x1ED5;i d&#x1EEF; li&#x1EC7;u m&#xE0; kh&#xF4;ng c&#x1EA7;n request l&#x1EA1;i.</p><p>&#x1AF;u &#x111;i&#x1EC3;m:</p><ul><li>G&#x1ECD;n nh&#x1EB9;</li><li>Hi&#x1EC7;u su&#x1EA5;t cao</li></ul><p>Nh&#x1B0;&#x1EE3;c &#x111;i&#x1EC3;m:</p><ul><li>Ph&#x1EA3;i t&#x1EF1; x&#x1EED; l&#xFD; c&#xE1;c v&#x1EA5;n &#x111;&#x1EC1; nh&#x1B0; reconnect, fallback, heartbeat</li></ul><h3 id="socketio">Socket.IO</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-44.png" class="kg-image" alt="Th&#x1EF1;c h&#xE0;nh x&#xE2;y d&#x1EF1;ng app chat th&#x1EDD;i gian th&#x1EF1;c b&#x1EB1;ng Flutter v&#xE0; Socket.IO" loading="lazy" width="1400" height="1060"></figure><p>L&#xE0; <strong>th&#x1B0; vi&#x1EC7;n JavaScript m&#xE3; ngu&#x1ED3;n m&#x1EDF;</strong> &#x111;&#x1B0;&#x1EE3;c x&#xE2;y d&#x1EF1;ng tr&#xEA;n WebSocket, cung c&#x1EA5;p th&#xEA;m nhi&#x1EC1;u t&#xED;nh n&#x103;ng ti&#x1EC7;n l&#x1EE3;i:</p><ul><li>T&#x1EF1; &#x111;&#x1ED9;ng reconnect</li><li>Event-driven API (emit/on)</li><li>Fallback qua polling n&#x1EBF;u WebSocket kh&#xF4;ng kh&#x1EA3; d&#x1EE5;ng</li><li>H&#x1ED7; tr&#x1EE3; room, namespace</li></ul><p><strong>Socket.IO = WebSocket + ti&#x1EC7;n &#xED;ch + b&#x1EA3;o tr&#xEC; d&#x1EC5; d&#xE0;ng</strong></p><h2 id="3-flutter-socketio-app-chat-m%E1%BA%A1nh-m%E1%BA%BD-hi%E1%BB%87u-qu%E1%BA%A3">3. Flutter + Socket.IO = App chat m&#x1EA1;nh m&#x1EBD; &amp; hi&#x1EC7;u qu&#x1EA3;</h2><p>Flutter v&#x1ED1;n n&#x1ED5;i ti&#x1EBF;ng v&#x1EDB;i kh&#x1EA3; n&#x103;ng x&#xE2;y d&#x1EF1;ng UI linh ho&#x1EA1;t v&#xE0; hi&#x1EC7;u su&#x1EA5;t cao. Khi k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i Socket.IO, b&#x1EA1;n s&#x1EBD; c&#xF3; th&#x1EC3;:</p><ul><li>X&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n chat t&#x1B0;&#x1A1;ng t&#xE1;c cao</li><li>L&#x1EAF;ng nghe v&#xE0; hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u ngay khi nh&#x1EAD;n &#x111;&#x1B0;&#x1EE3;c</li><li>T&#x1ED5; ch&#x1EE9;c code theo ki&#x1EBF;n tr&#xFA;c clean v&#xE0; m&#x1EDF; r&#x1ED9;ng</li></ul><h2 id="4-nh%E1%BB%AFng-ki%E1%BA%BFn-th%E1%BB%A9c-b%E1%BA%A1n-s%E1%BA%BD-h%E1%BB%8Dc-%C4%91%C6%B0%E1%BB%A3c-trong-qu%C3%A1-tr%C3%ACnh-th%E1%BB%B1c-h%C3%A0nh">4. Nh&#x1EEF;ng ki&#x1EBF;n th&#x1EE9;c b&#x1EA1;n s&#x1EBD; h&#x1ECD;c &#x111;&#x1B0;&#x1EE3;c trong qu&#xE1; tr&#xEC;nh th&#x1EF1;c h&#xE0;nh</h2><p>&#x110;&#xE2;y kh&#xF4;ng ch&#x1EC9; l&#xE0; m&#x1ED9;t app demo &#x2013; n&#xF3; l&#xE0; &#x111;i&#x1EC3;m kh&#x1EDF;i &#x111;&#x1EA7;u cho h&#x1EC7; th&#x1ED1;ng real-time th&#x1EF1;c th&#x1EE5;. D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; <strong>c&#xE1;c ki&#x1EBF;n th&#x1EE9;c b&#x1EA1;n s&#x1EBD; n&#x1EAF;m &#x111;&#x1B0;&#x1EE3;c</strong> n&#x1EBF;u &#x111;i theo h&#x1B0;&#x1EDB;ng n&#xE0;y:</p><h3 id="41-ki%E1%BA%BFn-th%E1%BB%A9c-v%E1%BB%81-flutter">4.1. Ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; Flutter</h3><ul><li>T&#x1EA1;o v&#xE0; qu&#x1EA3;n l&#xFD; <code>StatefulWidget</code></li><li>Giao ti&#x1EBF;p v&#x1EDB;i server th&#xF4;ng qua socket</li><li>X&#xE2;y d&#x1EF1;ng UI &#x111;&#x1ED9;ng v&#x1EDB;i <code>ListView.builder</code></li><li>Qu&#x1EA3;n l&#xFD; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u v&#x1EDB;i <code>Stream</code>, <code>setState</code>, ho&#x1EB7;c <code>Provider</code> (tu&#x1EF3; tr&#xEC;nh &#x111;&#x1ED9;)</li><li>X&#x1EED; l&#xFD; b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9; (async/await) v&#xE0; s&#x1EF1; ki&#x1EC7;n</li></ul><h3 id="42-ki%E1%BA%BFn-th%E1%BB%A9c-v%E1%BB%81-backend-real-time-nodejs">4.2. Ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; Backend real-time (Node.js)</h3><ul><li>T&#x1EA1;o server v&#x1EDB;i Express</li><li>T&#xED;ch h&#x1EE3;p Socket.IO &#x111;&#x1EC3; x&#x1EED; l&#xFD; k&#x1EBF;t n&#x1ED1;i</li><li>Qu&#x1EA3;n l&#xFD; nhi&#x1EC1;u client c&#xF9;ng l&#xFA;c (broadcast, room)</li><li>Thi&#x1EBF;t k&#x1EBF; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u realtime (emit t&#x1EEB; client &#x2192; server &#x2192; c&#xE1;c client kh&#xE1;c)</li><li>Debug lu&#x1ED3;ng socket hi&#x1EC7;u qu&#x1EA3;</li></ul><h3 id="43-k%E1%BB%B9-n%C4%83ng-k%E1%BB%B9-thu%E1%BA%ADt-t%E1%BB%95ng-h%E1%BB%A3p">4.3. K&#x1EF9; n&#x103;ng k&#x1EF9; thu&#x1EAD;t t&#x1ED5;ng h&#x1EE3;p</h3><ul><li>Giao ti&#x1EBF;p hai chi&#x1EC1;u gi&#x1EEF;a server-client</li><li>Qu&#x1EA3;n l&#xFD; session v&#xE0; socket id</li><li>X&#x1EED; l&#xFD; reconnect t&#x1EF1; &#x111;&#x1ED9;ng</li><li>Ph&#xE2;n t&#xED;ch g&#xF3;i tin v&#xE0; &#x111;&#x1ECB;nh d&#x1EA1;ng JSON</li><li>Thi&#x1EBF;t k&#x1EBF; ki&#x1EBF;n tr&#xFA;c d&#x1EC5; m&#x1EDF; r&#x1ED9;ng</li></ul><h2 id="5-d%E1%BB%B1-%C3%A1n-th%E1%BB%B1c-t%E1%BA%BF-chat-app-%C4%91%C6%A1n-gi%E1%BA%A3n-n%E1%BB%81n-t%E1%BA%A3ng-v%E1%BB%AFng-ch%E1%BA%AFc">5. D&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF;: Chat app &#x111;&#x1A1;n gi&#x1EA3;n, n&#x1EC1;n t&#x1EA3;ng v&#x1EEF;ng ch&#x1EAF;c</h2><p>Trong ph&#x1EA7;n th&#x1EF1;c h&#xE0;nh, b&#x1EA1;n s&#x1EBD;:</p><ul><li>T&#x1EA1;o m&#x1ED9;t server Node.js d&#xF9;ng Socket.IO</li><li>T&#x1EA1;o app Flutter k&#x1EBF;t n&#x1ED1;i v&#xE0; giao ti&#x1EBF;p qua socket</li><li>G&#x1EED;i v&#xE0; nh&#x1EAD;n tin nh&#x1EAF;n theo th&#x1EDD;i gian th&#x1EF1;c</li><li>C&#x1EAD;p nh&#x1EAD;t UI ngay khi c&#xF3; tin m&#x1EDB;i</li><li>Tri&#x1EC3;n khai server c&#x1EE5;c b&#x1ED9;, v&#xE0; m&#x1EDF; r&#x1ED9;ng l&#xEA;n cloud</li></ul><p>Sau khi ho&#xE0;n th&#xE0;nh, b&#x1EA1;n c&#xF3; th&#x1EC3; m&#x1EDF; r&#x1ED9;ng ra chat nh&#xF3;m, chia room, hi&#x1EC3;n th&#x1ECB; ng&#x1B0;&#x1EDD;i d&#xF9;ng &#x111;ang online, ho&#x1EB7;c l&#x1B0;u tr&#x1EEF; tin nh&#x1EAF;n trong Firebase/MongoDB.</p><h2 id="6-t%E1%BB%AB-demo-%C4%91%E1%BA%BFn-s%E1%BA%A3n-ph%E1%BA%A9m-th%E1%BB%B1c-chi%E1%BA%BFn-%E2%80%93-l%E1%BB%99-tr%C3%ACnh-b%E1%BA%A1n-n%C3%AAn-%C4%91i">6. T&#x1EEB; demo &#x111;&#x1EBF;n s&#x1EA3;n ph&#x1EA9;m th&#x1EF1;c chi&#x1EBF;n &#x2013; L&#x1ED9; tr&#xEC;nh b&#x1EA1;n n&#xEA;n &#x111;i</h2><p>M&#x1ED9;t app chat &#x111;&#x1A1;n gi&#x1EA3;n s&#x1EBD; gi&#xFA;p b&#x1EA1;n hi&#x1EC3;u nguy&#xEA;n l&#xFD;. Nh&#x1B0;ng &#x111;&#x1EC3; th&#x1EF1;c s&#x1EF1; &#xE1;p d&#x1EE5;ng v&#xE0;o d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF;, b&#x1EA1;n c&#x1EA7;n &#x111;i xa h&#x1A1;n:</p><!--kg-card-begin: html--><table class="min-w-full" data-start="3928" data-end="4273"><thead data-start="3928" data-end="3973"><tr data-start="3928" data-end="3973"><th data-start="3928" data-end="3940">Giai &#x111;o&#x1EA1;n</th><th data-start="3940" data-end="3960">M&#x1EE5;c ti&#xEA;u k&#x1EF9; thu&#x1EAD;t</th><th data-start="3960" data-end="3973">C&#xF4;ng ngh&#x1EC7;</th></tr></thead><tbody data-start="4018" data-end="4273"><tr data-start="4018" data-end="4070"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4018" data-end="4027">C&#x1A1; b&#x1EA3;n</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4027" data-end="4047">G&#x1EED;i/nh&#x1EAD;n tin nh&#x1EAF;n</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4047" data-end="4070">Flutter + Socket.IO</td></tr><tr data-start="4071" data-end="4135"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4071" data-end="4083">Trung c&#x1EA5;p</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4083" data-end="4108">Room, nickname, status</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4108" data-end="4135">Flutter, Socket.IO, JWT</td></tr><tr data-start="4136" data-end="4201"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4136" data-end="4147">N&#xE2;ng cao</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4147" data-end="4173">L&#x1B0;u l&#x1ECB;ch s&#x1EED;, ph&#xE2;n quy&#x1EC1;n</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4173" data-end="4201">Firebase, MongoDB, Redis</td></tr><tr data-start="4202" data-end="4273"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4202" data-end="4215">Production</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4215" data-end="4242">B&#x1EA3;o m&#x1EAD;t, m&#x1EDF; r&#x1ED9;ng, t&#x1ED1;i &#x1B0;u</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4242" data-end="4273">NGINX, Docker, Cloud Deploy</td></tr></tbody></table><!--kg-card-end: html--><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/hTIN5vvaJyI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="L&#x1EAD;p tr&#xEC;nh app Flutter - Th&#x1EF1;c h&#xE0;nh code app chat s&#x1EED; d&#x1EE5;ng th&#x1B0; vi&#x1EC7;n SocketIO"></iframe></figure><h2 id="7-kho%C3%A1-h%E1%BB%8Dc-flutter-t%E1%BA%A1i-codefresher-%E2%80%93-gi%C3%BAp-b%E1%BA%A1n-%C4%91i-nhanh-v%C3%A0-v%E1%BB%AFng-ch%E1%BA%AFc">7. <a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">Kho&#xE1; h&#x1ECD;c Flutter t&#x1EA1;i CodeFresher</a> &#x2013; Gi&#xFA;p b&#x1EA1;n &#x111;i nhanh v&#xE0; v&#x1EEF;ng ch&#x1EAF;c</h2><p>Vi&#x1EC7;c t&#x1EF1; h&#x1ECD;c mang l&#x1EA1;i tr&#x1EA3;i nghi&#x1EC7;m t&#x1ED1;t, nh&#x1B0;ng <strong>&#x111;i nhanh h&#x1A1;n, &#x111;&#xFA;ng h&#x1B0;&#x1EDB;ng h&#x1A1;n</strong> l&#xE0; &#x111;i&#x1EC1;u c&#x1EA7;n thi&#x1EBF;t n&#x1EBF;u b&#x1EA1;n mu&#x1ED1;n:</p><ul><li>Tham gia d&#x1EF1; &#xE1;n real-time ngo&#xE0;i &#x111;&#x1EDD;i</li><li>L&#xE0;m ch&#x1EE7; k&#x1EF9; thu&#x1EAD;t realtime &#x111;&#x1EC3; &#x1EE9;ng d&#x1EE5;ng v&#xE0;o app c&#x1EE7;a m&#xEC;nh</li><li>T&#x1EF1; tin build s&#x1EA3;n ph&#x1EA9;m ho&#xE0;n ch&#x1EC9;nh v&#xE0; th&#x1B0;&#x1A1;ng m&#x1EA1;i ho&#xE1;</li></ul><h3 id="trong-kho%C3%A1-h%E1%BB%8Dc-%E2%80%9Cl%E1%BA%ADp-tr%C3%ACnh-flutter-to%C3%A0n-t%E1%BA%ADp%E2%80%9D-t%E1%BA%A1i-codefresher-b%E1%BA%A1n-s%E1%BA%BD">Trong kho&#xE1; h&#x1ECD;c &#x201C;L&#x1EAD;p tr&#xEC;nh Flutter to&#xE0;n t&#x1EAD;p&#x201D; t&#x1EA1;i CodeFresher, b&#x1EA1;n s&#x1EBD;:</h3><ul><li>X&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng chat v&#x1EDB;i lu&#x1ED3;ng realtime chu&#x1EA9;n c&#xF4;ng nghi&#x1EC7;p</li><li>Qu&#x1EA3;n l&#xFD; state n&#xE2;ng cao v&#x1EDB;i Provider ho&#x1EB7;c Riverpod</li><li>Hi&#x1EC3;u r&#xF5; c&#xE1;ch Flutter t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i WebSocket v&#xE0; c&#xE1;c lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u</li><li>Tri&#x1EC3;n khai server realtime v&#x1EDB;i Node.js/Socket.IO c&#xF3; c&#x1EA5;u tr&#xFA;c chuy&#xEA;n nghi&#x1EC7;p</li><li>&#x110;&#x1B0;&#x1EE3;c h&#x1B0;&#x1EDB;ng d&#x1EAB;n m&#x1EDF; r&#x1ED9;ng th&#xE0;nh app production-ready</li></ul><p>B&#x1EA1;n kh&#xF4;ng ch&#x1EC9; h&#x1ECD;c c&#xE1;ch &#x201C;l&#xE0;m cho ch&#x1EA1;y&#x201D;, m&#xE0; c&#xF2;n hi&#x1EC3;u t&#x1EA1;i sao n&#xF3; ho&#x1EA1;t &#x111;&#x1ED9;ng &#x2013; v&#xE0; l&#xE0;m sao &#x111;&#x1EC3; <strong>&#x111;i&#x1EC1;u ch&#x1EC9;nh v&#xE0; ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng theo m&#x1EE5;c ti&#xEA;u th&#x1EF1;c t&#x1EBF;</strong>.</p><h2 id="8-h%E1%BB%8Dc-c%C3%B4ng-ngh%E1%BB%87-%C4%91%E1%BB%83-l%C3%A0m-%C4%91%C6%B0%E1%BB%A3c-s%E1%BA%A3n-ph%E1%BA%A9m-th%E1%BA%ADt">8. H&#x1ECD;c c&#xF4;ng ngh&#x1EC7; &#x111;&#x1EC3; l&#xE0;m &#x111;&#x1B0;&#x1EE3;c s&#x1EA3;n ph&#x1EA9;m th&#x1EAD;t</h2><p>Socket.IO v&#xE0; Flutter kh&#xF4;ng ch&#x1EC9; l&#xE0; hai c&#xF4;ng c&#x1EE5;, m&#xE0; l&#xE0; <strong>hai n&#x1EC1;n t&#x1EA3;ng m&#x1EDF; ra c&#x1A1; h&#x1ED9;i l&#xE0;m &#x1EE9;ng d&#x1EE5;ng ch&#x1EA5;t l&#x1B0;&#x1EE3;ng cao, t&#x1B0;&#x1A1;ng t&#xE1;c th&#x1EDD;i gian th&#x1EF1;c</strong>, th&#x1EE9; &#x111;ang ng&#xE0;y c&#xE0;ng ph&#x1ED5; bi&#x1EBF;n trong m&#x1ECD;i ng&#xE0;nh ngh&#x1EC1;.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang mu&#x1ED1;n h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh mobile v&#xE0; mu&#x1ED1;n n&#x1ED5;i b&#x1EAD;t v&#x1EDB;i k&#x1EF9; n&#x103;ng real-time, <strong>&#x111;&#xE2;y l&#xE0; l&#xFA;c b&#x1EA1;n b&#x1EAF;t &#x111;&#x1EA7;u nghi&#xEA;m t&#xFA;c</strong>.</p><p><strong>&#x1F449; &#x110;&#x103;ng k&#xFD; ngay kho&#xE1; h&#x1ECD;c &quot; </strong>L&#x1EAD;p tr&#xEC;nh Flutter to&#xE0;n t&#x1EAD;p&quot; <strong> &#x2013; Flutter &amp; Real-time App chuy&#xEA;n s&#xE2;u</strong></p><ul><li>H&#x1ECD;c qua d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF;</li><li>&#x110;&#x1B0;&#x1EE3;c h&#x1B0;&#x1EDB;ng d&#x1EAB;n 1-1 t&#x1EEB; mentor</li><li>C&#xF3; s&#x1EA3;n ph&#x1EA9;m ho&#xE0;n ch&#x1EC9;nh sau kho&#xE1; h&#x1ECD;c</li><li>H&#x1ED7; tr&#x1EE3; k&#x1EF9; thu&#x1EAD;t trong v&#xE0; sau kho&#xE1; h&#x1ECD;c</li></ul><p> <strong>B&#x1EA1;n h&#x1ECD;c &#x111;&#x1EC3; l&#xE0;m ra s&#x1EA3;n ph&#x1EA9;m, kh&#xF4;ng ch&#x1EC9; &#x111;&#x1EC3; hi&#x1EC3;u l&#xFD; thuy&#x1EBF;t.</strong></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <a href="https://codefresher.vn/"><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></a> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Chuyển đổi từ Java sang Kotlin trong Android: Tích hợp Kotlin, Convert file và những điều cần biết]]></title><description><![CDATA[Kể từ khi Kotlin trở thành ngôn ngữ chính thức cho lập trình Android (được Google công bố năm 2017), hàng loạt dự án Java truyền thống đã bắt đầu chuyển sang Kotlin để tận dụng cú pháp ngắn gọn, khả năng xử lý null an toàn, cũng như hỗ trợ lập trình hàm mạnh mẽ.]]></description><link>https://laptrinh-online.vn/blog/chuyen-doi-tu-java-sang-kotlin-trong-android-tich-hop-kotlin-convert-file-va-nhung-dieu-can-biet/</link><guid isPermaLink="false">6802763314958c001e7abac1</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Fri, 18 Apr 2025 16:51:09 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/maxresdefault.jpg" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t"><p>K&#x1EC3; t&#x1EEB; khi Kotlin tr&#x1EDF; th&#xE0;nh ng&#xF4;n ng&#x1EEF; ch&#xED;nh th&#x1EE9;c cho <strong><a href="https://laptrinh-online.vn/course/lap-trinh-android-kotlin-full">l&#x1EAD;p tr&#xEC;nh Android</a></strong> (&#x111;&#x1B0;&#x1EE3;c Google c&#xF4;ng b&#x1ED1; n&#x103;m 2017), h&#xE0;ng lo&#x1EA1;t d&#x1EF1; &#xE1;n Java truy&#x1EC1;n th&#x1ED1;ng &#x111;&#xE3; b&#x1EAF;t &#x111;&#x1EA7;u chuy&#x1EC3;n sang Kotlin &#x111;&#x1EC3; t&#x1EAD;n d&#x1EE5;ng c&#xFA; ph&#xE1;p ng&#x1EAF;n g&#x1ECD;n, kh&#x1EA3; n&#x103;ng x&#x1EED; l&#xFD; null an to&#xE0;n, c&#x169;ng nh&#x1B0; h&#x1ED7; tr&#x1EE3; l&#x1EAD;p tr&#xEC;nh h&#xE0;m m&#x1EA1;nh m&#x1EBD;.</p><p>Tuy nhi&#xEA;n, v&#x1EDB;i c&#xE1;c project Android &#x111;&#xE3; vi&#x1EBF;t b&#x1EB1;ng Java, vi&#x1EC7;c chuy&#x1EC3;n &#x111;&#x1ED5;i ho&#xE0;n to&#xE0;n sang Kotlin kh&#xF4;ng &#x111;&#x1A1;n gi&#x1EA3;n. Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; t&#xEC;m hi&#x1EC3;u c&#xE1;ch t&#xED;ch h&#x1EE3;p Kotlin v&#xE0;o m&#x1ED9;t project Android Java hi&#x1EC7;n c&#xF3;, h&#x1B0;&#x1EDB;ng d&#x1EAB;n chuy&#x1EC3;n &#x111;&#x1ED5;i file Java sang Kotlin (v&#xE0; ng&#x1B0;&#x1EE3;c l&#x1EA1;i), c&#x169;ng nh&#x1B0; ph&#xE2;n t&#xED;ch c&#xE1;c r&#xE0;o c&#x1EA3;n th&#x1B0;&#x1EDD;ng g&#x1EB7;p.</p><h2 id="t%C3%ADch-h%E1%BB%A3p-kotlin-v%C3%A0o-m%E1%BB%99t-project-java-c%C3%B3-s%E1%BA%B5n">T&#xED;ch h&#x1EE3;p Kotlin v&#xE0;o m&#x1ED9;t project Java c&#xF3; s&#x1EB5;n</h2><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang s&#x1EDF; h&#x1EEF;u m&#x1ED9;t project Android thu&#x1EA7;n Java, b&#x1EA1;n kh&#xF4;ng c&#x1EA7;n t&#x1EA1;o l&#x1EA1;i t&#x1EEB; &#x111;&#x1EA7;u &#x111;&#x1EC3; d&#xF9;ng Kotlin. <strong><a href="https://laptrinh-online.vn/course/lap-trinh-android-kotlin-full">Android Studio h&#x1ED7; tr&#x1EE3; t&#xED;ch h&#x1EE3;p Kotlin</a></strong> ch&#x1EC9; trong v&#xE0;i b&#x1B0;&#x1EDB;c c&#x1EA5;u h&#xEC;nh.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-36.png" class="kg-image" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t" loading="lazy" width="1002" height="514"></figure><h3 id="c%C3%A1c-b%C6%B0%E1%BB%9Bc-th%E1%BB%B1c-hi%E1%BB%87n">C&#xE1;c b&#x1B0;&#x1EDB;c th&#x1EF1;c hi&#x1EC7;n:</h3><ul><li><strong>M&#x1EDF; project Java c&#x1EE7;a b&#x1EA1;n trong Android Studio</strong><br>&#x110;&#xE2;y c&#xF3; th&#x1EC3; l&#xE0; project c&#x169; ho&#x1EB7;c do b&#x1EA1;n t&#x1EA1;o m&#x1EDB;i b&#x1EB1;ng Java.</li><li><strong>Th&#xEA;m support cho Kotlin b&#x1EB1;ng c&#xF4;ng c&#x1EE5; IDE</strong><br>V&#xE0;o menu <code>Tools &gt; Kotlin &gt; Configure Kotlin in Project</code>. Android Studio s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng th&#xEA;m plugin Kotlin v&#xE0; c&#xE1;c dependency c&#x1EA7;n thi&#x1EBF;t v&#xE0;o <code>build.gradle</code>.</li><li><strong>C&#x1EAD;p nh&#x1EAD;t file <code>build.gradle (Module)</code></strong><br>&#x110;&#x1EA3;m b&#x1EA3;o r&#x1EB1;ng b&#x1EA1;n c&#xF3;:</li></ul><pre><code>plugins {
    id &apos;com.android.application&apos;
    id &apos;org.jetbrains.kotlin.android&apos;
}

dependencies {
    implementation &quot;org.jetbrains.kotlin:kotlin-stdlib:1.9.0&quot;
}
</code></pre><ul><li><strong>&#x110;&#x1ED3;ng b&#x1ED9; project (Sync Project with Gradle Files)</strong><br>Sau khi c&#x1EA5;u h&#xEC;nh xong, b&#x1EA1;n &#x111;&#xE3; c&#xF3; th&#x1EC3; t&#x1EA1;o class, activity ho&#x1EB7;c fragment b&#x1EB1;ng Kotlin ngay trong project Java hi&#x1EC7;n t&#x1EA1;i.</li></ul><h2 id="convert-file-java-sang-kotlin-b%E1%BA%B1ng-android-studio">Convert file Java sang Kotlin b&#x1EB1;ng Android Studio</h2><p>Kotlin v&#xE0; Java t&#x1B0;&#x1A1;ng th&#xED;ch 100% tr&#xEA;n Android. V&#xEC; v&#x1EAD;y, b&#x1EA1;n c&#xF3; th&#x1EC3; chuy&#x1EC3;n t&#x1EEB;ng file Java sang Kotlin m&#xE0; kh&#xF4;ng &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n to&#xE0;n b&#x1ED9; project.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-37.png" class="kg-image" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t" loading="lazy" width="660" height="404"></figure><h3 id="c%C3%A1ch-th%E1%BB%B1c-hi%E1%BB%87n"><em>C&#xE1;ch th&#x1EF1;c hi&#x1EC7;n:</em></h3><p>M&#x1EDF; file Java b&#x1EA1;n mu&#x1ED1;n chuy&#x1EC3;n &#x111;&#x1ED5;i.</p><p>T&#x1EEB; menu, ch&#x1ECD;n <code>Code &gt; Convert Java File to Kotlin File</code> ho&#x1EB7;c d&#xF9;ng t&#x1ED5; h&#x1EE3;p ph&#xED;m <code>Ctrl + Alt + Shift + K</code> (Windows) ho&#x1EB7;c <code>Cmd + Alt + Shift + K</code> (macOS).</p><p>Android Studio s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng chuy&#x1EC3;n &#x111;&#x1ED5;i sang file <code>.kt</code> v&#x1EDB;i c&#xFA; ph&#xE1;p Kotlin t&#x1B0;&#x1A1;ng &#x111;&#x1B0;&#x1A1;ng.</p><h3 id="v%C3%AD-d%E1%BB%A5-minh-h%E1%BB%8Da"><em>V&#xED; d&#x1EE5; minh h&#x1ECD;a:</em></h3><ul><li><strong>Java:</strong></li></ul><pre><code>public class HelloWorld {
    public static void main(String[] args) {
        String message = &quot;Xin ch&#xE0;o t&#x1EEB; Java!&quot;;
        System.out.println(message);
    }
}
</code></pre><ul><li><strong>Sau khi convert sang Kotlin:</strong></li></ul><pre><code>fun main() {
    val message = &quot;Xin ch&#xE0;o t&#x1EEB; Java!&quot;
    println(message)
}
</code></pre><p>Nh&#x1B0; b&#x1EA1;n th&#x1EA5;y, c&#xFA; ph&#xE1;p Kotlin ng&#x1EAF;n g&#x1ECD;n v&#xE0; d&#x1EC5; &#x111;&#x1ECD;c h&#x1A1;n, lo&#x1EA1;i b&#x1ECF; t&#x1EEB; kh&#xF3;a r&#x1B0;&#x1EDD;m r&#xE0; nh&#x1B0; <code>public</code>, <code>static</code>, v.v.</p><h2 id="convert-file-kotlin-sang-java-ng%C6%B0%E1%BB%A3c-l%E1%BA%A1i">Convert file Kotlin sang Java (ng&#x1B0;&#x1EE3;c l&#x1EA1;i)</h2><p>M&#x1EB7;c d&#xF9; Kotlin l&#xE0; xu h&#x1B0;&#x1EDB;ng ch&#xED;nh, &#x111;&#xF4;i khi b&#x1EA1;n v&#x1EAB;n c&#x1EA7;n chuy&#x1EC3;n code t&#x1EEB; Kotlin sang Java (ch&#x1EB3;ng h&#x1EA1;n &#x111;&#x1EC3; t&#x1B0;&#x1A1;ng th&#xED;ch v&#x1EDB;i th&#x1B0; vi&#x1EC7;n c&#x169;, ho&#x1EB7;c chia s&#x1EBB; v&#x1EDB;i team d&#xF9;ng Java).</p><p>Android Studio kh&#xF4;ng h&#x1ED7; tr&#x1EE3; chuy&#x1EC3;n tr&#x1EF1;c ti&#x1EBF;p Kotlin &#x2192; Java b&#x1EB1;ng menu, nh&#x1B0;ng b&#x1EA1;n c&#xF3; th&#x1EC3; d&#xF9;ng c&#xF4;ng c&#x1EE5; decompile.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-38.png" class="kg-image" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t" loading="lazy" width="900" height="687"></figure><h3 id="c%C3%A1c-b%C6%B0%E1%BB%9Bc">C&#xE1;c b&#x1B0;&#x1EDB;c:</h3><p>Vi&#x1EBF;t m&#xE3; Kotlin trong file <code>.kt</code>.</p><p>Bi&#xEA;n d&#x1ECB;ch code, sau &#x111;&#xF3; v&#xE0;o <code>Tools &gt; Kotlin &gt; Show Kotlin Bytecode</code>.</p><p>Nh&#x1EA5;n n&#xFA;t <strong>Decompile</strong> &#x111;&#x1EC3; xem code Java t&#x1B0;&#x1A1;ng &#x111;&#x1B0;&#x1A1;ng.</p><h3 id="v%C3%AD-d%E1%BB%A5">V&#xED; d&#x1EE5;:</h3><p><strong>Kotlin:</strong></p><p><code>fun chao(name: String) { println(&quot;Xin ch&#xE0;o, $name!&quot;) }</code></p><p><strong>Sau khi decompile sang Java:</strong></p><pre><code>public final class ExampleKt {
    public static final void chao(@NotNull String name) {
        System.out.println(&quot;Xin ch&#xE0;o, &quot; + name + &apos;!&apos;);
    }
}
</code></pre><h2 id="nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m-khi-chuy%E1%BB%83n-ng%C3%B4n-ng%E1%BB%AF-t%E1%BB%AB-java-sang-kotlin">Nh&#x1B0;&#x1EE3;c &#x111;i&#x1EC3;m khi chuy&#x1EC3;n ng&#xF4;n ng&#x1EEF; t&#x1EEB; Java sang Kotlin</h2><p>M&#x1EB7;c d&#xF9; Kotlin mang l&#x1EA1;i nhi&#x1EC1;u l&#x1EE3;i &#xED;ch v&#x1EC1; tr&#x1EA3;i nghi&#x1EC7;m code, b&#x1EA3;o m&#x1EAD;t v&#xE0; ng&#x1EAF;n g&#x1ECD;n, qu&#xE1; tr&#xEC;nh chuy&#x1EC3;n &#x111;&#x1ED5;i c&#x169;ng ti&#x1EC1;m &#x1EA9;n m&#x1ED9;t s&#x1ED1; r&#xE0;o c&#x1EA3;n n&#x1EBF;u kh&#xF4;ng c&#x1EA9;n th&#x1EAD;n:</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-39.png" class="kg-image" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t" loading="lazy" width="700" height="400"></figure><h3 id="kh%C3%B3-kh%C4%83n-ch%C3%ADnh">Kh&#xF3; kh&#x103;n ch&#xED;nh:</h3><ul><li><strong>S&#x1EF1; kh&#xE1;c bi&#x1EC7;t v&#x1EC1; c&#x1EA5;u tr&#xFA;c ng&#xF4;n ng&#x1EEF;</strong>: M&#x1ED9;t s&#x1ED1; m&#x1EAB;u design pattern ph&#x1ED5; bi&#x1EBF;n trong Java (Builder, Singleton...) c&#x1EA7;n &#x111;&#x1B0;&#x1EE3;c vi&#x1EBF;t l&#x1EA1;i theo c&#xE1;ch &quot;Kotlin-idiomatic&quot;.</li><li><strong>V&#x1EA5;n &#x111;&#x1EC1; t&#x1B0;&#x1A1;ng th&#xED;ch API c&#x169;</strong>: Kh&#xF4;ng ph&#x1EA3;i th&#x1B0; vi&#x1EC7;n n&#xE0;o c&#x169;ng h&#x1ED7; tr&#x1EE3; t&#x1ED1;t Kotlin, nh&#x1EA5;t l&#xE0; v&#x1EDB;i reflection ho&#x1EB7;c Java annotation.</li><li><strong>Kh&#xF3; &#x111;&#x1ECD;c n&#x1EBF;u ch&#x1B0;a quen c&#xFA; ph&#xE1;p</strong>: Kotlin c&#xF3; nhi&#x1EC1;u c&#xFA; ph&#xE1;p m&#x1EDB;i (lambda, extension function, scope function...) g&#xE2;y kh&#xF3; hi&#x1EC3;u cho team ch&#x1B0;a c&#xF3; kinh nghi&#x1EC7;m.</li><li><strong>Bug chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EF1; &#x111;&#x1ED9;ng</strong>: C&#xF4;ng c&#x1EE5; convert &#x111;&#xF4;i khi kh&#xF4;ng t&#x1ED1;i &#x1B0;u ho&#x1EB7;c g&#xE2;y l&#x1ED7;i logic nh&#x1ECF; khi x&#x1EED; l&#xFD; bi&#x1EC3;u th&#x1EE9;c ph&#x1EE9;c t&#x1EA1;p.</li></ul><h3 id="g%E1%BB%A3i-%C3%BD-gi%E1%BA%A3i-ph%C3%A1p">G&#x1EE3;i &#xFD; gi&#x1EA3;i ph&#xE1;p:</h3><ul><li>Chuy&#x1EC3;n &#x111;&#x1ED5;i d&#x1EA7;n t&#x1EEB;ng module ho&#x1EB7;c package.</li><li>Vi&#x1EBF;t test &#x111;&#x1EC3; &#x111;&#x1EA3;m b&#x1EA3;o h&#xE0;nh vi kh&#xF4;ng b&#x1ECB; sai sau khi migrate.</li><li>&#x110;&#xE0;o t&#x1EA1;o n&#x1ED9;i b&#x1ED9; v&#x1EC1; c&#xFA; ph&#xE1;p Kotlin tr&#x1B0;&#x1EDB;c khi chuy&#x1EC3;n to&#xE0;n b&#x1ED9; d&#x1EF1; &#xE1;n.</li></ul><h2 id="v%C3%B2ng-l%E1%BA%B7p-trong-kotlin-for-while-v%C3%A0-c%C3%A1ch-%C3%A1p-d%E1%BB%A5ng">V&#xF2;ng l&#x1EB7;p trong Kotlin: <code>for</code>, <code>while</code> v&#xE0; c&#xE1;ch &#xE1;p d&#x1EE5;ng</h2><p>Sau khi &#x111;&#xE3; c&#xF3; &#x111;&#x1B0;&#x1EE3;c c&#xE1;c file Kotlin &#x111;&#x1EA7;u ti&#xEA;n, b&#x1EA1;n s&#x1EBD; c&#x1EA7;n s&#x1EED; d&#x1EE5;ng <strong>v&#xF2;ng l&#x1EB7;p</strong> &#x111;&#x1EC3; x&#x1EED; l&#xFD; danh s&#xE1;ch, m&#x1EA3;ng ho&#x1EB7;c th&#x1EF1;c hi&#x1EC7;n h&#xE0;nh &#x111;&#x1ED9;ng l&#x1EB7;p l&#x1EA1;i.</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-40.png" class="kg-image" alt="Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; Java sang Kotlin trong Android: T&#xED;ch h&#x1EE3;p Kotlin, Convert file v&#xE0; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t" loading="lazy" width="670" height="316"></figure><ul><li>V&#xF2;ng l&#x1EB7;p <code>for</code></li></ul><p>Kotlin h&#x1ED7; tr&#x1EE3; v&#xF2;ng l&#x1EB7;p <code>for-in</code>, &#x111;&#x1A1;n gi&#x1EA3;n h&#x1A1;n r&#x1EA5;t nhi&#x1EC1;u so v&#x1EDB;i Java.</p><pre><code>val danhSach = listOf(&quot;Android&quot;, &quot;Kotlin&quot;, &quot;Java&quot;)

for (item in danhSach) {
    println(item)
}</code></pre><p>Ho&#x1EB7;c l&#x1EB7;p theo ch&#x1EC9; s&#x1ED1;:</p><p><code>for (i in 0..4) { println(&quot;i = $i&quot;) }</code></p><ul><li>V&#xF2;ng l&#x1EB7;p <code>while</code> v&#xE0; <code>do-while</code></li></ul><p>C&#xE1;ch d&#xF9;ng t&#x1B0;&#x1A1;ng t&#x1EF1; Java:</p><pre><code>var i = 0
while (i &lt; 5) {
    println(&quot;while: $i&quot;)
    i++
}

do {
    println(&quot;do-while: $i&quot;)
    i++
} while (i &lt; 8)
</code></pre><p>Kotlin &#x111;ang tr&#x1EDF; th&#xE0;nh xu h&#x1B0;&#x1EDB;ng t&#x1EA5;t y&#x1EBF;u trong <strong><a href="https://laptrinh-online.vn/course/lap-trinh-android-kotlin-full">ph&#xE1;t tri&#x1EC3;n Android</a></strong> hi&#x1EC7;n &#x111;&#x1EA1;i. N&#x1EBF;u b&#x1EA1;n &#x111;ang l&#xE0;m vi&#x1EC7;c v&#x1EDB;i m&#x1ED9;t project Java, &#x111;&#x1EEB;ng ng&#x1EA7;n ng&#x1EA1;i t&#xED;ch h&#x1EE3;p Kotlin &#x111;&#x1EC3; t&#x1EAD;n d&#x1EE5;ng s&#x1EE9;c m&#x1EA1;nh c&#x1EE7;a c&#x1EA3; hai th&#x1EBF; gi&#x1EDB;i. Tuy nhi&#xEA;n, qu&#xE1; tr&#xEC;nh chuy&#x1EC3;n &#x111;&#x1ED5;i c&#x1EA7;n th&#x1EF1;c hi&#x1EC7;n t&#x1EEB; t&#x1EEB;, c&#xF3; ki&#x1EC3;m so&#xE1;t v&#xE0; c&#x1EA7;n s&#x1EF1; chu&#x1EA9;n b&#x1ECB; k&#x1EF9; c&#xE0;ng.</p><p>B&#x1EA1;n c&#xF3; th&#x1EC3; b&#x1EAF;t &#x111;&#x1EA7;u b&#x1EB1;ng vi&#x1EC7;c convert t&#x1EEB;ng file Java sang Kotlin, vi&#x1EBF;t c&#xE1;c class m&#x1EDB;i b&#x1EB1;ng Kotlin trong project Java hi&#x1EC7;n c&#xF3;. Quan tr&#x1ECD;ng nh&#x1EA5;t, h&#xE3;y lu&#xF4;n &#x111;&#x1EA3;m b&#x1EA3;o m&#xE3; ngu&#x1ED3;n &#x111;&#x1B0;&#x1EE3;c ki&#x1EC3;m th&#x1EED; &#x111;&#x1EA7;y &#x111;&#x1EE7;, v&#xEC; d&#xF9; Kotlin m&#x1EA1;nh m&#x1EBD; nh&#x1B0;ng kh&#xF4;ng th&#x1EC3; thay th&#x1EBF; s&#x1EF1; c&#x1EA9;n tr&#x1ECD;ng c&#x1EE7;a developer.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m kh&#xF3;a h&#x1ECD;c L&#x1EAD;p tr&#xEC;nh Android, h&#xE3;y truy c&#x1EAD;p li&#xEA;n k&#x1EBF;t ngay &#x111;&#x1EC3; <a href="https://laptrinh-online.vn/"><strong><strong>&#x110;&#x103;ng k&#xFD; ngay t&#x1EA1;i &#x111;&#xE2;y</strong></strong></a><strong><strong> .</strong></strong></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/c5EzkwIuAvA?list=PLc1iBK01_exeCP0mOAgCi6cDbXhRBi1bN" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>&#x110;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <a href="https://codefresher.vn/"><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> </a>&#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t th&#xF4;ng tin m&#x1EDB;i nh&#x1EA5;t v&#x1EC1; c&#xE1;c kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh!</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/courses/tat-ca-khoa-hoc">https://laptrinh-online.vn/courses/tat-ca-khoa-hoc</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[Lập trình Android Kotlin - Khái niệm Biến, Hàm và Null Safety và bài tập thực hành]]></title><description><![CDATA[Khi bắt đầu học lập trình Android với Kotlin, có ba khái niệm nền tảng mà bất kỳ lập trình viên nào cũng cần nắm vững, đó là: biến, hàm và Null Safety. Đây không chỉ là ba phần kiến thức khởi đầu, mà còn là nền móng cho tất cả các ứng dụng bạn sẽ xây dựng sau này. Trong bài viết này, chúng ta sẽ cùng đi sâu vào từng khái niệm, giải thích kỹ lưỡng và có ví dụ minh họa rõ ràng bằng mã Kotlin thực tế.]]></description><link>https://laptrinh-online.vn/blog/lap-trinh-android-kotlin/</link><guid isPermaLink="false">680260e614958c001e7ab9c0</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Fri, 18 Apr 2025 14:57:54 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/hq720--1-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/hq720--1-.jpg" alt="L&#x1EAD;p tr&#xEC;nh Android Kotlin - Kh&#xE1;i ni&#x1EC7;m Bi&#x1EBF;n, H&#xE0;m v&#xE0; Null Safety v&#xE0; b&#xE0;i t&#x1EAD;p th&#x1EF1;c h&#xE0;nh"><p>Khi b&#x1EAF;t &#x111;&#x1EA7;u <a href="https://laptrinh-online.vn/course/lap-trinh-android-kotlin-full"><strong>h&#x1ECD;c thi&#x1EBF;t l&#x1EAD;p Android v&#x1EDB;i Kotlin</strong></a> , c&#xF3; ba kh&#xE1;i ni&#x1EC7;m n&#x1EC1;n t&#x1EA3;ng m&#xE0; b&#x1EA5;t k&#x1EF3; tr&#xEC;nh c&#xE0;i &#x111;&#x1EB7;t n&#xE0;o c&#x169;ng c&#x1EA7;n n&#x1EAF;m ch&#x1EAF;c, &#x111;&#xF3; l&#xE0;: bi&#x1EBF;n, h&#xE0;m v&#xE0; Null Safety. &#x110;&#xE2;y kh&#xF4;ng ch&#x1EC9; l&#xE0; kh&#x1EDF;i &#x111;&#x1ED9;ng theo ki&#x1EBF;n &#x200B;&#x200B;tr&#xFA;c m&#xE0; c&#xF2;n l&#xE0; n&#x1EC1;n t&#x1EA3;ng cho t&#x1EA5;t c&#x1EA3; c&#xE1;c &#x1EE9;ng d&#x1EE5;ng m&#xE0; b&#x1EA1;n s&#x1EBD; x&#xE2;y d&#x1EF1;ng sau n&#xE0;y. Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng t&#xF4;i s&#x1EBD; c&#xF9;ng &#x111;i s&#xE2;u v&#xE0;o t&#x1EEB;ng kh&#xE1;i ni&#x1EC7;m, gi&#x1EA3;i th&#xED;ch k&#x1EF9; n&#x103;ng c&#xE2;n b&#x1EB1;ng v&#xE0; c&#xF3; v&#xED; d&#x1EE5; minh h&#x1ECD;a r&#xF5; r&#xE0;ng b&#x1EB1;ng m&#xE3; Kotlin th&#x1EF1;c t&#x1EBF;.</p><h2 id="bi%E1%BA%BFn-trong-kotlin">Bi&#x1EBF;n trong Kotlin </h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-31.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Android Kotlin - Kh&#xE1;i ni&#x1EC7;m Bi&#x1EBF;n, H&#xE0;m v&#xE0; Null Safety v&#xE0; b&#xE0;i t&#x1EAD;p th&#x1EF1;c h&#xE0;nh" loading="lazy" width="662" height="194"></figure><p>Trong qu&#xE1; tr&#xEC;nh c&#xE0;i &#x111;&#x1EB7;t, bi&#x1EBF;n l&#xE0; &#x111;&#x1EA1;i di&#x1EC7;n cho m&#x1ED9;t v&#xF9;ng nh&#x1EDB; &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng &#x111;&#x1EC3; l&#x1B0;u tr&#x1EEF; th&#xF4;ng tin. M&#x1ED7;i bi&#x1EBF;n trong Kotlin &#x111;&#x1EC1;u mang theo lo&#x1EA1;i d&#x1EEF; li&#x1EC7;u v&#xE0; kh&#x1EA3; n&#x103;ng kh&#xF4;ng th&#x1EC3; thay &#x111;&#x1ED5;i ho&#x1EB7;c c&#xF3; th&#x1EC3; thay &#x111;&#x1ED5;i, c&#x1EA3;nh b&#xE1;o khai b&#xE1;o t&#xF9;y ch&#x1ECD;n.</p><p>Kotlin cung c&#x1EA5;p hai c&#xE1;ch khai b&#xE1;o ch&#xED;nh: <code>val</code>v&#xE0; <code>var</code>. Trong &#x111;&#xF3;: </p><ul><li><strong><code>val</code></strong>d&#xF9;ng &#x111;&#x1EC3; khai b&#xE1;o h&#x1EB1;ng s&#x1ED1; &#x2013; m&#x1ED9;t bi&#x1EBF;n &#x111;&#x1B0;&#x1EE3;c &#x111;&#x1ECB;nh gi&#xE1; tr&#x1ECB; ch&#x1EC9; m&#x1ED9;t l&#x1EA7;n duy nh&#x1EA5;t. &#x110;i&#x1EC1;u n&#xE0;y mang l&#x1EA1;i s&#x1EF1; an to&#xE0;n trong c&#xE0;i &#x111;&#x1EB7;t, tr&#xE1;nh nh&#x1EEF;ng thay &#x111;&#x1ED5;i m&#xE0; b&#x1EA1;n kh&#xF4;ng mong mu&#x1ED1;n.</li><li><strong><code>var</code></strong>cho ph&#xE9;p g&#xE1;n l&#x1EA1;i gi&#xE1; tr&#x1ECB; nhi&#x1EC1;u l&#x1EA7;n, th&#xED;ch h&#x1EE3;p cho c&#xE1;c bi&#x1EBF;n m&#xE0; gi&#xE1; tr&#x1ECB; s&#x1EBD; thay &#x111;&#x1ED5;i trong qu&#xE1; tr&#xEC;nh ch&#x1EA1;y ch&#x1B0;&#x1A1;ng tr&#xEC;nh.</li></ul><h3 id="v%C3%AD-d%E1%BB%A5-minh-h%E1%BB%8Da">V&#xED; d&#x1EE5; minh h&#x1ECD;a:</h3><pre><code>fun main() 
{val pi = 3.14
var soLuong = 1
println(&quot;Pi = $pi&quot;)
println(&quot;S&#x1ED1; l&#x1B0;&#x1EE3;ng ban &#x111;&#x1EA7;u = $soLuong&quot;)

soLuong = 20 // c&#xF3; th&#x1EC3; g&#xE1;n l&#x1EA1;i v&#xEC; l&#xE0; var
println(&quot;S&#x1ED1; l&#x1B0;&#x1EE3;ng sau khi c&#x1EAD;p nh&#x1EAD;t = $soLuong&quot;) }
</code></pre><p>Ngo&#xE0;i ra, Kotlin v&#x1EAB;n h&#x1ED7; tr&#x1EE3; th&#x1EA3;o lu&#x1EAD;n v&#x1EC1; ki&#x1EC3;u d&#x1EEF; li&#x1EC7;u &#x2013; ngh&#x129;a l&#xE0; b&#x1EA1;n kh&#xF4;ng c&#x1EA7;n &#x111;&#x1ECB;nh ngh&#x129;a ch&#x1EC9; lo&#x1EA1;i n&#x1EBF;u tr&#xEC;nh bi&#xEA;n d&#x1ECB;ch c&#xF3; th&#x1EC3; t&#x1EF1; &#x111;&#x1ED9;ng hi&#x1EC3;u. Tuy nhi&#xEA;n, b&#x1EA1;n v&#x1EAB;n c&#xF3; th&#x1EC3; khai b&#xE1;o T&#x1B0;&#x1EDD;ng minh &#x111;&#x1EC3; m&#xE3; ngu&#x1ED3;n d&#x1EC5; &#x111;&#x1ECD;c h&#x1A1;n:</p><ul><li><code>val ten: String = &quot;Android&quot;</code></li><li><code>var diem: Float = 9.5f</code></li></ul><h2 id="h%C3%A0m-trong-kotlin-%E2%80%93-x%C3%A2y-d%E1%BB%B1ng-logic-t%E1%BB%95-ch%E1%BB%A9c-ch%C6%B0%C6%A1ng-tr%C3%ACnh">H&#xE0;m trong Kotlin &#x2013; X&#xE2;y d&#x1EF1;ng logic, t&#x1ED5; ch&#x1EE9;c ch&#x1B0;&#x1A1;ng tr&#xEC;nh</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-32.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Android Kotlin - Kh&#xE1;i ni&#x1EC7;m Bi&#x1EBF;n, H&#xE0;m v&#xE0; Null Safety v&#xE0; b&#xE0;i t&#x1EAD;p th&#x1EF1;c h&#xE0;nh" loading="lazy" width="996" height="628"></figure><p>H&#xE0;m l&#xE0; th&#xE0;nh ph&#x1EA7;n c&#x1EE7;a t&#x1ED5;ng h&#x1EE3;p ngu&#x1ED3;n m&#xE3; theo t&#x1EEB;ng kh&#x1ED1;i ch&#x1EE9;c n&#x103;ng ri&#xEA;ng bi&#x1EC7;t. Nh&#x1EDD; c&#xF3; ch&#x1EE9;c n&#x103;ng, ch&#x1B0;&#x1A1;ng tr&#xEC;nh tr&#x1EDF; n&#xEA;n g&#x1ECD;n g&#xE0;ng, d&#x1EC5; s&#x1EED; d&#x1EE5;ng v&#xE0; b&#x1EA3;o tr&#xEC;.</p><p>Trong Kotlin, h&#xE0;m &#x111;&#x1B0;&#x1EE3;c &#x111;&#x1ECB;nh ngh&#x129;a b&#x1EB1;ng t&#x1EEB; kh&#xF3;a <code>fun</code>, theo c&#x1EA5;u tr&#xFA;c:</p><p><code>fun tenHam(thamSo1: Kieu1, thamSo2: Kieu2): KieuTraVe { // n&#x1ED9;i dung &#xA0; &#xA0;return giaTri }</code></p><h3 id="ph%C3%A2n-t%C3%ADch-s%C3%A2u-v%E1%BB%81-c%C3%A1c-lo%E1%BA%A1i-h%C3%A0m">Ph&#xE2;n t&#xED;ch s&#xE2;u v&#x1EC1; c&#xE1;c lo&#x1EA1;i h&#xE0;m:</h3><ul><li>H&#xE0;m tr&#x1EA3; gi&#xE1; tr&#x1ECB;: &#x110;&#xE2;y l&#xE0; m&#x1ED9;t bi&#x1EBF;n ph&#x1ED5; bi&#x1EBF;n, gi&#xFA;p nh&#x1EAD;n &#x111;&#x1EA7;u v&#xE0;o, x&#x1EED; l&#xFD; v&#xE0; tr&#x1EA3; k&#x1EBF;t qu&#x1EA3;.</li><li>H&#xE0;m kh&#xF4;ng tr&#x1EA3; v&#x1EC1; b&#x1EA5;t c&#x1EE9; &#x111;i&#x1EC1;u g&#xEC; (tr&#x1EA3; v&#x1EC1; <code>Unit</code>): Th&#x1B0;&#x1EDD;ng &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng &#x111;&#x1EC3; th&#x1EF1;c hi&#x1EC7;n m&#x1ED9;t h&#xE0;nh &#x111;&#x1ED9;ng, h&#x1EA1;n ch&#x1EBF; tr&#xEA;n m&#xE0;n h&#xEC;nh.</li><li>H&#xE0;m m&#x1ED9;t d&#xF2;ng (h&#xE0;m bi&#x1EC3;u th&#x1EE9;c &#x111;&#x1A1;n gi&#x1EA3;n): R&#xFA;t g&#x1ECD;n cho c&#xE1;c h&#xE0;m &#x111;&#x1A1;n gi&#x1EA3;n, gi&#xFA;p m&#xE3; h&#xF3;a r&#xFA;t g&#x1ECD;n.</li><li>Tham s&#x1ED1; m&#x1EB7;c &#x111;&#x1ECB;nh: Cho ph&#xE9;p g&#xE1;n gi&#xE1; tr&#x1ECB; m&#x1EB7;c &#x111;&#x1ECB;nh cho tham s&#x1ED1; n&#x1EBF;u ng&#x1B0;&#x1EDD;i d&#xF9;ng kh&#xF4;ng truy&#x1EC1;n v&#xE0;o.</li><li>H&#xE0;m v&#x1EDB;i s&#x1ED1; l&#x1B0;&#x1EE3;ng tham s&#x1ED1; kh&#xF4;ng gi&#x1EDB;i h&#x1EA1;n ( <code>vararg</code>): Ph&#xF9; h&#x1EE3;p khi b&#x1EA1;n kh&#xF4;ng bi&#x1EBF;t tr&#x1B0;&#x1EDB;c s&#x1ED1; l&#x1B0;&#x1EE3;ng gi&#xE1; tr&#x1ECB; truy&#x1EC1;n v&#xE0;o.</li><li>H&#xE0;m b&#x1EAD;c cao h&#x1A1;n: H&#xE0;m c&#xF3; th&#x1EC3; nh&#x1EAD;n bi&#x1EBF;t c&#xE1;c h&#xE0;m kh&#xE1;c l&#xE0;m tham s&#x1ED1;, &#x111;&#x1EB7;c tr&#x1B0;ng c&#x1EE7;a h&#xE0;m hi&#x1EC7;n &#x111;&#x1EA1;i.</li></ul><h3 id="v%C3%AD-d%E1%BB%A5-t%E1%BB%95ng-h%E1%BB%A3p">V&#xED; d&#x1EE5; t&#x1ED5;ng h&#x1EE3;p:</h3><pre><code>fun chao(name: String = &quot;Ng&#x1B0;&#x1EDD;i d&#xF9;ng&quot;) {
    println(&quot;Xin ch&#xE0;o, $name!&quot;)
}

fun binhPhuong(x: Int): Int {
    return x * x
}

fun tinhTong(vararg so: Int): Int {
    return so.sum()
}

fun xuLy(x: Int, hamXuLy: (Int) -&gt; Int): Int {
    return hamXuLy(x)
}

fun main() {
    chao()
    println(&quot;4^2 = ${binhPhuong(4)}&quot;)
    println(&quot;T&#x1ED5;ng = ${tinhTong(1, 2, 3)}&quot;)

    val ketQua = xuLy(5) { it * 10 }
    println(&quot;K&#x1EBF;t qu&#x1EA3; x&#x1EED; l&#xFD;: $ketQua&quot;)
}
</code></pre><h2 id="null-safety-%E2%80%93-b%E1%BA%A3o-v%E1%BB%87-%E1%BB%A9ng-d%E1%BB%A5ng-kh%E1%BB%8Fi-l%E1%BB%97i-th%C6%B0%E1%BB%9Dng-g%E1%BA%B7p-nh%E1%BA%A5t">Null Safety &#x2013; B&#x1EA3;o v&#x1EC7; &#x1EE9;ng d&#x1EE5;ng kh&#x1ECF;i l&#x1ED7;i th&#x1B0;&#x1EDD;ng g&#x1EB7;p nh&#x1EA5;t</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-35.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Android Kotlin - Kh&#xE1;i ni&#x1EC7;m Bi&#x1EBF;n, H&#xE0;m v&#xE0; Null Safety v&#xE0; b&#xE0;i t&#x1EAD;p th&#x1EF1;c h&#xE0;nh" loading="lazy" width="2518" height="1202"></figure><p>M&#x1ED9;t trong nh&#x1EEF;ng s&#x1EA3;n ph&#x1EA9;m n&#x1ED5;i b&#x1EAD;t nh&#x1EA5;t Kotlin &#x111;&#x1B0;&#x1EE3;c &#x1B0;a chu&#x1ED9;ng l&#xE0; kh&#x1EA3; n&#x103;ng x&#x1EED; l&#xFD; null m&#x1ED9;t c&#xE1;ch an to&#xE0;n v&#xE0; r&#xF5; r&#xE0;ng. Trong Java, l&#x1ED7;i <code>NullPointerException</code>(NPE) l&#xE0; nguy&#xEA;n nh&#xE2;n ch&#xED;nh g&#xE2;y ra s&#x1EF1; c&#x1ED1; cho &#x1EE9;ng d&#x1EE5;ng Android. Kotlin &#x111;&#xE3; quy&#x1EBF;t &#x111;&#x1ECB;nh gi&#x1EA3;i quy&#x1EBF;t v&#x1EA5;n &#x111;&#x1EC1; n&#xE0;y b&#x1EB1;ng h&#x1EC7; th&#x1ED1;ng Null Safety.</p><h3 id="kh%C3%A1i-ni%E1%BB%87m-c%E1%BB%91t-l%C3%B5i"><em>Kh&#xE1;i ni&#x1EC7;m c&#x1ED1;t l&#xF5;i:</em></h3><p>M&#x1ED7;i bi&#x1EBF;n trong Kotlin <strong>ph&#x1EA3;i &#x111;&#x1B0;&#x1EE3;c khai b&#xE1;o r&#xF5; r&#xE0;ng</strong> c&#xF3; th&#x1EC3; tr&#x1ED1;ng ho&#x1EB7;c kh&#xF4;ng. N&#x1EBF;u bi&#x1EBF;n kh&#xF4;ng &#x111;&#x1B0;&#x1EE3;c ph&#xE9;p r&#x1ED7;ng, tr&#xEC;nh bi&#xEA;n d&#x1ECB;ch s&#x1EBD; c&#x1EA3;nh b&#xE1;o ngay khi b&#x1EA1;n c&#x1ED1; g&#x1EAF;ng chuy&#x1EC3;n gi&#xE1; tr&#x1ECB; r&#x1ED7;ng.</p><ul><li><code>val ten: String = &quot;Kotlin&quot;</code></li><li><code>var email: String? = null // c&#xF3; th&#x1EC3; null v&#xEC; c&#xF3; d&#x1EA5;u ?</code></li></ul><h3 id="c%C3%B4ng-c%E1%BB%A5-x%E1%BB%AD-l%C3%BD-null-an-to%C3%A0n"><em>C&#xF4;ng c&#x1EE5; x&#x1EED; l&#xFD; null an to&#xE0;n:</em></h3><ul><li><strong>Cu&#x1ED9;c g&#x1ECD;i an to&#xE0;n ( </strong><code><strong>?.</strong></code><strong>)</strong> : D&#xF9;ng &#x111;&#x1EC3; g&#x1ECD;i thu&#x1ED9;c t&#xED;nh/ph&#x1B0;&#x1A1;ng th&#x1EE9;c m&#x1ED9;t c&#xE1;ch an to&#xE0;n. N&#x1EBF;u bi&#x1EBF;n l&#xE0; null, k&#x1EBF;t qu&#x1EA3; tr&#x1EA3; v&#x1EC1; c&#x169;ng l&#xE0; null thay v&#xEC; g&#xE2;y ra l&#x1ED7;i.</li><li><strong>To&#xE1;n t&#x1EED; Elvis ( </strong><code><strong>?:</strong></code><strong>)</strong> : Cho ph&#xE9;p g&#xE1;n gi&#xE1; tr&#x1ECB; m&#x1EB7;c &#x111;&#x1ECB;nh n&#x1EBF;u bi&#x1EBF;n l&#xE0; null.</li><li><strong>Kh&#x1EB3;ng &#x111;&#x1ECB;nh kh&#xF4;ng null ( </strong><code><strong>!!</strong></code><strong>)</strong> : &#xC9;p bu&#x1ED9;c bi&#x1EBF;n kh&#xF4;ng th&#x1EC3; r&#x1ED7;ng. N&#x1EBF;u null, ch&#x1B0;&#x1A1;ng tr&#xEC;nh s&#x1EBD; b&#x1ECB; l&#x1ED7;i. Ch&#x1EC9; s&#x1EED; d&#x1EE5;ng khi gi&#xE1; tr&#x1ECB; ch&#x1EAF;c ch&#x1EAF;n kh&#xF4;ng c&#xF3; gi&#xE1; tr&#x1ECB; r&#x1ED7;ng.</li></ul><h3 id="v%C3%AD-d%E1%BB%A5-th%E1%BB%B1c-t%E1%BA%BF"><em>V&#xED; d&#x1EE5; th&#x1EF1;c t&#x1EBF;:</em></h3><pre><code>// Safe call
val doDai = email?.length
println(&quot;Chi&#x1EC1;u d&#xE0;i email: $doDai&quot;)

// Elvis operator
val doDaiFix = email?.length ?: 0
println(&quot;Chi&#x1EC1;u d&#xE0;i email (fix): $doDaiFix&quot;)

// Not-null assertion (c&#x1EA9;n th&#x1EAD;n!)
// println(&quot;Chi&#x1EC1;u d&#xE0;i email (&#xE9;p): ${email!!.length}&quot;) // crash n&#x1EBF;u email l&#xE0; null
</code></pre><p>Bi&#x1EBF;n, h&#xE0;m v&#xE0; Null Safety l&#xE0; ba kh&#xE1;i ni&#x1EC7;m n&#x1EC1;n t&#x1EA3;ng kh&#xF4;ng th&#x1EC3; thi&#x1EBF;u trong qu&#xE1; tr&#xEC;nh h&#x1ECD;c Kotlin n&#xF3;i chung v&#xE0; <a href="https://laptrinh-online.vn/course/lap-trinh-android-kotlin-full"><strong>l&#x1EAD;p tr&#xEC;nh ri&#xEA;ng cho Android</strong></a> . Bi&#x1EBF;t r&#xF5; t&#x1EEB;ng ph&#x1EA7;n kh&#xF4;ng ch&#x1EC9; gi&#xFA;p b&#x1EA1;n vi&#x1EBF;t m&#xE3; s&#x1EA1;ch v&#xE0; hi&#x1EC7;u qu&#x1EA3;, nh&#x1B0;ng c&#x169;ng gi&#x1EA3;m thi&#x1EC3;u l&#x1ED7;i logic c&#x169;ng nh&#x1B0; r&#xFA;t ng&#x1EAF;n th&#x1EDD;i gian ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng.</p><p>N&#x1EBF;u b&#x1EA1;n m&#x1EDB;i b&#x1EAF;t &#x111;&#x1EA7;u, h&#xE3;y ki&#x1EC3;m tra t&#x1EAD;p tin c&#xE1;c ch&#x1B0;&#x1A1;ng tr&#xEC;nh s&#x1EED; d&#x1EE5;ng bi&#x1EBF;n nh&#x1ECF;, &#x111;&#x1ECB;nh ngh&#x129;a h&#xE0;m &#x111;&#x1A1;n gi&#x1EA3;n v&#xE0; bi&#x1EBF;n x&#x1EED; l&#xFD; null. &#x110;&#xE2;y l&#xE0; b&#x1B0;&#x1EDB;c &#x111;&#x1EC7;m quan tr&#x1ECD;ng tr&#x1B0;&#x1EDB;c khi b&#x1EA1;n ti&#x1EBF;p c&#x1EAD;n c&#xE1;c kh&#xE1;i ni&#x1EC7;m cao h&#x1A1;n nh&#x1B0; class, object, coroutine hay MVVM trong Android.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m kh&#xF3;a h&#x1ECD;c L&#x1EAD;p tr&#xEC;nh Android, h&#xE3;y truy c&#x1EAD;p li&#xEA;n k&#x1EBF;t ngay &#x111;&#x1EC3; <a href="https://laptrinh-online.vn/"><strong>&#x110;&#x103;ng k&#xFD; ngay t&#x1EA1;i &#x111;&#xE2;y</strong></a><strong> .</strong></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/Lkie5EKlNxw?list=PLc1iBK01_exeCP0mOAgCi6cDbXhRBi1bN" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>&#x110;&#x1EEB;ng qu&#xEA;n theo d&#xF5;i <a href="https://codefresher.vn/"><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong>CodeFresher</strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> </a>&#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t th&#xF4;ng tin m&#x1EDB;i nh&#x1EA5;t v&#x1EC1; c&#xE1;c kh&#xF3;a h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh!</p><p>Link &#x111;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c: <a href="https://laptrinh-online.vn/courses/tat-ca-khoa-hoc">https://laptrinh-online.vn/courses/tat-ca-khoa-hoc</a></p><p>&#x110;&#x1ECB;a ch&#x1EC9;: Trung t&#xE2;m <strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><a href="https://codefresher.vn/">CodeFresher</a></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong></strong> &#x2013; S&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.</p><p>S&#x110;T: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo/call)</p>]]></content:encoded></item><item><title><![CDATA[StatelessWidget, StatefulWidget và một số UI cơ bản trong Flutter]]></title><description><![CDATA[<p><strong><a href="https://codefresher.vn/can-chuan-bi-gi-de-hoc-lap-trinh-mobile-flutter/">Flutter l&#xE0; m&#x1ED9;t framework ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng</a></strong> do Google ph&#xE1;t tri&#x1EC3;n, cho ph&#xE9;p b&#x1EA1;n vi&#x1EBF;t m&#x1ED9;t l&#x1EA7;n</p>]]></description><link>https://laptrinh-online.vn/blog/statelesswidget-statefulwidget-va-mot-so-ui-co-ban-trong-flutter/</link><guid isPermaLink="false">67ffaeac14958c001e7ab958</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Wed, 16 Apr 2025 13:52:44 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/flutter-stateless-vs-stateful-widget.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/flutter-stateless-vs-stateful-widget.jpeg" alt="StatelessWidget, StatefulWidget v&#xE0; m&#x1ED9;t s&#x1ED1; UI c&#x1A1; b&#x1EA3;n trong Flutter"><p><strong><a href="https://codefresher.vn/can-chuan-bi-gi-de-hoc-lap-trinh-mobile-flutter/">Flutter l&#xE0; m&#x1ED9;t framework ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng</a></strong> do Google ph&#xE1;t tri&#x1EC3;n, cho ph&#xE9;p b&#x1EA1;n vi&#x1EBF;t m&#x1ED9;t l&#x1EA7;n v&#xE0; ch&#x1EA1;y &#x111;&#x1B0;&#x1EE3;c tr&#xEA;n Android, iOS, Web v&#xE0; Desktop. Flutter s&#x1EED; d&#x1EE5;ng ng&#xF4;n ng&#x1EEF; Dart, n&#x1ED5;i b&#x1EAD;t v&#x1EDB;i kh&#x1EA3; n&#x103;ng x&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n UI m&#x1ED9;t c&#xE1;ch nhanh ch&#xF3;ng, linh ho&#x1EA1;t v&#xE0; &#x111;&#x1EB9;p m&#x1EAF;t.</p><p>M&#x1ED9;t trong nh&#x1EEF;ng <a href="https://codefresher.vn/flutter-co-the-lam-duoc-gi/"><strong>kh&#xE1;i ni&#x1EC7;m &#x111;&#x1EA7;u ti&#xEA;n</strong></a> b&#x1EA1;n c&#x1EA7;n n&#x1EAF;m khi h&#x1ECD;c Flutter l&#xE0; <code>StatelessWidget</code> v&#xE0; <code>StatefulWidget</code>. &#x110;&#xE2;y l&#xE0; hai ki&#x1EC3;u widget n&#x1EC1;n t&#x1EA3;ng m&#xE0; b&#x1EA1;n s&#x1EBD; l&#xE0;m vi&#x1EC7;c v&#x1EDB;i g&#x1EA7;n nh&#x1B0; m&#x1ECD;i l&#xFA;c khi x&#xE2;y d&#x1EF1;ng UI.</p><h2 id="stateless-v%C3%A0-stateful">Stateless v&#xE0; Stateful</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-28.png" class="kg-image" alt="StatelessWidget, StatefulWidget v&#xE0; m&#x1ED9;t s&#x1ED1; UI c&#x1A1; b&#x1EA3;n trong Flutter" loading="lazy" width="1200" height="700"></figure><p><strong>Flutter</strong> coi m&#x1ECD;i th&#xE0;nh ph&#x1EA7;n tr&#xEA;n m&#xE0;n h&#xEC;nh l&#xE0; widget &#x2013; t&#x1EEB; m&#x1ED9;t n&#xFA;t b&#x1EA5;m, m&#x1ED9;t d&#xF2;ng ch&#x1EEF;, &#x111;&#x1EBF;n to&#xE0;n b&#x1ED9; giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng. Tuy nhi&#xEA;n, kh&#xF4;ng ph&#x1EA3;i widget n&#xE0;o c&#x169;ng gi&#x1ED1;ng nhau.</p><p><strong>StatelessWidget</strong> l&#xE0; lo&#x1EA1;i widget <strong>kh&#xF4;ng thay &#x111;&#x1ED5;i theo th&#x1EDD;i gian</strong>. M&#x1ED9;t khi &#x111;&#x1B0;&#x1EE3;c d&#x1EF1;ng l&#xEA;n, n&#xF3; gi&#x1EEF; nguy&#xEA;n tr&#x1EA1;ng th&#xE1;i v&#xE0; kh&#xF4;ng c&#x1EAD;p nh&#x1EAD;t l&#x1EA1;i. V&#xED; d&#x1EE5; &#x111;i&#x1EC3;n h&#xEC;nh l&#xE0; m&#x1ED9;t bi&#x1EC3;u t&#x1B0;&#x1EE3;ng t&#x129;nh ho&#x1EB7;c d&#xF2;ng ch&#x1EEF; kh&#xF4;ng thay &#x111;&#x1ED5;i.</p><p><strong>StatefulWidget</strong> l&#xE0; widget <strong>c&#xF3; th&#x1EC3; thay &#x111;&#x1ED5;i giao di&#x1EC7;n</strong> trong qu&#xE1; tr&#xEC;nh s&#x1EED; d&#x1EE5;ng, th&#xF4;ng qua vi&#x1EC7;c c&#x1EAD;p nh&#x1EAD;t tr&#x1EA1;ng th&#xE1;i (<code>state</code>). V&#xED; d&#x1EE5;: m&#x1ED9;t c&#xF4;ng t&#x1EAF;c b&#x1EAD;t/t&#x1EAF;t, n&#xFA;t b&#x1EA5;m thay &#x111;&#x1ED5;i m&#xE0;u khi &#x111;&#x1B0;&#x1EE3;c nh&#x1EA5;n, b&#x1ED9; &#x111;&#x1EBF;m s&#x1ED1; l&#x1EA7;n b&#x1EA5;m.</p><p>Hi&#x1EC3;u r&#xF5; s&#x1EF1; kh&#xE1;c nhau gi&#x1EEF;a hai lo&#x1EA1;i widget n&#xE0;y s&#x1EBD; gi&#xFA;p b&#x1EA1;n bi&#x1EBF;t n&#xEA;n s&#x1EED; d&#x1EE5;ng c&#xE1;i n&#xE0;o trong t&#x1EEB;ng t&#xEC;nh hu&#x1ED1;ng c&#x1EE5; th&#x1EC3;, t&#x1EEB; &#x111;&#xF3; t&#x1ED1;i &#x1B0;u hi&#x1EC7;u su&#x1EA5;t v&#xE0; &#x111;&#x1A1;n gi&#x1EA3;n h&#xF3;a logic x&#x1EED; l&#xFD;.</p><h2 id="c%C3%A1ch-t%E1%BA%A1o-m%E1%BB%99t-statefulwidget">C&#xE1;ch t&#x1EA1;o m&#x1ED9;t StatefulWidget</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-29.png" class="kg-image" alt="StatelessWidget, StatefulWidget v&#xE0; m&#x1ED9;t s&#x1ED1; UI c&#x1A1; b&#x1EA3;n trong Flutter" loading="lazy" width="1050" height="700"></figure><p>Khi b&#x1EA1;n c&#x1EA7;n m&#x1ED9;t widget ph&#x1EA3;n h&#x1ED3;i l&#x1EA1;i h&#xE0;nh &#x111;&#x1ED9;ng c&#x1EE7;a ng&#x1B0;&#x1EDD;i d&#xF9;ng ho&#x1EB7;c thay &#x111;&#x1ED5;i khi d&#x1EEF; li&#x1EC7;u thay &#x111;&#x1ED5;i, b&#x1EA1;n s&#x1EBD; c&#x1EA7;n m&#x1ED9;t <code>StatefulWidget</code>. C&#xFA; ph&#xE1;p bao g&#x1ED3;m hai ph&#x1EA7;n: ph&#x1EA7;n widget ch&#xED;nh v&#xE0; ph&#x1EA7;n <code>State</code> qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i.</p><p><code>class MyWidget extends StatefulWidget { </code></p><p><code>@override State&lt;MyWidget&gt; createState() =&gt; _MyWidgetState(); </code></p><p><code>} </code></p><p><code>class _MyWidgetState extends State&lt;MyWidget&gt; </code></p><p><code>{ @override Widget build(BuildContext context) { </code></p><p><code>return Container(); // UI ch&#xED;nh </code></p><p> &#xA0; &#xA0; &#xA0;<code>} </code></p><p><code>}</code></p><p>B&#xEA;n trong l&#x1EDB;p <code>State</code>, b&#x1EA1;n c&#xF3; th&#x1EC3; khai b&#xE1;o c&#xE1;c bi&#x1EBF;n tr&#x1EA1;ng th&#xE1;i v&#xE0; c&#x1EAD;p nh&#x1EAD;t ch&#xFA;ng b&#x1EB1;ng c&#xE1;ch g&#x1ECD;i <code>setState()</code> m&#x1ED7;i khi c&#x1EA7;n d&#x1EF1;ng l&#x1EA1;i giao di&#x1EC7;n.</p><h2 id="qu%E1%BA%A3n-l%C3%BD-state">Qu&#x1EA3;n l&#xFD; state</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-30.png" class="kg-image" alt="StatelessWidget, StatefulWidget v&#xE0; m&#x1ED9;t s&#x1ED1; UI c&#x1A1; b&#x1EA3;n trong Flutter" loading="lazy" width="1600" height="840"></figure><p>Trong Flutter, <strong>UI lu&#xF4;n ph&#x1EA3;n &#xE1;nh tr&#x1EF1;c ti&#x1EBF;p state</strong>. V&#xEC; v&#x1EAD;y, vi&#x1EC7;c qu&#x1EA3;n l&#xFD; state hi&#x1EC7;u qu&#x1EA3; l&#xE0; m&#x1ED9;t ph&#x1EA7;n c&#x1ED1;t l&#xF5;i trong qu&#xE1; tr&#xEC;nh x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng.</p><p>B&#x1EA1;n c&#xF3; th&#x1EC3; qu&#x1EA3;n l&#xFD; state theo nhi&#x1EC1;u c&#xE1;ch, t&#xF9;y v&#xE0;o &#x111;&#x1ED9; ph&#x1EE9;c t&#x1EA1;p c&#x1EE7;a &#x1EE9;ng d&#x1EE5;ng. Trong b&#xE0;i h&#x1ECD;c n&#xE0;y, ta c&#xF9;ng t&#xEC;m hi&#x1EC3;u hai c&#xE1;ch ti&#x1EBF;p c&#x1EAD;n c&#x1A1; b&#x1EA3;n v&#xE0; d&#x1EC5; &#xE1;p d&#x1EE5;ng nh&#x1EA5;t: d&#xF9;ng <code>setState</code> &#x1EDF; c&#x1EA5;p cha, v&#xE0; t&#x1EA1;o widget custom t&#x1EF1; qu&#x1EA3;n l&#xFD;.</p><h2 id="c%C3%A1ch-1-%C4%91%E1%BA%A9y-setstate-l%C3%AAn-l%E1%BB%9Bp-cha">C&#xE1;ch 1: &#x110;&#x1EA9;y setState l&#xEA;n l&#x1EDB;p cha</h2><p>&#x1EDE; ph&#x1B0;&#x1A1;ng ph&#xE1;p n&#xE0;y, widget cha gi&#x1EEF; to&#xE0;n b&#x1ED9; state, c&#xF2;n widget con ch&#x1EC9; nh&#x1EAD;n d&#x1EEF; li&#x1EC7;u v&#xE0; callback t&#x1EEB; cha. &#x110;&#xE2;y l&#xE0; c&#xE1;ch l&#xE0;m r&#xF5; r&#xE0;ng v&#xE0; d&#x1EC5; ki&#x1EC3;m so&#xE1;t khi app c&#xF2;n nh&#x1ECF; ho&#x1EB7;c khi b&#x1EA1;n mu&#x1ED1;n th&#x1ED1;ng nh&#x1EA5;t lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u.</p><p>V&#xED; d&#x1EE5;:</p><p><code>class ParentWidget extends StatefulWidget { ... } </code></p><p><code>class _ParentWidgetState extends State&lt;ParentWidget&gt; { </code></p><p><code>int counter = 0; </code></p><p><code>void increment() { </code></p><p><code>setState(() { </code></p><p><code>counter++; </code></p><p><code>}); </code></p><p><code>}</code></p><p><code>@override Widget build(BuildContext context) { </code></p><p><code>return ChildWidget(onPressed: increment, value: counter);</code></p><p><code> &#xA0; &#xA0;} </code></p><p><code>}</code></p><h2 id="c%C3%A1ch-2-t%E1%BA%A1o-m%E1%BB%99t-widget-custom-t%E1%BB%B1-qu%E1%BA%A3n-l%C3%BD-state">C&#xE1;ch 2: T&#x1EA1;o m&#x1ED9;t widget custom t&#x1EF1; qu&#x1EA3;n l&#xFD; state</h2><p>Khi b&#x1EA1;n mu&#x1ED1;n <strong>&#x111;&#xF3;ng g&#xF3;i ho&#xE0;n to&#xE0;n m&#x1ED9;t t&#xED;nh n&#x103;ng nh&#x1ECF;</strong> v&#xE0;o m&#x1ED9;t widget &#x111;&#x1ED9;c l&#x1EAD;p &#x2013; v&#xED; d&#x1EE5; nh&#x1B0; m&#x1ED9;t n&#xFA;t &quot;Like&quot;, thanh k&#xE9;o, ho&#x1EB7;c form nh&#x1EAD;p li&#x1EC7;u &#x2013; th&#xEC; b&#x1EA1;n c&#xF3; th&#x1EC3; t&#x1EA1;o m&#x1ED9;t <code>StatefulWidget</code> ri&#xEA;ng &#x111;&#x1EC3; t&#x1EF1; qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i c&#x1EE7;a n&#xF3;.</p><p>V&#xED; d&#x1EE5;:</p><p><code>class LikeButton extends StatefulWidget { ... } </code></p><p><code>class _LikeButtonState extends State&lt;LikeButton&gt; { </code></p><p><code>bool isLiked = false; </code></p><p><code>void toggleLike() { </code></p><p><code>setState(() { </code></p><p><code>isLiked = !isLiked; </code></p><p> &#xA0; &#xA0;<code>}); </code></p><p><code>} </code></p><p><code>@override </code></p><p><code>Widget build(BuildContext context) { </code></p><p><code>return IconButton( </code></p><p><code>icon: Icon(isLiked ? Icons.favorite : Icons.favorite_border), </code></p><p><code>onPressed: toggleLike, </code></p><p><code>); </code></p><p> &#xA0; &#xA0; &#xA0;<code>} </code></p><p><code>}</code></p><p>C&#xE1;ch l&#xE0;m n&#xE0;y r&#x1EA5;t g&#x1ECD;n v&#xE0; linh ho&#x1EA1;t, &#x111;&#x1EB7;c bi&#x1EC7;t l&#xE0; khi b&#x1EA1;n mu&#x1ED1;n t&#xE1;i s&#x1EED; d&#x1EE5;ng widget &#x1EDF; nhi&#x1EC1;u n&#x1A1;i kh&#xE1;c nhau m&#xE0; kh&#xF4;ng c&#x1EA7;n quan t&#xE2;m &#x111;&#x1EBF;n tr&#x1EA1;ng th&#xE1;i b&#xEA;n ngo&#xE0;i.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/4h7sD5gaVI8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="StatelessWidget, StatefulWidget c&#x1A1; b&#x1EA3;n v&#xE0; &#x1EE9;ng d&#x1EE5;ng - Kho&#xE1; h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh Flutter 2022"></iframe></figure><h2 id="l%E1%BB%99-tr%C3%ACnh-h%E1%BB%8Dc-flutter-t%E1%BB%AB-c%C6%A1-b%E1%BA%A3n-t%E1%BB%9Bi-n%C3%A2ng-cao-t%E1%BA%A1i-codefresher">L&#x1ED9; tr&#xEC;nh h&#x1ECD;c Flutter t&#x1EEB; c&#x1A1; b&#x1EA3;n t&#x1EDB;i n&#xE2;ng cao t&#x1EA1;i CodeFresher</h2><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang nghi&#xEA;m t&#xFA;c theo &#x111;u&#x1ED5;i Flutter v&#xE0; mu&#x1ED1;n r&#xFA;t ng&#x1EAF;n th&#x1EDD;i gian h&#x1ECD;c, <strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">l&#x1ED9; tr&#xEC;nh h&#x1ECD;c Flutter t&#x1EA1;i CodeFresher</a></strong> l&#xE0; m&#x1ED9;t l&#x1EF1;a ch&#x1ECD;n ph&#xF9; h&#x1EE3;p. L&#x1ED9; tr&#xEC;nh &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; b&#xE0;i b&#x1EA3;n, theo chi&#x1EC1;u s&#xE2;u, gi&#xFA;p b&#x1EA1;n t&#x1EEB;ng b&#x1B0;&#x1EDB;c x&#xE2;y d&#x1EF1;ng k&#x1EF9; n&#x103;ng:</p><ul><li>L&#xE0;m ch&#x1EE7; Dart v&#xE0; Flutter core (widget, layout, state)</li><li>Qu&#x1EA3;n l&#xFD; state v&#x1EDB;i Provider, Riverpod, Bloc</li><li>X&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng ho&#xE0;n ch&#x1EC9;nh: &#x111;a m&#xE0;n h&#xEC;nh, responsive, g&#x1ECD;i API, x&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n</li><li>K&#x1EBF;t n&#x1ED1;i backend, l&#x1B0;u tr&#x1EEF; d&#x1EEF; li&#x1EC7;u, th&#x1EF1;c hi&#x1EC7;n ki&#x1EC3;m th&#x1EED;</li><li>Deploy &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF; l&#xEA;n store</li></ul><p>L&#x1ED9; tr&#xEC;nh kh&#xF4;ng ch&#x1EC9; gi&#xFA;p b&#x1EA1;n <strong>l&#xE0;m &#x111;&#x1B0;&#x1EE3;c</strong>, m&#xE0; c&#xF2;n gi&#xFA;p b&#x1EA1;n <strong>hi&#x1EC3;u s&#xE2;u</strong>, s&#x1EB5;n s&#xE0;ng b&#x1B0;&#x1EDB;c v&#xE0;o m&#xF4;i tr&#x1B0;&#x1EDD;ng l&#xE0;m vi&#x1EC7;c chuy&#xEA;n nghi&#x1EC7;p ho&#x1EB7;c ph&#xE1;t tri&#x1EC3;n s&#x1EA3;n ph&#x1EA9;m ri&#xEA;ng.</p><p><strong>Flutter</strong> &#x111;ang l&#xE0; c&#xF4;ng ngh&#x1EC7; &#x111;&#x1B0;&#x1EE3;c &#x1B0;a chu&#x1ED9;ng b&#x1EDF;i s&#x1EF1; nhanh ch&#xF3;ng, hi&#x1EC7;u qu&#x1EA3; v&#xE0; t&#xED;nh &#x111;a n&#x1EC1;n t&#x1EA3;ng. H&#x1ECD;c v&#x1EEF;ng Flutter h&#xF4;m nay, b&#x1EA1;n s&#x1EBD; c&#xF3; nhi&#x1EC1;u c&#x1A1; h&#x1ED9;i h&#x1A1;n trong t&#x1B0;&#x1A1;ng lai &#x2013; c&#x1EA3; trong ngh&#x1EC1; nghi&#x1EC7;p l&#x1EAB;n s&#x1EA3;n ph&#x1EA9;m c&#xE1; nh&#xE2;n.</p><p><strong>&#x110;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c ngay t&#x1EA1;i</strong>: <a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban</a></p><p><strong><strong>&#x110;&#x1ECB;a ch&#x1EC9;:</strong></strong> <strong>Trung t&#xE2;m <a href="https://codefresher.vn/" rel="noreferrer noopener">CodeFresher</a></strong> &#x2013; s&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.<br><strong><strong>Hotline</strong></strong>: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo / call)</p>]]></content:encoded></item><item><title><![CDATA[Lập trình Dart cơ bản và nâng cao]]></title><description><![CDATA[<p><strong>Dart</strong> l&#xE0; ng&#xF4;n ng&#x1EEF; l&#x1EAD;p tr&#xEC;nh &#x111;&#x1B0;&#x1EE3;c Google ph&#xE1;t tri&#x1EC3;n v&#xE0; s&#x1EED; d&#x1EE5;ng l&#xE0;m n&#x1EC1;n t&#x1EA3;ng ch&#xED;nh cho <strong><a href="https://codefresher.vn/can-chuan-bi-gi-de-hoc-lap-trinh-mobile-flutter/">Flutter &#x2013; b&#x1ED9; c&</a></strong></p>]]></description><link>https://laptrinh-online.vn/blog/lap-trinh-dart-co-ban-va-nang-cao/</link><guid isPermaLink="false">67fe6e1614958c001e7ab904</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Tue, 15 Apr 2025 14:43:58 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/1136387e-106d-462f-8214-6237d64abc2c.webp" medium="image"/><content:encoded><![CDATA[<img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/1136387e-106d-462f-8214-6237d64abc2c.webp" alt="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n v&#xE0; n&#xE2;ng cao"><p><strong>Dart</strong> l&#xE0; ng&#xF4;n ng&#x1EEF; l&#x1EAD;p tr&#xEC;nh &#x111;&#x1B0;&#x1EE3;c Google ph&#xE1;t tri&#x1EC3;n v&#xE0; s&#x1EED; d&#x1EE5;ng l&#xE0;m n&#x1EC1;n t&#x1EA3;ng ch&#xED;nh cho <strong><a href="https://codefresher.vn/can-chuan-bi-gi-de-hoc-lap-trinh-mobile-flutter/">Flutter &#x2013; b&#x1ED9; c&#xF4;ng c&#x1EE5; x&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng</a></strong>. Hi&#x1EC3;u r&#xF5; Dart kh&#xF4;ng ch&#x1EC9; gi&#xFA;p b&#x1EA1;n h&#x1ECD;c Flutter hi&#x1EC7;u qu&#x1EA3; h&#x1A1;n m&#xE0; c&#xF2;n t&#x1EA1;o n&#x1EC1;n m&#xF3;ng v&#x1EEF;ng ch&#x1EAF;c &#x111;&#x1EC3; ph&#xE1;t tri&#x1EC3;n c&#xE1;c &#x1EE9;ng d&#x1EE5;ng c&#xF3; hi&#x1EC7;u su&#x1EA5;t cao v&#xE0; ki&#x1EBF;n tr&#xFA;c t&#x1ED1;t.</p><p>Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; &#x111;i&#x1EC3;m qua m&#x1ED9;t s&#x1ED1; <strong>ki&#x1EBF;n th&#x1EE9;c Dart quan tr&#x1ECD;ng t&#x1EEB; c&#x1A1; b&#x1EA3;n &#x111;&#x1EBF;n n&#xE2;ng cao</strong> &#x2013; t&#x1EAD;p trung v&#xE0;o nh&#x1EEF;ng ch&#x1EE7; &#x111;&#x1EC1; th&#x1B0;&#x1EDD;ng g&#xE2;y b&#x1ED1;i r&#x1ED1;i cho ng&#x1B0;&#x1EDD;i m&#x1EDB;i nh&#x1B0;ng l&#x1EA1;i r&#x1EA5;t c&#x1EA7;n thi&#x1EBF;t n&#x1EBF;u b&#x1EA1;n mu&#x1ED1;n ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF;.</p><h3 id="1-s%E1%BB%AD-d%E1%BB%A5ng-named-parameters-v%C3%A0-optional-parameters-trong-h%C3%A0m">1. S&#x1EED; d&#x1EE5;ng Named Parameters v&#xE0; Optional Parameters trong h&#xE0;m</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-25.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n v&#xE0; n&#xE2;ng cao" loading="lazy" width="1200" height="675"></figure><p>Dart h&#x1ED7; tr&#x1EE3; c&#xE1;c ki&#x1EC3;u tham s&#x1ED1; r&#x1EA5;t linh ho&#x1EA1;t, cho ph&#xE9;p b&#x1EA1;n vi&#x1EBF;t h&#xE0;m d&#x1EC5; &#x111;&#x1ECD;c, d&#x1EC5; b&#x1EA3;o tr&#xEC;. &#x110;&#x1EB7;c bi&#x1EC7;t l&#xE0; hai ki&#x1EC3;u: <strong>Named Parameters</strong> v&#xE0; <strong>Optional Parameters</strong>.</p><h4 id="named-parameters">Named Parameters</h4><p>&#x110;&#xE2;y l&#xE0; c&#xE1;ch truy&#x1EC1;n tham s&#x1ED1; theo t&#xEA;n. R&#x1EA5;t ph&#xF9; h&#x1EE3;p khi b&#x1EA1;n c&#xF3; nhi&#x1EC1;u gi&#xE1; tr&#x1ECB; kh&#xF4;ng b&#x1EAF;t bu&#x1ED9;c, gi&#xFA;p h&#xE0;m r&#xF5; r&#xE0;ng v&#xE0; tr&#xE1;nh l&#x1ED7;i khi truy&#x1EC1;n sai th&#x1EE9; t&#x1EF1;.</p><p><code>void createUser({required String name, int age = 18}) { </code></p><p><code>print(&apos;Name: $name, Age: $age&apos;); </code></p><p><code>} </code></p><p><code>createUser(name: &apos;An&apos;); // Age m&#x1EB7;c &#x111;&#x1ECB;nh l&#xE0; 18</code></p><h4 id="optional-positional-parameters">Optional Positional Parameters</h4><p>D&#xF9;ng khi b&#x1EA1;n mu&#x1ED1;n c&#xE1;c tham s&#x1ED1; c&#xF3; th&#x1EC3; b&#x1ECF; qua nh&#x1B0;ng v&#x1EAB;n theo th&#x1EE9; t&#x1EF1;.</p><p><code>void sayHello([String? name]) {</code></p><p><code>print(&apos;Hello, ${name ?? &apos;guest&apos;}&apos;); </code></p><p><code>} </code></p><p><code>sayHello(); // Hello, guest</code></p><p><strong>L&#x1B0;u &#xFD; quan tr&#x1ECD;ng:</strong> Dart y&#xEA;u c&#x1EA7;u b&#x1EA1;n x&#x1EED; l&#xFD; <code>null</code> r&#xF5; r&#xE0;ng &#x2013; &#x111;i&#x1EC1;u n&#xE0;y r&#x1EA5;t h&#x1EEF;u &#xED;ch khi x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng ch&#x1EAF;c ch&#x1EAF;n, tr&#xE1;nh l&#x1ED7;i runtime.</p><h3 id="2-l%C3%A0m-vi%E1%BB%87c-v%E1%BB%9Bi-class-v%C3%A0-oop-trong-dart">2. L&#xE0;m vi&#x1EC7;c v&#x1EDB;i Class v&#xE0; OOP trong Dart</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-27.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n v&#xE0; n&#xE2;ng cao" loading="lazy" width="1280" height="720"></figure><p>Dart h&#x1ED7; tr&#x1EE3; &#x111;&#x1EA7;y &#x111;&#x1EE7; c&#xE1;c t&#xED;nh n&#x103;ng l&#x1EAD;p tr&#xEC;nh h&#x1B0;&#x1EDB;ng &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng: class, inheritance, mixins, interface...</p><h4 id="khai-b%C3%A1o-class-c%C6%A1-b%E1%BA%A3n">Khai b&#xE1;o class c&#x1A1; b&#x1EA3;n:</h4><p><code>class User { </code></p><p><code>String name; </code></p><p><code>int age; </code></p><p><code>User(this.name, this.age); </code></p><p><code>void greet() { </code></p><p><code>print(&apos;Hello, I am $name&apos;); </code></p><p> &#xA0; &#xA0;<code>} </code></p><p><code>}</code></p><h4 id="k%E1%BA%BF-th%E1%BB%ABa">K&#x1EBF; th&#x1EEB;a:</h4><p><code>class Admin extends User { </code></p><p><code>Admin(String name, int age) : super(name, age); </code></p><p><code>void manage() { </code></p><p><code>print(&apos;$name is managing...&apos;); </code></p><p> &#xA0; &#xA0; &#xA0;<code>} </code></p><p><code>}</code></p><h4 id="getter-setter-constructor-t%C3%B9y-bi%E1%BA%BFn-static-method%E2%80%A6">Getter, Setter, Constructor t&#xF9;y bi&#x1EBF;n, Static Method&#x2026;</h4><p>Dart cho ph&#xE9;p tu&#x1EF3; bi&#x1EBF;n r&#x1EA5;t nhi&#x1EC1;u, gi&#xFA;p b&#x1EA1;n x&#xE2;y d&#x1EF1;ng m&#xF4; h&#xEC;nh d&#x1EEF; li&#x1EC7;u v&#xE0; logic kinh doanh theo c&#xE1;ch linh ho&#x1EA1;t m&#xE0; v&#x1EAB;n d&#x1EC5; ki&#x1EC3;m so&#xE1;t.</p><p>N&#x1EBF;u b&#x1EA1;n &#x111;&#xE3; quen v&#x1EDB;i Java ho&#x1EB7;c C#, c&#xFA; ph&#xE1;p Dart s&#x1EBD; r&#x1EA5;t th&#xE2;n thi&#x1EC7;n. N&#x1EBF;u b&#x1EA1;n m&#x1EDB;i b&#x1EAF;t &#x111;&#x1EA7;u l&#x1EAD;p tr&#xEC;nh, &#x111;&#xE2;y l&#xE0; c&#x1A1; h&#x1ED9;i tuy&#x1EC7;t v&#x1EDD;i &#x111;&#x1EC3; h&#x1ECD;c OOP m&#x1ED9;t c&#xE1;ch b&#xE0;i b&#x1EA3;n nh&#x1B0;ng kh&#xF4;ng qu&#xE1; ph&#x1EE9;c t&#x1EA1;p.</p><h3 id="3-l%E1%BA%ADp-tr%C3%ACnh-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99-asynchronous-programming">3. L&#x1EAD;p tr&#xEC;nh b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9; (Asynchronous Programming)</h3><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-26.png" class="kg-image" alt="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n v&#xE0; n&#xE2;ng cao" loading="lazy" width="640" height="480"></figure><p>Trong m&#xF4;i tr&#x1B0;&#x1EDD;ng &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF;, &#x111;&#x1EB7;c bi&#x1EC7;t l&#xE0; mobile/web &#x2013; ph&#x1EA7;n l&#x1EDB;n c&#xF4;ng vi&#x1EC7;c l&#xE0; x&#x1EED; l&#xFD; b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9;: g&#x1ECD;i API, &#x111;&#x1ECD;c file, ch&#x1EDD; k&#x1EBF;t qu&#x1EA3; t&#x1EEB; server, v.v.</p><p>Dart cung c&#x1EA5;p c&#xE1;c c&#xF4;ng c&#x1EE5; m&#x1EA1;nh m&#x1EBD; &#x111;&#x1EC3; l&#xE0;m vi&#x1EC7;c b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9;:</p><p><code>Future</code>: &#x111;&#x1EA1;i di&#x1EC7;n cho m&#x1ED9;t gi&#xE1; tr&#x1ECB; c&#xF3; th&#x1EC3; c&#xF3; trong t&#x1B0;&#x1A1;ng lai.</p><p><code>async/await</code>: c&#xFA; ph&#xE1;p gi&#xFA;p vi&#x1EBF;t code b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9; r&#xF5; r&#xE0;ng nh&#x1B0; &#x111;&#x1ED3;ng b&#x1ED9;.</p><p><code>Stream</code>: x&#x1EED; l&#xFD; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u li&#xEA;n t&#x1EE5;c (v&#xED; d&#x1EE5;: s&#x1EF1; ki&#x1EC7;n UI, d&#x1EEF; li&#x1EC7;u t&#x1EEB; socket&#x2026;).</p><h4 id="v%C3%AD-d%E1%BB%A5-d%C3%B9ng-asyncawait">V&#xED; d&#x1EE5; d&#xF9;ng async/await:</h4><p><code>Future&lt;String&gt; fetchData() async { </code></p><p><code>await Future.delayed(Duration(seconds: 2)); </code></p><p><code>return &apos;Data loaded&apos;; </code></p><p><code>} </code></p><p><code>void main() async { </code></p><p><code>print(&apos;Loading...&apos;); </code></p><p><code>String data = await fetchData(); </code></p><p><code>print(data); </code></p><p><code>}</code></p><p>B&#x1EB1;ng c&#xE1;ch s&#x1EED; d&#x1EE5;ng b&#x1EA5;t &#x111;&#x1ED3;ng b&#x1ED9; &#x111;&#xFA;ng c&#xE1;ch, b&#x1EA1;n s&#x1EBD; tr&#xE1;nh &#x111;&#x1B0;&#x1EE3;c hi&#x1EC7;n t&#x1B0;&#x1EE3;ng &#x201C;&#x1EE9;ng d&#x1EE5;ng treo&#x201D;, &#x111;&#x1ED3;ng th&#x1EDD;i t&#x1ED1;i &#x1B0;u tr&#x1EA3;i nghi&#x1EC7;m ng&#x1B0;&#x1EDD;i d&#xF9;ng.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/-cRceXfGpv8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n 2022 - B&#xE0;i 1.1 - Khai b&#xE1;o v&#xE0; s&#x1EED; d&#x1EE5;ng bi&#x1EBF;n, h&#xE0;m trong Dart"></iframe></figure><h2 id="k%E1%BA%BFt-lu%E1%BA%ADn-n%E1%BA%AFm-v%E1%BB%AFng-dart-l%C3%A0-b%C6%B0%E1%BB%9Bc-kh%E1%BB%9Fi-%C4%91%E1%BA%A7u-%C4%91%E1%BB%83-l%C3%A0m-ch%E1%BB%A7-flutter">K&#x1EBF;t lu&#x1EAD;n: N&#x1EAF;m v&#x1EEF;ng Dart l&#xE0; b&#x1B0;&#x1EDB;c kh&#x1EDF;i &#x111;&#x1EA7;u &#x111;&#x1EC3; l&#xE0;m ch&#x1EE7; Flutter</h2><p>Dart kh&#xF4;ng ch&#x1EC9; l&#xE0; &quot;ng&#xF4;n ng&#x1EEF; b&#x1EAF;t bu&#x1ED9;c&quot; khi h&#x1ECD;c Flutter. Vi&#x1EC7;c hi&#x1EC3;u v&#xE0; s&#x1EED; d&#x1EE5;ng th&#xE0;nh th&#x1EA1;o Dart s&#x1EBD; gi&#xFA;p b&#x1EA1;n:</p><ul><li>Vi&#x1EBF;t code r&#xF5; r&#xE0;ng, d&#x1EC5; m&#x1EDF; r&#x1ED9;ng</li><li>X&#xE2;y d&#x1EF1;ng ki&#x1EBF;n tr&#xFA;c &#x1EE9;ng d&#x1EE5;ng chu&#x1EA9;n ch&#x1EC9;nh</li><li>Tr&#xE1;nh l&#x1ED7;i runtime, n&#xE2;ng cao &#x111;&#x1ED9; &#x1ED5;n &#x111;&#x1ECB;nh</li><li>H&#x1ECD;c Flutter nhanh h&#x1A1;n, ti&#x1EBF;p c&#x1EAD;n &#x111;&#x1B0;&#x1EE3;c c&#xE1;c ki&#x1EBF;n th&#x1EE9;c n&#xE2;ng cao s&#x1EDB;m h&#x1A1;n</li></ul><h2 id="tham-gia-kh%C3%B3a-h%E1%BB%8Dc-flutter-t%E1%BB%AB-c%C6%A1-b%E1%BA%A3n-%C4%91%E1%BA%BFn-th%E1%BB%B1c-chi%E1%BA%BFn">Tham gia kh&#xF3;a h&#x1ECD;c Flutter: T&#x1EEB; c&#x1A1; b&#x1EA3;n &#x111;&#x1EBF;n th&#x1EF1;c chi&#x1EBF;n</h2><p>N&#x1EBF;u b&#x1EA1;n &#x111;ang mu&#x1ED1;n ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng di &#x111;&#x1ED9;ng hi&#x1EC7;n &#x111;&#x1EA1;i, ho&#x1EB7;c kh&#xE1;m ph&#xE1; Flutter m&#x1ED9;t c&#xE1;ch b&#xE0;i b&#x1EA3;n, kh&#xF3;a h&#x1ECD;c <strong><a href="https://codefresher.vn/khoa-lap-trinh-flutter-co-ban/">L&#x1EAD;p tr&#xEC;nh Flutter to&#xE0;n t&#x1EAD;p</a></strong> s&#x1EBD; gi&#xFA;p b&#x1EA1;n:</p><ul><li>N&#x1EAF;m v&#x1EEF;ng n&#x1EC1;n t&#x1EA3;ng Dart v&#xE0; l&#x1EAD;p tr&#xEC;nh h&#x1B0;&#x1EDB;ng &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng</li><li>Th&#xE0;nh th&#x1EA1;o Flutter v&#x1EDB;i d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF; nh&#x1B0;: app du l&#x1ECB;ch, m&#x1EA1;ng x&#xE3; h&#x1ED9;i mini, clone Tiktok</li><li>Hi&#x1EC3;u r&#xF5; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u, qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i, g&#x1ECD;i API v&#xE0; t&#x1ED1;i &#x1B0;u hi&#x1EC7;u n&#x103;ng</li><li>X&#xE2;y d&#x1EF1;ng &#x111;&#x1B0;&#x1EE3;c s&#x1EA3;n ph&#x1EA9;m &#x111;&#x1EA7;u tay c&#xF3; th&#x1EC3; &#x111;&#x1B0;a l&#xEA;n App Store/Play Store</li></ul><p>Kh&#xF3;a h&#x1ECD;c &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; t&#x1EEB; c&#x1A1; b&#x1EA3;n &#x111;&#x1EBF;n n&#xE2;ng cao, c&#xF3; &#x111;&#x1ECB;nh h&#x1B0;&#x1EDB;ng th&#x1EF1;c ti&#x1EC5;n, gi&#xFA;p b&#x1EA1;n h&#x1ECD;c &#x111;&#xFA;ng tr&#x1ECD;ng t&#xE2;m v&#xE0; c&#xF3; th&#x1EC3; &#xE1;p d&#x1EE5;ng ngay sau m&#x1ED7;i b&#xE0;i h&#x1ECD;c.</p><p><strong>B&#x1EA1;n &#x111;&#xE3; s&#x1EB5;n s&#xE0;ng vi&#x1EBF;t &#x1EE9;ng d&#x1EE5;ng Flutter &#x111;&#x1EA7;u ti&#xEA;n c&#x1EE7;a m&#xEC;nh ch&#x1B0;a?</strong><br><strong>&#x110;&#x103;ng k&#xFD; kh&#xF3;a h&#x1ECD;c ngay t&#x1EA1;i</strong>: <a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban</a></p><p><strong><strong>&#x110;&#x1ECB;a ch&#x1EC9;:</strong></strong> <strong>Trung t&#xE2;m <a href="https://codefresher.vn/" rel="noreferrer noopener">CodeFresher</a></strong> &#x2013; s&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.<br><strong><strong>Hotline</strong></strong>: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo / call)</p>]]></content:encoded></item><item><title><![CDATA[Giới Thiệu Lập Trình Dart Cơ Bản - Khám Phá Null Safety và Lazy Initialization]]></title><description><![CDATA[<h3 id="b%E1%BA%AFt-%C4%91%E1%BA%A7u-v%E1%BB%9Bi-dartng%C3%B4n-ng%E1%BB%AF-l%E1%BA%ADp-tr%C3%ACnh-hi%E1%BB%87n-%C4%91%E1%BA%A1i">B&#x1EAF;t &#x110;&#x1EA7;u V&#x1EDB;i Dart - Ng&#xF4;n Ng&#x1EEF; L&#x1EAD;p Tr&#xEC;nh Hi&#x1EC7;n &#x110;&#x1EA1;i</h3><p>Ch&#xE0;o b&#x1EA1;n &#x111;&#x1EBF;n v&#x1EDB;i th&#x1EBF; gi&#x1EDB;i l&#x1EAD;p tr&#xEC;</p>]]></description><link>https://laptrinh-online.vn/blog/gioi-thieu-lap-trinh-dart-co-ban-kham-pha-null-safety-va-lazy-initialization/</link><guid isPermaLink="false">67fd08be14958c001e7ab86a</guid><dc:creator><![CDATA[Duy Lê]]></dc:creator><pubDate>Mon, 14 Apr 2025 14:10:13 GMT</pubDate><media:content url="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-21-1.png" medium="image"/><content:encoded><![CDATA[<h3 id="b%E1%BA%AFt-%C4%91%E1%BA%A7u-v%E1%BB%9Bi-dartng%C3%B4n-ng%E1%BB%AF-l%E1%BA%ADp-tr%C3%ACnh-hi%E1%BB%87n-%C4%91%E1%BA%A1i">B&#x1EAF;t &#x110;&#x1EA7;u V&#x1EDB;i Dart - Ng&#xF4;n Ng&#x1EEF; L&#x1EAD;p Tr&#xEC;nh Hi&#x1EC7;n &#x110;&#x1EA1;i</h3><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-21-1.png" alt="Gi&#x1EDB;i Thi&#x1EC7;u L&#x1EAD;p Tr&#xEC;nh Dart C&#x1A1; B&#x1EA3;n - Kh&#xE1;m Ph&#xE1; Null Safety v&#xE0; Lazy Initialization"><p>Ch&#xE0;o b&#x1EA1;n &#x111;&#x1EBF;n v&#x1EDB;i th&#x1EBF; gi&#x1EDB;i l&#x1EAD;p tr&#xEC;nh Dart! N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m m&#x1ED9;t ng&#xF4;n ng&#x1EEF; m&#x1EA1;nh m&#x1EBD;, d&#x1EC5; h&#x1ECD;c v&#xE0; ph&#xF9; h&#x1EE3;p &#x111;&#x1EC3; <a href="https://codefresher.vn/react-native-vs-flutter-nen-hoc-cai-nao-de-phat-trien-ung-dung-di-dong/"><strong>ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng &#x111;a n&#x1EC1;n t&#x1EA3;ng</strong></a> (nh&#x1B0; Flutter), th&#xEC; Dart ch&#xED;nh l&#xE0; l&#x1EF1;a ch&#x1ECD;n l&#xFD; t&#x1B0;&#x1EDF;ng. Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; c&#xF9;ng kh&#xE1;m ph&#xE1; nh&#x1EEF;ng n&#x1ED9;i dung c&#x1A1; b&#x1EA3;n t&#x1EEB; bu&#x1ED5;i h&#x1ECD;c v&#x1EC1; l&#x1EAD;p tr&#xEC;nh Dart, t&#x1EAD;p trung v&#xE0;o <strong>Null Safety</strong>, <strong>Lazy Initialization</strong> v&#xE0; t&#x1EEB; kh&#xF3;a late. &#x110;&#xE2;y l&#xE0; nh&#x1EEF;ng ki&#x1EBF;n th&#x1EE9;c n&#x1EC1;n t&#x1EA3;ng gi&#xFA;p b&#x1EA1;n v&#x1EEF;ng b&#x1B0;&#x1EDB;c tr&#xEA;n h&#xE0;nh tr&#xEC;nh tr&#x1EDF; th&#xE0;nh l&#x1EAD;p tr&#xEC;nh vi&#xEA;n chuy&#xEA;n nghi&#x1EC7;p.</p><p>H&#xE3;y c&#xF9;ng b&#x1EAF;t &#x111;&#x1EA7;u n&#xE0;o!</p><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-24.png" class="kg-image" alt="Gi&#x1EDB;i Thi&#x1EC7;u L&#x1EAD;p Tr&#xEC;nh Dart C&#x1A1; B&#x1EA3;n - Kh&#xE1;m Ph&#xE1; Null Safety v&#xE0; Lazy Initialization" loading="lazy" width="1200" height="700"></figure><p>Trong bu&#x1ED5;i h&#x1ECD;c n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; t&#xEC;m hi&#x1EC3;u c&#xE1;c kh&#xE1;i ni&#x1EC7;m quan tr&#x1ECD;ng c&#x1EE7;a Dart, bao g&#x1ED3;m:</p><ol><li><strong>Null Safety</strong>: M&#x1ED9;t t&#xED;nh n&#x103;ng &#x111;&#x1ED9;t ph&#xE1; gi&#xFA;p l&#x1EAD;p tr&#xEC;nh vi&#xEA;n tr&#xE1;nh &#x111;&#x1B0;&#x1EE3;c c&#xE1;c l&#x1ED7;i li&#xEA;n quan &#x111;&#x1EBF;n gi&#xE1; tr&#x1ECB; null.</li><li><strong>Lazy Initialization v&#xE0; t&#x1EEB; kh&#xF3;a late</strong>: C&#xE1;ch t&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC7;u su&#x1EA5;t b&#x1EB1;ng c&#xE1;ch tr&#xEC; ho&#xE3;n vi&#x1EC7;c kh&#x1EDF;i t&#x1EA1;o bi&#x1EBF;n.</li><li><strong>Code m&#x1EAB;u th&#x1EF1;c t&#x1EBF;</strong>: M&#x1ED9;t v&#xED; d&#x1EE5; minh h&#x1ECD;a &#x111;&#x1EC3; b&#x1EA1;n d&#x1EC5; d&#xE0;ng &#xE1;p d&#x1EE5;ng ki&#x1EBF;n th&#x1EE9;c.</li></ol><p>Bu&#x1ED5;i h&#x1ECD;c n&#xE0;y &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; d&#xE0;nh cho c&#x1EA3; ng&#x1B0;&#x1EDD;i m&#x1EDB;i b&#x1EAF;t &#x111;&#x1EA7;u l&#x1EAB;n nh&#x1EEF;ng ai mu&#x1ED1;n n&#xE2;ng cao k&#x1EF9; n&#x103;ng l&#x1EAD;p tr&#xEC;nh Dart. N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m m&#x1ED9;t kh&#xF3;a h&#x1ECD;c &#x111;&#x1EA7;y &#x111;&#x1EE7; &#x111;&#x1EC3; th&#xE0;nh th&#x1EA1;o Dart v&#xE0; Flutter, h&#xE3;y kh&#xE1;m ph&#xE1; kh&#xF3;a h&#x1ECD;c c&#x1EE7;a ch&#xFA;ng t&#xF4;i t&#x1EA1;i cu&#x1ED1;i b&#xE0;i!</p><h2 id="null-safety-trong-dart">Null safety trong Dart</h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-22.png" class="kg-image" alt="Gi&#x1EDB;i Thi&#x1EC7;u L&#x1EAD;p Tr&#xEC;nh Dart C&#x1A1; B&#x1EA3;n - Kh&#xE1;m Ph&#xE1; Null Safety v&#xE0; Lazy Initialization" loading="lazy" width="1268" height="702"></figure><p>Null safety l&#xE0; t&#xED;nh n&#x103;ng cho ph&#xE9;p Dart ph&#xE2;n bi&#x1EC7;t r&#xF5; r&#xE0;ng gi&#x1EEF;a m&#x1ED9;t bi&#x1EBF;n c&#xF3; th&#x1EC3; c&#xF3; gi&#xE1; tr&#x1ECB; <code>null</code> v&#xE0; m&#x1ED9;t bi&#x1EBF;n kh&#xF4;ng th&#x1EC3; <code>null</code>. &#x110;i&#x1EC1;u n&#xE0;y gi&#xFA;p gi&#x1EA3;m thi&#x1EC3;u &#x111;&#xE1;ng k&#x1EC3; c&#xE1;c l&#x1ED7;i li&#xEA;n quan &#x111;&#x1EBF;n dereferencing m&#x1ED9;t bi&#x1EBF;n <code>null</code>.</p><p>C&#xFA; ph&#xE1;p:</p><p><code>String name = &apos;Dart&apos;; &#xA0; &#xA0; &#xA0; &#xA0;// Kh&#xF4;ng th&#x1EC3; null </code></p><p><code>String? nickname; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;// C&#xF3; th&#x1EC3; null</code></p><p>Dart y&#xEA;u c&#x1EA7;u b&#x1EA1;n x&#x1EED; l&#xFD; r&#xF5; r&#xE0;ng c&#xE1;c tr&#x1B0;&#x1EDD;ng h&#x1EE3;p c&#xF3; th&#x1EC3; <code>null</code>, gi&#xFA;p t&#x103;ng &#x111;&#x1ED9; tin c&#x1EAD;y cho ch&#x1B0;&#x1A1;ng tr&#xEC;nh v&#xE0; c&#x1EA3;i thi&#x1EC7;n tr&#x1EA3;i nghi&#x1EC7;m ph&#xE1;t tri&#x1EC3;n.</p><h2 id="c%C6%A1-ch%E1%BA%BF-lazy-initialization-v%C3%A0-t%E1%BB%AB-kh%C3%B3a-late">C&#x1A1; ch&#x1EBF; lazy initialization v&#xE0; t&#x1EEB; kh&#xF3;a <code>late</code></h2><figure class="kg-card kg-image-card"><img src="https://cdn-s.hoolacdn.com/daotaotester-18154-1fa76n8o6/sgp1/blog/2025/04/image-23.png" class="kg-image" alt="Gi&#x1EDB;i Thi&#x1EC7;u L&#x1EAD;p Tr&#xEC;nh Dart C&#x1A1; B&#x1EA3;n - Kh&#xE1;m Ph&#xE1; Null Safety v&#xE0; Lazy Initialization" loading="lazy" width="640" height="480"></figure><p>Trong m&#x1ED9;t s&#x1ED1; t&#xEC;nh hu&#x1ED1;ng, b&#x1EA1;n mu&#x1ED1;n khai b&#xE1;o m&#x1ED9;t bi&#x1EBF;n m&#xE0; kh&#xF4;ng g&#xE1;n gi&#xE1; tr&#x1ECB; ngay l&#x1EAD;p t&#x1EE9;c &#x2013; v&#xED; d&#x1EE5;, khi gi&#xE1; tr&#x1ECB; &#x111;&#xF3; ph&#x1EE5; thu&#x1ED9;c v&#xE0;o m&#x1ED9;t t&#xE1;c v&#x1EE5; t&#x1ED1;n th&#x1EDD;i gian ho&#x1EB7;c &#x111;&#x1B0;&#x1EE3;c x&#xE1;c &#x111;&#x1ECB;nh sau khi kh&#x1EDF;i t&#x1EA1;o &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng.</p><p>T&#x1EEB; kh&#xF3;a <code>late</code> cho ph&#xE9;p b&#x1EA1;n tr&#xEC; ho&#xE3;n vi&#x1EC7;c kh&#x1EDF;i t&#x1EA1;o gi&#xE1; tr&#x1ECB; cho m&#x1ED9;t bi&#x1EBF;n, nh&#x1B0;ng v&#x1EAB;n &#x111;&#x1EA3;m b&#x1EA3;o r&#x1EB1;ng n&#xF3; kh&#xF4;ng b&#x1ECB; <code>null</code> khi &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng.</p><p>V&#xED; d&#x1EE5;:</p><p><code>late String description; </code></p><p><code>void setup() {</code></p><p><code>description = &apos;This is initialized later.&apos;; </code></p><p><code>}</code></p><p>N&#x1EBF;u b&#x1EA1;n c&#x1ED1; s&#x1EED; d&#x1EE5;ng <code>description</code> tr&#x1B0;&#x1EDB;c khi n&#xF3; &#x111;&#x1B0;&#x1EE3;c g&#xE1;n gi&#xE1; tr&#x1ECB;, Dart s&#x1EBD; b&#xE1;o l&#x1ED7;i t&#x1EA1;i runtime. &#x110;i&#x1EC1;u n&#xE0;y gi&#xFA;p ph&#xE1;t hi&#x1EC7;n s&#x1EDB;m l&#x1ED7;i logic trong qu&#xE1; tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n.</p><h2 id="code-m%E1%BA%ABu-lesson2dart">Code m&#x1EAB;u: <code>lesson2.dart</code></h2><p><code>void main() {</code></p><p><code>// Null safety</code></p><p><code>String name = &apos;Dart&apos;; </code></p><p><code>String? nickname; </code></p><p><code>print(&apos;Name: $name&apos;); </code></p><p><code>print(&apos;Nickname: ${nickname ?? &apos;Kh&#xF4;ng c&#xF3;&apos;}&apos;); </code></p><p><code>// Lazy initialization </code></p><p><code>late String message;</code></p><p><code>message = createMessage(); </code></p><p><code>print(message); </code></p><p><code>} </code></p><p><code>String createMessage() </code></p><p><code>{ </code></p><p><code>print(&apos;Creating message...&apos;); </code></p><p><code>return &apos;Welcome to Dart lesson 2!&apos;; </code></p><p><code>}</code></p><p>Trong &#x111;o&#x1EA1;n code tr&#xEA;n, b&#x1EA1;n s&#x1EBD; th&#x1EA5;y &#x111;&#x1B0;&#x1EE3;c c&#xE1;ch Dart x&#x1EED; l&#xFD; gi&#xE1; tr&#x1ECB; <code>null</code>, c&#x169;ng nh&#x1B0; c&#x1A1; ch&#x1EBF; tr&#xEC; ho&#xE3;n kh&#x1EDF;i t&#x1EA1;o c&#x1EE7;a bi&#x1EBF;n <code>message</code>.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/YWo9JBk-AQo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="L&#x1EAD;p tr&#xEC;nh Dart c&#x1A1; b&#x1EA3;n - B&#xE0;i 2 (Video full) - Null Safety, t&#x1EEB; kh&#xF3;a late"></iframe></figure><h2 id="t%E1%BB%95ng-k%E1%BA%BFt-b%C3%A0i-h%E1%BB%8Dc">T&#x1ED5;ng k&#x1EBF;t b&#xE0;i h&#x1ECD;c</h2><!--kg-card-begin: html--><table class="min-w-full" data-start="4232" data-end="4832"><thead data-start="4232" data-end="4332"><tr data-start="4232" data-end="4332"><th data-start="4232" data-end="4257">N&#x1ED9;i dung</th><th data-start="4257" data-end="4332">&#xDD; ngh&#x129;a</th></tr></thead><tbody data-start="4433" data-end="4832"><tr data-start="4433" data-end="4532"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4433" data-end="4458">Null safety</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)] min-w-[calc(var(--thread-content-max-width)/3)]" data-start="4458" data-end="4532">B&#x1EA3;o v&#x1EC7; ch&#x1B0;&#x1A1;ng tr&#xEC;nh kh&#x1ECF;i l&#x1ED7;i khi l&#xE0;m vi&#x1EC7;c v&#x1EDB;i bi&#x1EBF;n <code data-start="4511" data-end="4517">null</code></td></tr><tr data-start="4533" data-end="4632"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4533" data-end="4558">D&#x1EA5;u <code data-start="4539" data-end="4542">?</code> v&#xE0; <code data-start="4546" data-end="4550">??</code></td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)] min-w-[calc(var(--thread-content-max-width)/3)]" data-start="4558" data-end="4632">Ki&#x1EC3;m so&#xE1;t bi&#x1EBF;n c&#xF3; th&#x1EC3; null, cung c&#x1EA5;p gi&#xE1; tr&#x1ECB; thay th&#x1EBF; khi c&#x1EA7;n</td></tr><tr data-start="4633" data-end="4732"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4633" data-end="4658">Lazy initialization</td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)] min-w-[calc(var(--thread-content-max-width)/3)]" data-start="4658" data-end="4732">Tr&#xEC; ho&#xE3;n vi&#x1EC7;c kh&#x1EDF;i t&#x1EA1;o &#x111;&#x1EC3; t&#x1ED1;i &#x1B0;u hi&#x1EC7;u su&#x1EA5;t</td></tr><tr data-start="4733" data-end="4832"><td class="max-w-[calc(var(--thread-content-max-width)*2/3)]" data-start="4733" data-end="4758">T&#x1EEB; kh&#xF3;a <code data-start="4743" data-end="4749">late</code></td><td class="max-w-[calc(var(--thread-content-max-width)*2/3)] min-w-[calc(var(--thread-content-max-width)/3)]" data-start="4758" data-end="4832">Cho ph&#xE9;p khai b&#xE1;o bi&#x1EBF;n non-nullable m&#xE0; kh&#x1EDF;i t&#x1EA1;o sau</td></tr></tbody></table><!--kg-card-end: html--><p>B&#xE0;i h&#x1ECD;c h&#xF4;m nay gi&#xFA;p b&#x1EA1;n l&#xE0;m quen v&#x1EDB;i c&#xE1;c t&#xED;nh n&#x103;ng hi&#x1EC7;n &#x111;&#x1EA1;i trong Dart nh&#x1B0; <strong>null safety</strong>, <strong>lazy initialization</strong>, v&#xE0; t&#x1EEB; kh&#xF3;a <code>late</code> &#x2013; nh&#x1EEF;ng y&#x1EBF;u t&#x1ED1; quan tr&#x1ECD;ng &#x111;&#x1EC3; vi&#x1EBF;t code an to&#xE0;n, t&#x1ED1;i &#x1B0;u v&#xE0; d&#x1EC5; b&#x1EA3;o tr&#xEC;.</p><p>&#x110;&#xE2;y m&#x1EDB;i ch&#x1EC9; l&#xE0; b&#x1B0;&#x1EDB;c kh&#x1EDF;i &#x111;&#x1EA7;u tr&#xEA;n h&#xE0;nh tr&#xEC;nh kh&#xE1;m ph&#xE1; Dart. N&#x1EBF;u b&#x1EA1;n &#x111;ang t&#xEC;m ki&#x1EBF;m m&#x1ED9;t l&#x1ED9; tr&#xEC;nh h&#x1ECD;c b&#xE0;i b&#x1EA3;n, c&#xF3; c&#x1EA5;u tr&#xFA;c r&#xF5; r&#xE0;ng t&#x1EEB; c&#x1A1; b&#x1EA3;n &#x111;&#x1EBF;n n&#xE2;ng cao, kh&#xF3;a h&#x1ECD;c <strong><a href="https://laptrinh-online.vn/course/lap-trinh-flutter-co-ban">L&#x1EAD;p tr&#xEC;nh Dart &amp; Flutter t&#x1EEB; &#x111;&#x1EA7;u</a></strong> s&#x1EBD; &#x111;&#x1ED3;ng h&#xE0;nh c&#xF9;ng b&#x1EA1;n trong su&#x1ED1;t qu&#xE1; tr&#xEC;nh:</p><ul><li>H&#x1EC7; th&#x1ED1;ng b&#xE0;i h&#x1ECD;c t&#x1EEB;ng b&#x1B0;&#x1EDB;c, b&#xE1;m s&#xE1;t th&#x1EF1;c t&#x1EBF;</li><li>K&#x1EBF;t h&#x1EE3;p l&#xFD; thuy&#x1EBF;t v&#xE0; th&#x1EF1;c h&#xE0;nh qua d&#x1EF1; &#xE1;n m&#x1EAB;u</li><li>Gi&#x1EA3;i th&#xED;ch chi ti&#x1EBF;t c&#xE1;c kh&#xE1;i ni&#x1EC7;m c&#x1ED1;t l&#xF5;i, kh&#xF4;ng b&#x1ECF; s&#xF3;t ng&#x1B0;&#x1EDD;i m&#x1EDB;i</li></ul><p>Kh&#xF3;a h&#x1ECD;c &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; cho nh&#x1EEF;ng ai mu&#x1ED1;n <strong>n&#x1EAF;m v&#x1EEF;ng n&#x1EC1;n t&#x1EA3;ng Dart</strong>, s&#x1EB5;n s&#xE0;ng b&#x1B0;&#x1EDB;c v&#xE0;o x&#xE2;y d&#x1EF1;ng &#x1EE9;ng d&#x1EE5;ng <strong>Flutter chuy&#xEA;n nghi&#x1EC7;p</strong>, ho&#x1EB7;c &#x111;&#x1A1;n gi&#x1EA3;n l&#xE0; hi&#x1EC3;u r&#xF5; h&#x1A1;n v&#x1EC1; c&#xE1;ch vi&#x1EBF;t code an to&#xE0;n, s&#x1EA1;ch s&#x1EBD; trong m&#x1ED9;t ng&#xF4;n ng&#x1EEF; hi&#x1EC7;n &#x111;&#x1EA1;i.</p><p><strong><strong>&#x110;&#x1ECB;a ch&#x1EC9;:</strong></strong> <strong>Trung t&#xE2;m <a href="https://codefresher.vn/" rel="noreferrer noopener">CodeFresher</a></strong> &#x2013; s&#x1ED1; 104 Ho&#xE0;ng Ng&#xE2;n, C&#x1EA7;u Gi&#x1EA5;y, H&#xE0; N&#x1ED9;i.<br><strong><strong>Hotline</strong></strong>: Ms Nga &#x2013; 0968089175 , Ms Di&#x1EC7;u &#x2013; 0332026803 (zalo / call)</p>]]></content:encoded></item></channel></rss>