Được chỉnh sửa ngày 07/06/2019.
Chào mừng các bạn đã đến với bài học Android thứ 16, bài học về cách sử dụng String (phần tiếp theo). Đây là bài học trong chuỗi bài viết về lập trình ứng dụng Android bằng Java của Yellow Code Books.
Các bạn có thể thấy rằng, với một chủ đề đơn giản là tập trung vào một loại resource bình thường thôi, vậy mà chúng ta cần đến hai bài học mới có thể nói đủ về nó. Thật ra thì khi nhìn vào resource này, chúng ta ngỡ là nó đơn giản. Nhưng bạn nên nhớ rằng, string cũng là một dạng resource rất quan trọng, nó vừa giúp ứng dụng chuyền tải được nội dung của từng view đến với người dùng, hướng dẫn người dùng cách sử dụng ứng dụng, nó còn có thể giúp làm ứng dụng trông đẹp hơn nữa.
Và bài học hôm nay chúng ta cùng đi đến các loại string còn lại mà bài hôm trước còn đang nói dở dang.
Sử Dụng Formatting String
Nếu như bài hôm trước các bạn đã làm quen đến styled string, đó là các cách giúp bạn hiển thị string trông đẹp hơn nhờ có các phong cách kèm theo, như màu sắc, độ đậm, độ lớn,… Thì hôm nay chúng ta làm quen với một dạng string khác, mình tạm gọi rằng đây là một “string được định dạng”.
Nghe qua thì mông lung tí, thực chất loại string này giúp bạn tạo ra các định dạng bằng các text giữ chỗ. Mục đích của các text này là giúp cho bạn linh động hơn trong việc thiết kế một string. Ví dụ như, khi bạn không biết phải hiển thị gì khi khai báo string này ở XML, vì bạn cần phải để chương trình chạy lên thì mới biết thông tin của string cần hiển thị, thì một text giữ chỗ như vậy là khá quan trọng.
Khai Báo Các Formatting String Này
Việc khai báo formatting string rất giống với plain string hay styled string. Nhưng nội dung của formatting string thì hơi khác một chút, nội dung được hỗ trợ thêm các định dạng trong đó, bạn hãy xem những ví dụ về định dạng được mình tô sáng như sau.
Những định dạng trên được tuân thủ theo cú pháp.
%[thứ_tự_xuất_hiện$]kiểu_định_dạng
Trong đó:
- % – Biểu thị rằng bạn đang định dạng một string. Nếu chỉ có % thôi mà không có các thành phần kèm theo như cú pháp trên, thì % này vẫn sẽ hiển thị bình thường là một ký tự.
- thứ_tự_xuất_hiện – Thứ tự này sẽ làm việc chặt chẽ với Java code mà bạn sẽ làm quen ngay sau đây.
- $ – Nếu có khai báo thứ_tự_xuất_hiện, thì ngay sau nó phải là ký hiệu $ này. Bạn nên nhớ giữa chúng không có khoảng trắng nào cả đâu nhé. Và vì chúng đang nằm trong cặp ngoặc vuông, có nghĩa là chúng có thể không cần hiển thị nếu bạn chỉ có một định dạng trong string mà thôi.
- kiểu_định_dạng – Tùy vào bạn muốn Java code sẽ điền vào đây kiểu dữ liệu nào. Chúng ta có các kiểu định dạng sau.
- s – Dùng để thay thế bằng một chuỗi
- d – Dùng để thay thế bằng một số nguyên
- f – Dùng để thay thế bằng một số thực
Ví Dụ Khai Báo Formatting String
Ví dụ này chính là hình mình đã chụp ở trên kia nhé. Trong hình đó, các phần tô sáng %1$s, %2$d và %3$f chính là các định dạng. Mình cá là các bạn đã hiểu rõ gần hết, ngoại trừ các thứ_tự_xuất_hiện 1, 2, 3 là gì đúng không nào. Vậy chúng ta cùng xem qua cách sử dụng sau.
Truy Xuất Đến Formatting String
Như bạn biết, mục đích của việc sử dụng định dạng cho string, là vì chúng ta muốn string linh động trong quá trình thực thi ứng dụng. Do đó sự linh động này chỉ có thể được sử dụng thông qua Java code mà thôi.
Bạn hãy xem cách sử dụng string đã được định dạng, và chú ý đặc biệt vào hàm getString() được mình tô sáng ở code dưới đây.
// Khai báo TextView chính là TextView từ XML resource, với id đã khai báo là activity_main_tv_empty
TextView textView = (TextView) findViewById(R.id.activity_main_tv_empty);
// Lấy ngày tháng năm hiện tại từ hệ thống, hiển thị theo dạng dd/mmm/yyyy
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy");
String currentDate = df.format(c.getTime());
// Set text có các tham số truyền vào tương đương các định dạng %1$s, %2$d, %3$f trong XML
textView.setText(getString(R.string.example_for_formatting_string, currentDate, 0, 3.5f));
Bạn thấy rằng nếu bỏ qua tham số thứ nhất của hàm là R.string.example_for_formatting_string, tham số này giúp load string từ XML resource lên. Thì ba tham số còn lại là currentDate, 0, và 3.5f chúng sẽ khớp với định dạng %1$s, %2$d và %3$f trong XML trước đó, cả về thứ tự lẫn kiểu dữ liệu của định dạng. Bạn đã hiểu rồi đúng không nào. Và do đó bạn hoàn toàn có thể định nghĩa thêm %4$x, %5$x, %6$x,… trong XML, rồi tăng thêm tham số truyền vào tương ứng cho hàm getString(), vậy là xong!
Như mình cũng đã nói, là nếu bạn chỉ có duy nhất một định dạng cho string, thì bạn không cần đến thứ_tự_xuất_hiện của nó, khi đó chỉ cần %s, hoặc %d, hoặc %f là được.
Sử Dụng String Theo Số Lượng
Đây là một dạng hỗ trợ đặc biệt của string. Bạn có nhớ rằng với ngôn ngữ tiếng Anh, sẽ có sự khác biệt khi hiển thị một từ theo sau số lượng? Chẳng hạn, với ví dụ trên đây, nếu bạn định nghĩa string trong XML là “You have %d note now”, thì chắc chắn sẽ có trường hợp ngữ pháp tiếng Anh bị sai, nếu như tham số truyền vào cho %d là một số lớn hơn 1, khi đó string sẽ hiển thị chẳng hạn như “4 note”. Sai rồi, phải là “4 notes“.
Trước đây mình không áp dụng string theo số lượng này, mình định nghĩa hai string khác biệt trong XML, rồi if ở Java code để biết khi nào số ít thì load string số ít, khi nào số nhiều thì load string số nhiều. Đó cũng là một cách, nhưng với string theo số lượng của bài học hôm nay, thì Android hỗ trợ chúng ta một cách khác hiệu quả hơn, có thể phục vụ cho nhiều ngôn ngữ khác nhau.
Khai Báo String Theo Số Lượng
Có một chút khác biệt so với các string mà chúng ta đã làm quen trước đó, bạn hãy nhìn hình bên dưới đây, string theo số lượng lần này được định nghĩa bằng thẻ plurals (1) thay vì thẻ string. Tên cho thẻ plurals này vẫn được để trong thuộc tính name (2). Sau cùng, “nội dung” của plurals là các thẻ item (3) khác, mỗi thẻ item như vậy được định nghĩa một quantity (4) cho biết khi nào nên load nội dung (5) của item đó.
Chi tiết tất cả các quantity có thể có, các bạn hãy tham khảo link này. Vì thực sự mình chưa hiểu hết ý nghĩa của tất cả các quantity, nên chưa dám chém trên đây, mong các bạn thông cảm. 🙂
Như ví dụ khai báo của hình dưới đây chúng ta có hai quantity là “one” và “other”. Hai quantity này có nghĩa là, nếu hệ thống biết string này biểu diễn cho số ít, thì quantity “one” được load, ngược lại nếu string này biểu diễn cho số nhiều, thì quantity “other” được load.
Còn với resource string tiếng Việt, mình cũng phải khai báo thẻ plurals với name như bên resource tiếng Anh này. Nhưng vì tiếng Việt không phân biệt số ít số nhiều, nên chúng ta chỉ cần một quantity “other” là đủ.
Truy Xuất Đến String Theo Số Lượng
Cũng giống formatting string, string theo số lượng này chỉ dùng ở Java code. Khi đó chúng ta phải nhờ đến hàm getResources().getQuantityString(). Bạn xem code sau.
// Khai báo TextView chính là TextView từ XML resource, với id đã khai báo là activity_main_tv_empty
TextView textView = (TextView) findViewById(R.id.activity_main_tv_empty);
// Giả lập số lượng note, bạn thử thay đổi để xem từng trường hợp nhé
int numOfNotes = 2;
// Set text cho TextView, với string truyền vào là R.plurals.example_for_quantity_string
textView.setText(getResources().getQuantityString(R.plurals.example_for_quantity_string, numOfNotes, numOfNotes));
Giờ mình sẽ tập trung giải thích các tham số truyền vào hàm getQuantityString().
- R.plurals.example_for_quantity_string – Bạn thấy tham số này vẫn bắt đầu bằng R như những tham số cho các hàm liên quan đến string, nhưng thay vì R.string thì lần này lại là R.plurals, vì bạn thấy chúng tương tự như các định nghĩa ở thẻ gốc trong XML đúng không nào.
- numOfNotes thứ nhất – Tham số này sẽ giúp hệ thống biết string bạn đang ở số ít hay số nhiều.
- numOfNotes thứ hai – Tham số này dùng cho định dạng %d bên trong mỗi item thôi. Nếu bạn không dùng đến formatting string trong item thì không cần tham số này. Hoặc nếu bạn định nghĩa nhiều formatting như %1$x, %2$x thì bạn cứ tăng tham số truyền vào như là cách dùng formatting bên trên vậy.
Mình làm vài thử nghiệm thay thế các giá trị cho numOfNotes, bạn xem mình chạy lên thiết bị và chụp màn hình ở cả hai ngôn ngữ Anh và Việt như sau.
Sử Dụng String Array
Như tên gọi của nó cũng đủ nói lên tất cả. String array giúp bạn khai báo mảng các string ngay trong XML, và rồi sẽ được tự động load lên ở dạng mảng các chuỗi khi bạn thao tác với Java code.
Khai Báo String Array
String Array không dùng thẻ string, không dùng thẻ plurals như các bạn đã biết, mà dùng thẻ string-array (1). Tên cho thẻ này vẫn được để trong thuộc tính name (2). Từng phần tử mảng sẽ được định nghĩa ở mỗi thẻ item (3), mỗi thẻ item như vậy chứa một nội dung (4) của phần tử mảng đó.
Truy Xuất Đến String Array
Lại một lần nữa, chúng ta chỉ có thể gọi đến string array qua Java code, với hàm getResources().getStringArray(), hàm này sẽ trả về kết quả là mảng String[]. Tham số truyền vào cho getStringArray() là R.array.tên_string_array. Bạn xem ví dụ.
// Khai báo TextView chính là TextView từ XML resource, với id đã khai báo là activity_main_tv_empty
TextView textView = (TextView) findViewById(R.id.activity_main_tv_empty);
// Mảng String[] sẽ chứa danh sách các string được load lên từ string-array
String[] stringArray = getResources().getStringArray(R.array.example_for_string_array);
Thực Hành Hoàn Thiện Resource String Cho TourNote
Bài thực hành hôm nay hoàn toàn mở. Đó là mình sẽ để cho bạn tự tạo toàn bộ resource string cho ứng dụng TourNote. Tất nhiên mình cũng sẽ xây dựng bộ resource cùng với bạn và để trên GitHub để bạn tham khảo. Và mình cũng sẽ đưa toàn bộ screenshot về string resource của TourNote ra đây để bạn quyết định những nội dung, style, format có thể có cho resource của bạn. Nhớ là phải có đầy đủ ngôn ngữ cho cả tiếng Anh và Việt nhé.
Như vậy là từ đây về sau mình sẽ sử dụng các string resource đã được định nghĩa ở bài hôm nay ra dùng. Nếu có sửa đổi hoặc thêm mới resource string thì mình sẽ thông báo.
Đây là tất cả những thiết kế cho TourNote đến giai đoạn này.

