Android Bài 9: Đi Sâu Vào Widget

Posted by
Rating: 4.9/5. From 15 votes.
Please wait...

Được chỉnh sửa ngày 20/3/2019.

Chào mừng các bạn đã đến với bài học Android thứ 9, bài học về các widget trong Android. Đâ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.

Chắc bạn còn nhớ ở bài 7, bạn đã làm quen với việc tạo một giao diện khá cơ bản cho TourNote, khi đó bạn đã biết về mối tương quan giữa ViewWidget. Bài học hôm nay sẽ giúp bạn hiểu rõ hơn, cũng như sẽ biết cách sử dụng tốt hơn vài widget cơ bản nhất trong lập trình Android. Sau bài học này thì mình cũng có viết một bài mở rộng, nơi đó mình nói về tất cả các widget còn lại mà bài học hôm nay chưa kịp nói đến.

Nào trước khi vào từng widget cụ thể, chúng ta hãy đi qua các khái niệm sau.

Khái Niệm Thuộc Tính (Attribute)

Các Thuộc Tính của một view được dùng để định nghĩa các biểu hiện của một view đó. Chẳng hạn như vị trí của chúng, độ rộng & chiều cao của chúng, màu sắc, nội dung,…

Các thuộc tính này được hiển thị trong cửa sổ Attribute khi bạn nhấn chọn vào View này trong editor ở chế độ Design. Hoặc được định nghĩa thông qua các câu lệnh XML. Ở bài 7 bạn có thực hành sơ qua việc sử dụng các thuộc tính này, cụ thể là thuộc tính text.

Tạo giao diện người dùng - Sửa chữa TextView

Một số ít trường hợp còn lại các thuộc tính sẽ được định nghĩa bằng Java code, nhằm phục vụ một số ý đồ thay đổi diện mạo cho view đó ở runtime.

Một ví dụ để bạn biết nơi tham khảo tất cả các thuộc tính XML của một view, bạn hãy vào link này, đây là ví dụ cho TextView. Khi đã mở link ra thì bạn hãy nhìn vào bảng “XML attributes”, bảng này sẽ liệt kê tất cả các thuộc tính bằng XML của TextView. Kéo xuống bảng ở dưới một tí là “Inherited XML attributes”, bảng này liệt kê tiếp tất cả các thuộc tính XML mà TextView đó kế thừa từ view gốc, nếu bạn chưa hiểu khái niệm kế thừa là gì thì bạn cứ nhớ rằng tất cả các thuộc tính XML của TextView này sẽ nằm ở cả 2 bảng vừa nhắc đến trên đây. Dựa vào các thuộc tính này của XML, bạn cũng sẽ dễ dàng suy ra các giá trị bên trong cửa sổ Attribute của tab Design thôi, vì tên của chúng khá giống nhau, bạn so sánh đi nhé. Hơn nữa, ở dưới trang mình đã đưa còn một bảng hữu dụng nữa là “Public methods”, bảng này chứa các thuộc tính mà bạn có thể gọi đến ở Java code cho các mục đích thay đổi runtime được nhắc đến ở trên.

Một Số Thuộc Tính Quan Trọng Của View

Phần này mình sẽ nói đến các thuộc tính quan trọng hoặc hay sử dụng thôi nhé. Vì bạn cũng biết đó, mỗi View có rất nhiều thuộc tính, việc của bạn là đến các link liên quan đến các View đó như link mình đưa ra ở mục trước, để tự tìm hiểu các thuộc tính liên quan của View.

View Nào Cũng Nên Có ID

Bạn thử nghĩ xem nếu bạn muốn tô màu cho một View, hay set text cho chúng, cách tốt nhất để có thể phân biệt xem View nào là View nào, là đặt cho chúng một ID rồi gọi chúng thông qua ID này. ID thực ra là một cái tên do bạn đặt cho các View hay ViewGroup. Tất nhiên cũng có View không cần bạn phải đặt một ID, vì chúng luôn luôn hiển thị với một trạng thái duy nhất trong suốt quá trình sống của ứng dụng, chúng không bị thay đổi, và không ảnh hưởng đến vị trí hiển thị của view nào khác cả.

Định Nghĩa ID Cho Một View

Để định nghĩa một ID cho View (hay ViewGroup), bạn có thể làm bằng một trong hai cách, tùy vào kiểu hiển thị Design hay Text đối với View đó.

Nếu như ở tab Design của editor chỉnh sửa giao diện. Để định nghĩa ID cho View, bạn hãy đảm bảo View bạn cần đặt ID được chọn trong màn hình trực quan thiết kế. Rồi tìm đến cửa sổ Attribute bên cạnh, và tìm field có tên ID. Field này chính là nơi bạn đặt ID cho View hay ViewGroup được chọn đó. Bạn xem hình sau sẽ rõ. Còn việc đặt ID theo tiêu chuẩn gì thì bạn có thể tham khảo cách đặt tên ID ở code XML mình nói ngay dưới hình sau.

Tạo giao diện người dùng - Tạo ID

Nếu bạn muốn thêm ID cho View hay ViewGroup ngay bên trong code của tab Text, thì bạn nên nhớ cú pháp để định nghĩa một ID là.

android:id="@+id/id_của_view"

Trong đó.

android:id – Thuộc tính này được dùng khi bạn muốn định nghĩa một ID cho View hay ViewGroup bằng code XML.

@+id/  – Báo cho hệ thống biết bạn muốn tạo mới một ID. Nhớ là phải có dấu “+”.

 id_của_view  – Là tên bạn tự đặt (theo chuẩn đặt tên biến của Java, nếu bạn nào có nhu cầu có thể xem cách đặt tên biến ở bài học Java này).

Truy Xuất Đến ID Của Một View

Bạn vừa mới tạo một ID, nếu bạn muốn gọi đến view thông qua ID này thì có các trường hợp sau.

Trường hợp thứ nhất, nếu bạn dùng phương pháp kéo thả giao diện tab Design, thì bạn hầu như không cần quan tâm đến ID của các View. Vì sao. Vì bạn đã làm việc trực quan với giao diện của chúng rồi. Hệ thống sẽ tự động tìm kiếm và điền ID vào code XML cho bạn. Đến các bài thực hành kế tiếp bạn sẽ hiểu rõ vấn đề này. Nhưng cho dù cách thức lập trình giao diện này không hề liên quan đến ID, mình vẫn liệt kê ra đây, để cho bạn thấy rằng ID nó khá là quan trọng trong thiết kế giao diện.

Trường hợp thứ hai, nếu bạn thiết kế hay chỉnh sửa giao diện trong code XML, thì bạn sẽ đụng chạm nhiều đến ID hơi bị nhiều, khi đó bạn có thể dùng cú pháp sau để có thể gọi đến các ID của các View hay ViewGroup thông qua code XML này.

thuộc_tính_android="@+id/id_của_view"

Trong đó.

thuộc_tính_android – Một số thuộc tính của Android. Như bạn sẽ làm quen ở ngay dưới phần thực hành của bài học này, hay cụ thể hơn ở Bài 10, khi đó với layout có tên là ConstraintLayout sẽ bắt bạn phải chỉ định vị trí tương quan giữa các view, và vì vậy bạn sẽ gọi đến ID của view khác thông qua rất nhiều thuộc tính, như app:layout_constraintBottom_toTopOf, hay app:layout_constraintStart_toEndOf,… như code minh họa sau.

<TextView
    ...
    app:layout_constraintBottom_toTopOf="@+id/id_của_view"
    app:layout_constraintEnd_toEndOf="@+id/id_của_view"
    app:layout_constraintStart_toEndOf="@+id/id_của_view"
    app:layout_constraintTop_toTopOf="@+id/id_của_view" />

@id/ – Khác với khi định nghĩa một ID mới, lúc đó bạn phải dùng dấu “+” phía sau ký tự “@”. Lần này truy xuất đến ID đã định nghĩa, bạn có thể bỏ dấu “+” đi và chỉ cần gọi @id/ mà thôi.

id_của_view – Chính là ID mà bạn đã định nghĩa.