Với các màn hình như trên thì mình tạo ra bộ resource cho tiếng Anh và tiếng Việt như hình chụp sau. Chú ý là mình có thay đổi tên string empty_note thành mainscreen_empty_note cho nó đồng nhất. Tất cả code từ hình ảnh này đều đã có trên GitHub cả rồi nhé.
Hình ảnh resource string tiếng Anh Hình ảnh resource string tiếng Việt
Download Source Code Mẫu
Bạn có thể download source code mẫu của bài này ở đây.
Có thể nói với kết thúc bài học hôm nay thì bạn đã nắm chắc cách sử dụng string resource này rồi. Và TourNote cũng được bạn nâng cấp thêm những cái mới. Buổi sau chúng ta sẽ nói rõ về một dạng resource tiếp theo của Android, đó là color resource.
Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy ủng hộ blog bằng cách:
– Đánh giá 5 sao bên dưới mỗi bài nếu thấy thích.
– Comment bên dưới mỗi bài nếu có thắc mắc.
– Để lại địa chỉ email của bạn ở thanh bên phải để nhận được thông báo sớm nhất khi có bài viết mới.
– Chia sẻ các bài viết của Yellow Code Books đến nhiều người khác.
Bài Kế Tiếp
Bài sau chúng ta sẽ cùng tìm hiểu tất cả cách sử dụng một loại resource khá “đẹp” của Android, resource liên quan đến màu sắc, đó chính là color resource.
Reblogged this on gioilaptrinh.
Chào Bạn, Khi đến bài này Mình vướng vấn đề sau :
Sau khi Download code mẫu về thì Mình chuyển tất cả thư mục TOURNOTE cũ đi đồng thời giải nén và chép thư mục TOURNOTE mới vào vị trí của thư mục TORNOTE cũ.
Khi Mình chạy lại chương trình thì hiện thông báo lỗi như hình sau ( Mình đã gửi qua mail cho Bạn với tiêu đề là Thông báo lỗi của Bài 16 ), đồng thời trong quá trình xử lý lỗi thì Mình cũng đã cập nhật lại Ver của ANDROID STUDIO lên 2.3.2.
Theo Mình hiếu thì có vẻ như lỗi là do đường dẫn đến các file liên quan chưa chính xác nhưng Mình không biết cách giải quyết vấn đề.Bạn có thể trả lời giúp Mình vấn đề này tý nhé. Cám ơn Bạn nhiều.
Mình đã phát hiện lỗi đường dẫn sai ( TOURNOTE1 ), đường dẫn đúng là TOURNOTE và Mình đã khắc phục xong. Cám ơn Bạn nhé và Bạn không phải tìm nữa. Mĩnh sẽ tìm hiểu tiếp về Bài này nếu có vướng gì thì nhờ Bạn giải đáp giúp. Cảm ơn Bạn nhiều
Ồ quá tốt! Cố lên bạn Thuận! 😉
Lâu nay Mình chỉ làm theo phương pháp XML mà không sử dụng phương pháp mã code JAVA. Đến bài 16 thì bắt buộc phải sử dụng JAVA nên mình hơi lúng túng Chắc phải đọc và thực hành lại những bài mẫu ban đầu để cho quen với cách sử dụng phương pháp mã code đã. Theo ý của Bạn thì Mình làm như vậy có đúng không?
Không sao đâu bạn. Mình cũng chỉ tập trung vào thiết lập giao diện trên XML là chính. Đến khi mà cần dùng chúng trên Java, mình toàn vào trang developer.android.com để tìm các hàm tương ứng và cách sử dụng. Chứ không cố nhớ làm chi cho mệt.