Trường hợp thứ ba nếu bạn gọi đến ID của View hay ViewGroup trong Java code, bạn phải truyền R.id.id_của_view vào một số hàm, ví dụ hàm này findViewByID(R.id.id_của_view);.

View Nào Cũng Cần Có Kích Cỡ

Kích cỡ ở đây là các định nghĩa về chiều ngang & dọc của view. Tương ứng với điều đó chúng ta có 2 thuộc tính liên quan đến xác định kích cỡ cho view, đó là layout_widthlayout_height (lưu ý là bạn có thể không cần định nghĩa ID cho view, nhưng bạn buộc phải định nghĩa kích cỡ, nếu không thì hệ thống sẽ báo lỗi).

Do trong lập trình mobile, bạn sẽ không biết chính xác ứng dụng của bạn sẽ được chạy trên kích thước màn hình nào, có hàng ngàn kích thước màn hình khác nhau trên thị trường, do đó để chỉ định được kích cỡ của một view sao cho hoàn hảo khi ứng dụng được chạy lên là điều không dễ. Nhưng Android đã hỗ trợ bạn, không chỉ với việc chỉ định kích thước cụ thể, mà còn có thể có các chọn lựa khác nhau cho các kích thước động nữa, mời bạn làm quen trước với các khái niệm kích thước sau.

1. Bạn có thể chỉ định giá trị match_parent, với giá trị này thì view của bạn sẽ thoải mái bung ngang hay bung dọc sao cho có thể dàn hết không gian mà view cha của view đó cho phép. Ví dụ một view được set thuộc tính android:layout_width=”match_parent” sẽ có chiều ngang hết cỡ trong khoảng chiều ngang của view cha, và nếu thuộc tính android:layout_height=”match_parent” thì sẽ có chiều cao hết cỡ trong khoảng chiều cao của view cha.

2. Bạn có thể chỉ định giá trị match_constraint. Nếu view của bạn nằm trong một ConstraintLayout, thì sẽ không có kiểu match_parent như trên đâu, mà là match_constraint. Cơ bản thì kiểu khoảng cách này gần gần giống với match_parent quen thuộc ở các layout khác. Chỉ khác ở chỗ Match Constraint không “độc ác” đến nổi đẩy các view khác ra khỏi màn hình mà chiếm lấy hết không gian ở view cha. Nó vẫn chiếm không gian của view cha nhưng chiếm trong khả năng cho phép, tức là vẫn tuân thủ theo quy luật mà các constraint đã tạo, vẫn chừa không gian cho các view khác xuất hiện. Và khi bạn chỉ định kiểu khoảng cách là Match Constraint thì code XML của view sẽ mang giá trị là 0dp.

3. Bạn có thể chỉ định giá trị wrap_content, với chỉ định này thì view của bạn sẽ có kích thước co dãn sao cho đủ không gian cho các thành phần con bên trong nó.

4. Chỉ định kích cỡ cụ thể. Hai cách trên khá tốt, với màn hình khác nhau bạn cũng không sợ, vì bạn có thể chỉ định một view rộng hết màn hình, hay rộng trong khoảng thành phần con của nó thôi. Tuy nhiên còn 1 cách nữa là bạn có thể chỉ định độ lớn mong muốn theo một giá trị dp, ví dụ bạn set android:layout_width=”125dp” (hoặc 125dip cũng được, 2 ký hiệu viết tắt này đều là density independent, biểu thị một giá trị ảo dựa trên tỉ lệ điểm ảnh của màn hình, giá trị này sẽ được mình nói đến ở bài sau vì nó cũng khá dài dòng).

Để định nghĩa kích thước cho View (hay ViewGroup), bạn cũng có thể làm bằng một trong hai cách, tùy vào kiểu hiển thị Design hay Text đối với View đó.

Nếu như ở tab Design của editor chỉnh sửa giao diện, bạn hãy đảm bảo View bạn cần đặt ID được chọn trong màn hình trực quan thiết kế. Ở cửa sổ Attribute bên cạnh hãy tìm đến các field có tên layout_widthlayout_height và set vào đó một trong các giá trị mà mình vừa trình bày trên kia. Bạn có thể tham khảo hình sau.

Tạo giao diện người dùng - Thiết lập kích thước

Có một lưu ý nữa là, với cửa sổ Attribute này, bạn còn có thể có một cách khác thú vị hơn nữa để thay đổi kích thước của View, bằng cách click vào một trong các nơi được mình tô đỏ như hình dưới đây.

Tạo giao diện người dùng - Tùy chình kích thước

Về ý nghĩa của các ký hiệu kích thước ở hình trên đây, thì mình mời các bạn xem qua một chút ở link này, mình không nhắc lại ở bài học này để tránh rườm rà nhé.

Còn nếu như bạn không muốn sử dụng tab Design như trên đây, mà muốn định nghĩa kích thước cho View hay ViewGroup ngay bên trong code của tab Text, thì bạn có thể để ý đến hai thuộc tính sau.

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    ... />

Xây Dựng Một Số Widget Cho Tour Note

Nào giờ chúng ta sẽ thực hành thực tế việc chỉnh sửa các thuộc tính cho các View sẽ như thế nào nhé.

TextView – Nơi Hiển Thị Các Label

Lại nhắc đến bài số 7, khi đó bạn đã tạo một TextView bên trong file activity_main.xml rồi, với TextView này bạn đã biết công dụng của nó là hiển thị thông báo đến người dùng khi không có ghi chú nào trong ứng dụng được tạo. Đúng vậy, TextView chính là một label, widget này chuyên dùng để hiển thị các đoạn text mang tính thông báo mà người dùng không thể chỉnh sửa được.

Các Thuộc Tính Thường Dùng Của TextView

Ngoài các thuộc tính chung được nói ở mục trên kia, TextView còn có các thuộc tính thường dùng của riêng nó như sau.

android:gravity – Dùng để canh chỉnh text của nó sao cho canh trái, phải, giữa,… so với không gian của chính nó. bài học số 7 bạn đã thử canh chỉnh thuộc tính gravity này rồi.

android:text – Bạn đã dùng đến thuộc tính này để set text cho TextView ở bài trước rồi đúng không nào.

android:textColor – Hiển thị màu cho text, bài thực hành hiển thị màu sẽ được mình nói đến ở bài viết đi sâu hơn về resource.

android:textSize – Kích cỡ của text, kích cỡ này được tính theo đơn vị sp. Định nghĩa và cách sử dụng đơn vị này sẽ được nói đến ở bài khác, cùng với các định nghĩa về dpdip được nhắc đến ở trên.

android:textAllCaps – Dùng để in hoa hết tất cả các ký tự của text nếu giá trị thuộc tính này là true.

android:padding – Set khoảng cách giữa biên của view đến các thành phần con của nó. Đơn vị tính của thuộc tính này cũng là dp hoặc dip. Nếu bạn muốn khoảng cách riêng cho từng cạnh biên có thể dùng tách biệt từng thuộc tính cụ thể của padding như android:paddingTop, android:paddingBottom, android:paddingLeftandroid:paddingRight.

android:margin – Set khoảng cách giữa biên của view đến các thành phần bên ngoài của nó. Nếu như padding trên kia giúp cho các thành phần con cách xa cạnh biên của view ra, thì margin lại giúp các thành phần bên ngoài tránh xa cạnh biên của view. Bạn nên phân biệt hai giá trị này. Đơn vị tính của thuộc tính này cũng là dp hoặc dip. Tương tự bạn có thể set android:marginTop, android:marginBottom, android:marginLeftandroid:marginRight đối với từng cạnh của view.

android:ellipsize – Dùng thuộc tính này khi bạn muốn text của mình sẽ bị cắt và hiển thị “…” khi không đủ không gian để chứa hết text đó.

android:background – Dùng để set màu nền hoặc ảnh nền cho View.

Thực Hành Hoàn Thiện Các Thuộc Tính Cho TextView Của TourNote

Bây giờ các bạn hãy mở lại project TourNote lên, chúng ta tiến hành chỉnh sửa lại TextView ở bài trước cho đúng đắn và chuyên nghiệp hơn.

Bạn mở lại file activity_main.xml ra, hãy để giao diện này đang ở tab Design, và đảm bảo TextView ở giữa màn hình được chọn, chúng ta sẽ thêm các thuộc tính sau vào trong TextView.

Trước hết, hãy thêm vào TextView này một ID và các kích thước, bạn hãy thêm vào các thông tin như hình sau rồi mình giải thích nhé.

Tạo giao diện người dùng - Chỉnh sửa TextView

ID – Bạn đặt ID cho TextView này là activity_main_tv_empty, sở dĩ mình đặt dài dòng như vậy là vì muốn đảm bảo ID này không bị trùng trong ứng dụng của chúng ta, để làm vậy thì chúng ta nên đặt có đủ 3 thành tố sau: tên_file_xml + viết_tắt_của_widget + tên_widget. Theo đó thì tên file xml là activity_main, viết tắt của TextViewtv, và tên của TextView này thông báo không có ghi chú nên đặt là empty. Cộng lại chúng ta có ID như trên.

layout_width – Được set là match_constraint, như mình có nói ở mục trên, tức là chiều rộng sẽ là maximum so với chiều rộng của view cha.

layout_height – Được set là wrap_content, mình cũng đã nói rõ, tức chiều cao sẽ tùy theo số dòng của text.

Ngoài ID và kích thước ra, mình còn muốn các bạn chỉ định margin cho TextView này nữa. margin là gì thì mình có nói ở mục trên rồi nhé. Để chỉnh sửa các thuộc tính này, thì bạn vẫn cứ hãy ở tab Design, và đảm bảo TextView ở giữa màn hình được chọn, rồi thêm các chỉnh sửa như hình sau vào trong TextView.

Tạo giao diện người dùng - Margin cho TextView

Chỉ cần nhấn chọn vào hình tam giác bên phải mỗi số thôi là bạn có sẵn các chọn lựa cho các giá trị này. Bạn có thể tự đưa ra cho View một con số bất kỳ nào đó khác cũng được. Và sau khi bạn chỉ định một số, đơn vị của nó sẽ là dp. Bạn hãy so sánh giao diện trực quan giữa trước và sau khi set margin cho View nhé, bạn sẽ hiểu margin là gì thông qua việc so sánh này thôi.

Tạo giao diện người dùng - So sánh margin

Bước tiếp theo của bài thực hành này, mình muốn các bạn chỉnh sửa kích cỡ của text trong TextView. Để chỉnh sửa các thuộc tính này, thì bạn vẫn cứ hãy ở tab Design, và đảm bảo TextView ở giữa màn hình được chọn, rồi thêm kích cỡ text như hình sau vào trong TextView.

Tạo giao diện người dùng - Thay đổi text size

Bạn có thể thấy rằng, với kích thước text, bạn nên định nghĩa cho nó một độ lớn kèm theo giá trị là sp. Về cơ bản dp cũng như sp thôi, nhưng chúng có một chút khác biệt nhau. Việc bây giờ bạn cần biết rằng bạn nên sử dụng thông số sp cho kích cỡ text, hay còn gọi là font size, còn dp dành cho các kích cỡ về các kích thước của View. Tại sao có sự khác biệt này thì chúng ta sẽ tìm hiểu ở bài khác nhé.

Giờ thì mình muốn bạn chuyển cửa sổ thiết kế của activity_main.xml này sang tab Text, để xem các giá trị mới được thêm vào cho code XML của chúng ta như thế nào nhé. Mình liệt kê thay đổi đó bằng các dòng code được tô sáng sau.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/activity_main_tv_empty"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:gravity="center"
        android:text="@string/empty_note"
        android:textSize="15sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Bạn thấy làm việc với giao diện của Android có dễ không nào. Tất cả chỉ là canh chỉnh các giá trị của chúng thôi. Tuy nhiên làm việc hoài với TextView cũng chán, phần sau đây mình mời các bạn cùng thử vọc với việc hiển thị ảnh Bitmap lên ứng dụng xem sao nhé.

Ảnh (Image) Sẽ Giúp Ứng Dụng Trông Pro Hơn

TextView không thôi vẫn chưa đủ mạnh (strong), người dùng sẽ bỏ qua câu thông báo của bạn ngay (ví dụ như trong trường hợp này của ứng dụng TourNote), bạn cần phải có một ảnh làm cho ứng dụng thêm đẹp hơn và người dùng chú ý nhiều hơn tới câu thông báo. Ngoài ra trong hầu hết các ứng dụng khác của Android sau này, bạn sẽ cần dùng đến rất nhiều ảnh, do đó mình xin nói đến cách sử dụng ảnh rất sớm từ bài này.

Có 2 widget giúp hiển thị ảnh trong Android, đó là ImageViewImageButton. Bài hôm nay chỉ nói về ImageView thôi, trong khi ImageButton là con của ImageView nên cũng có các thuộc tính tương tự ImageView. Tất cả các widget đã được mình tổng hợp lại trong bài Tìm Hiểu Các Widget Cơ Bản, các bạn vào xem nhé.

Các Thuộc Tính Thường Dùng Của ImageView

Tương tự như TextView, ImageView cũng có các thuộc tính quan trọng của riêng nó như sau.

android:src – Hiển thị ảnh theo dạng content, ảnh này sẽ nằm đè lên trên ảnh background nói đến ở dưới đây.

android:background – Thuộc tính này dùng để set màu nền hoặc ảnh nền cho view.

android:scaleTyle – Cho biết tỉ lệ co dãn hoặc vị trí của ảnh so với khung của view, các giá trị của thuộc tính này sẽ được nói kỹ sau bài thực hành dưới đây.

android:padding – Tương tự padding của TextView ở trên. Tuy nhiên padding sẽ làm ảnh hưởng đến không gian hiển thị của src, với background thì “miễn nhiễm” với thuộc tính này.

Thực Hành Thêm ImageView Cho TourNote

Trước hết bạn hãy nhấn vào đây để download resource.

Resource bạn vừa down về chứa đựng nhiều thư mục (drawable-mdpi/drawable-hdpi/drawable-xhdpi/drawable-xxhdpi/ và drawable-xxxhdpi/), bạn giải nén và copy các thư mục này vào thư mục res/ của project TourNote, trong các thư mục đều chứa một ảnh có tên giống nhau là empty_note.png. Bạn biết tại sao ảnh này lại để trong các thư mục này đúng không nào, đó là cách bạn xác định ảnh cho alternative resource (bạn có thể xem bài 8 nếu chưa biết về alternative resource), để khi load lên, độ phân giải của ảnh sẽ được hiển thị chính xác nhất theo tỉ lệ mình hàn hình trên thị trường.

Bạn phải đảm bảo rằng sau khi giải nén và copy các thư mục chứa ảnh vào trong thư mục res/ của project, thì chúng phải hiển thị như hình sau trong ứng dụng, nếu không bạn có thể xóa các thư mục vừa tạo để copy lại, hoặc download source code mẫu theo đường link cuối bài học để check xem thế nào nhé.

Tạo giao diện người dùng - Tổ chức ảnh bitmapSau khi đã copy các ảnh như trên rồi chúng ta tiến hành chỉnh sửa thêm cho giao diện activity_main.xml như sau. Bạn đảm bảo file activity_main.xml đang mở, và tab Design đang được chọn. Ở cửa sổ Palette phía trên bên trái editor này, bạn hãy tìm đến thành phần ImageView. Nắm và kéo thành phần này vào màn hình trực quan thiết kế, bạn hãy thả thành phần ImageView này ra khi thấy rằng nó nằm đâu đó ở dưới TextView như hình sau (chú ý là bạn cũng đừng quan trọng quá ImageView sẽ nằm dưới TextView bao xa, chúng ta chỉ cần đảm bảo nó nằm dưới, thế thôi, việc còn lại sẽ chỉnh sửa sau).

Tạo giao diện người dùng - Kéo thả ImageView

Sau khi thả chuột ra sau quá trình kéo thả, một cửa sổ mới mở lên, cửa sổ này buộc phải chọn ảnh để hiển thị vào trong ImageView này. Bạn hãy đảm bảo Drawable ở bên trái cửa sổ được chọn, tùy chọn này cho hệ thống biết sẽ tìm ảnh trong thư mục res/drawable. Sau đó nhấn chọn vào Project, tùy chọn này ý muốn chúng ta tìm đến ảnh trong project của chúng ta, và sau cùng là chọn vào empty_note, chính là ảnh bạn vừa để vào thư mục của project ở bước trên đây.

Tạo giao diện người dùng - Tìm đến drawable image

Sau khi chọn xong ảnh, thì bạn nhấn OK. Bạn sẽ thấy ảnh hiện ra sẽ đâu đó như thế này.

Tạo giao diện người dùng - Thêm vào một imageview

Nếu chú ý đến field srcCompat bạn sẽ thấy nội dung của nó là @drawable/empty_note. Giá trị này cũng giống với cấu trúc giá trị text của TextView đúng không nào. Đừng quá lo lắng nếu như ảnh không hiển thị canh giữa vào màn hình nhé. Chúng ta cùng đến bước tiếp theo để canh chỉnh ImageView này cho nó đẹp hơn.

Để có thể hiểu được sự canh chỉnh các giá trị bên trong một ConstraintLayout như thế nào thì mình mời các bạn hãy bỏ thời gian đọc qua loạt bài về ConstraintLayout của mình nhé. Với bài thực hành hôm nay, nếu bạn chưa có nhu cầu muốn hiểu tường tận về ConstraintLayout thì cũng có thể thử các bước sau.

Tạo giao diện người dùng - Canh chỉnh View

Mình giải nghĩa một chút các ý đồ của các bước trên đây của mình.

– Đảm bảo điểm neo bên trên của ImageView chính là TextView, điểm neo bên trái là biên trái màn hình, và điểm neo bên phải là biên phải màn hình. Vì ConstraintLayout buộc các View phải có từ 2 điểm neo trở lên, và việc neo các view với nhau này sẽ giúp ConstraintLayout xác định được các View sẽ được vẽ ở đâu với kích thước và khoảng cách như thế nào.

layout_widthlayout_height của ImageView đều mang giá trị 60dp.

– Đảm bảo các giá trị margin đều là 8dp.

scaleType được set là fitCenter, chúng ta sẽ tìm hiểu các kiểu co dãn ảnh ở mục sau đây.

Chúng ta lại chuyển cửa sổ thiết kế của activity_main.xml này sang tab Text, để xem các giá trị mới được thêm vào cho code XML của chúng ta như thế nào. Mình liệt kê thay đổi đó bằng các dòng code được tô sáng sau.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/activity_main_tv_empty"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:gravity="center"
        android:text="@string/empty_note"
        android:textSize="15sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:scaleType="fitCenter"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/activity_main_tv_empty"
        app:srcCompat="@drawable/empty_note" />

</android.support.constraint.ConstraintLayout>

Giờ bạn có thể thử run project lên để xem thành quả được rồi đấy.

Tạo giao diện người dùng - Kết quả thực thi

Các Dạng Scale Của Ảnh

Bước thực hành trên đây chúng ta vừa làm quen với một dạng scale, đó là android:scaletype=”fitCenter”, các dạng scale này chính là do widget ImageView này hỗ trợ, nó giúp bạn có được các tùy chỉnh thú vị hơn khi sử dụng đến ảnh.

Chúng ta cùng xem qua các dạng scale có thể có của một ImageView nhé.

Giả sử mình dùng ảnh có hình con robot như sau ( bạn chú ý khung màu xanh dương là khung giới hạn của ImageView để xem chúng “biến hóa” như thế nào trong khung giới hạn).

fitCenter

Nếu sử dụng giá trị này cho scaleType, ảnh sẽ tự động scale sao cho hiển thị gọn bên trong khung mà tỉ lệ của ảnh vẫn không thay đổi.

Tạo giao diện người dùng - Scale fit center

fitXY

Giá trị này làm ảnh bị scale sao cho hiển thị gọn bên trong khung, nhưng khác fitCenter ở chỗ fitXY làm cho ảnh bị biến dạng không còn tỉ lệ gốc nữa.

Tạo giao diện người dùng - Scale fit xy

fitStart

Cách scale này giống với fitCenter là sẽ đảm bảo ảnh nằm gọn trong khung mà tỉ lệ ảnh không đổi, nhưng thay vì ảnh nằm giữa khung thì nó bị neo góc trên bên trái khung.

Tạo giao diện người dùng - Scale fit start

fitEnd

Tương tự như fitStart, nhưng góc neo của ảnh lại là góc dưới bên phải khung.

Tạo giao diện người dùng - Scale fit end

centerCrop

Giá trị này làm ảnh sẽ bị scale đến khi một chiều ngắn nhất của ảnh nằm gọn trong khung, chiều còn lại bị cắt sao cho tỉ lệ của ảnh không bị đổi. Trường hợp dưới đây cho thấy chiều dọc của ảnh sẽ nhìn thấy gọn trong khung, trong khi chiều dài bị cắt.

Tạo giao diện người dùng - Scale center crop

center

Giá trị này không làm scale ảnh, nó chỉ có nhiệm vụ hiển thị ảnh đúng với kích cỡ của nó vào giữa khung mà thôi.

Tạo giao diện người dùng - Scale center

Nói như vậy có nghĩa là nếu như khung nhỏ hơn kích thước ảnh, ảnh sẽ bị cắt đi như hình sau.

Tạo giao diện người dùng - Scale center

centerInside

Cách scale này cũng giống như center, tức là nó cũng sẽ giữ kích thước gốc của ảnh, nhưng nếu khung vẫn còn nhỏ hơn kích thước ảnh, lúc này ảnh sẽ tự scale xuống mà vẫn giữ tỉ lệ của nó.

Tạo giao diện người dùng - Scale center indise

matrix

Dùng khi bạn muốn scale ảnh và xoay ảnh dạng Matrix, bạn có thể search thêm cách scale hay xoay ảnh dạng Matrix trên mạng, hoặc mình sẽ viết cách sử dụng Matrix ở một bài khác.

Bạn vừa cùng mình thực hành 2 cách sử dụng widget là TextViewImageView, hãy đọc Tìm Hiểu Các Widget Cơ Bản để biết cách sử dụng các widget cơ bản còn lại bạn nhé.

Download Source Code Mẫu

Bạn có thể download source code mẫu của bài này ở đây.

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ạn sẽ được học rõ hơn cách sử dụng 2 layout phổ biến nhất hiện nay là LinearLayout và RelativeLayout, qua đó bạn sẽ nắm rõ cách sắp xếp các View hay ViewGroup theo một trật tự nhất định để tạo thành một giao diện hoàn chỉnh của ứng dụng.

 

10 comments

  1. Reblogged this on gioilaptrinh.

    No votes yet.
    Please wait...
  2. Em vừa học java và android trên web của anh luôn thì không biết có theo được bài của anh không?

    No votes yet.
    Please wait...
    1. Cảm ơn bạn Nam đã theo dõi các bài học của mình. Mình nghĩ không có vấn đề gì đâu bạn, bạn hoàn toàn có thể theo dõi và học song song cả Java và Android. Nhưng thời gian qua có nhiều bạn muốn biết vững Java hơn nên có lẽ mình đẩy nhanh Java một chút.
      Ngoài ra thì nếu có thắc mắc nào ở mỗi bài học, bạn Nam cứ comment nhé, mình sẽ chỉnh sửa lại nội dung các bài học sao cho dễ hiểu nhất có thể.

      No votes yet.
      Please wait...
      1. Cám ơn anh, anh trình bày bài học vậy là chi tiết và dễ hiểu lắm rồi! Mong anh đẩy nhanh tiến độ bài viết hơn thôi! Chúc anh thêm nhiều sức khỏe để viết bài nhé!

        No votes yet.
        Please wait...

Gửi phản hồi