Thêm hình ảnh vào ứng dụng Android

1. Trước khi bắt đầu

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách thêm hình ảnh vào ứng dụng bằng cách sử dụng thành phần kết hợp Image.

Điều kiện tiên quyết

  • Kiến thức cơ bản về cách tạo và chạy ứng dụng trong Android Studio.
  • Kiến thức cơ bản về cách thêm thành phần giao diện người dùng, chẳng hạn như thành phần kết hợp văn bản.

Kiến thức bạn sẽ học được

  • Cách thêm ảnh hoặc hình ảnh vào ứng dụng Android.
  • Cách dùng thành phần kết hợp Image để hiện hình ảnh trong ứng dụng.
  • Các phương pháp hay nhất khi sử dụng tài nguyên String.

Sản phẩm bạn sẽ tạo ra

  • Cải thiện ứng dụng Happy Birthday (Chúc mừng sinh nhật) để thêm hình ảnh.

Bạn cần có

2. Thiết lập ứng dụng

Mở dự án Happy Birthday trong Android Studio mà bạn thực hiện từ lớp học lập trình trước.

Khi bạn chạy ứng dụng, ứng dụng sẽ có dạng như ảnh chụp màn hình này.

fdf3fc55ab1d348a.png

Thêm hình ảnh vào dự án

Trong nhiệm vụ này, bạn sẽ tải một hình ảnh xuống từ Internet rồi thêm hình ảnh đó vào ứng dụng Happy Birthday.

  1. Mở hình ảnh cho ứng dụng thiệp sinh nhật qua đường liên kết này.
  2. Nhấp vào Download (Tải xuống).

1d731e32164fca8a.png

  1. Nhấp chuột phải vào hình ảnh rồi lưu tệp trên máy tính dưới dạng androidparty.png.
  2. Ghi lại vị trí bạn đã lưu hình ảnh.

Ví dụ: bạn có thể đã lưu hình ảnh trong thư mục Downloads (Tệp đã tải xuống).

  1. Trong Android Studio, hãy nhấp vào View (Xem) > Tool Windows (Cửa sổ công cụ) > Resource Manager (Trình quản lý tài nguyên) hoặc nhấp vào thẻ Resource Manager (Trình quản lý tài nguyên) ở bên cạnh cửa sổ Project (Dự án).

3cda2692405276d.png

3b6c04c505468229.png

  1. Nhấp vào + (Add resources to the module) > Import Drawables (Thêm tài nguyên vào mô-đun > Nhập đối tượng có thể vẽ).

a85b707150fcff9a.png

  1. Trong trình duyệt tệp, hãy chọn tệp hình ảnh mà bạn tải xuống rồi nhấp vào Open (Mở).

Thao tác này sẽ mở hộp thoại Import Drawables (Nhập đối tượng có thể vẽ).

d64abadd7b79ecf0.png

  1. Android Studio sẽ cho thấy bản xem trước của hình ảnh được tải xuống. Chọn Density (Mật độ) trên danh sách thả xuống của Qualifier Type (Loại bộ hạn định). Bạn sẽ tìm hiểu lý do cần làm việc này ở một phần sau.

loại bộ hạn định đang được đặt thành mật độ

  1. Chọn Không có mật độ (No Density) trên danh sách Giá trị (Value).

 không có dpi nào được chọn trong trình đơn thả xuống chứa giá trị

Thiết bị Android có nhiều loại kích thước màn hình (chẳng hạn như điện thoại, máy tính bảng, TV, v.v. ) và màn hình của chúng cũng có nhiều kích thước pixel. Tức là trong khi một thiết bị có kích thước 160 pixel mỗi inch vuông, thì một thiết bị khác lại đáp ứng 480 pixel trên cùng không gian đó. Nếu bạn không xem xét những biến thể này trong phần mật độ pixel thì có thể hệ thống sẽ điều chỉnh tỷ lệ hình ảnh của bạn. Việc này có thể khiến hình ảnh bị mờ, hình ảnh lớn chiếm nhiều bộ nhớ hoặc hình ảnh sai kích thước.

Khi bạn đổi kích thước hình ảnh thành kích thước lớn hơn quy cách mà hệ thống Android có thể xử lý, hệ thống sẽ báo lỗi hết bộ nhớ. Đối với ảnh chụp và hình nền, chẳng hạn như hình ảnh hiện tại, androidparty.png, bạn nên đặt chúng vào thư mục drawable-nodpi để ngừng hành vi đổi kích thước.

Để biết thêm thông tin về mật độ pixel, hãy xem nội dung Hỗ trợ nhiều mật độ pixel.

  1. Nhấp vào Next (Tiếp theo).
  2. Android Studio cho bạn thấy cấu trúc thư mục chứa hình ảnh. Hãy lưu ý thư mục drawable-nodpi.
  3. Nhấp vào Import(C) (Nhập (C)).

74d23f98b8018f93.png

Android Studio tạo thư mục drawable-nodpi rồi đưa hình ảnh vào thư mục đó. Trong khung hiển thị dự án của Android Studio, tên tài nguyên sẽ có dạng androidparty.png (nodpi). Trong hệ thống tệp trên máy tính, Android Studio sẽ tạo một thư mục có tên drawable-nodpi.

5e5ca441e391929e.png

Cửa sổ này được đặt trong thư mục drawable-nodpi

Nếu hình ảnh được nhập thành công thì Android Studio sẽ thêm hình ảnh đó vào danh sách trong thẻ Drawable (Đối tượng có thể vẽ). Danh sách này bao gồm mọi hình ảnh và biểu tượng cho ứng dụng. Giờ đây, bạn có thể sử dụng hình ảnh này trong ứng dụng của mình.

cho thấy hình ảnh mới được thêm vào

  1. Quay lại khung hiển thị của dự án, nhấp vào View > Tool Windows > Project (Xem > Cửa sổ công cụ > Dự án) hoặc nhấp vào thẻ Project (Dự án) ở ngoài cùng bên trái.
  2. Nhấp vào app > res > drawable (ứng dụng > tài nguyên > đối tượng có thể vẽ) rồi xác nhận rằng hình ảnh đã ở trong thư mục drawable.

f95964d9f0ee2dba.png

3. Thêm thành phần kết hợp Hình ảnh

Để hiện hình ảnh trong ứng dụng, bạn cần xác định vị trí hiện hình ảnh. Tương tự như khi sử dụng thành phần kết hợp Text để hiện văn bản, bạn có thể dùng thành phần kết hợp Image để cho thấy hình ảnh.

Trong nhiệm vụ này, bạn sẽ thêm một thành phần kết hợp Image vào ứng dụng, đặt hình ảnh của thành phần đó thành hình ảnh mà bạn tải xuống, sau đó đặt và điều chỉnh kích thước của hình ảnh sao cho vừa với màn hình.

Thêm hàm có khả năng kết hợp để thêm hình ảnh

  1. Trong tệp MainActivity.kt, hãy thêm một hàm có khả năng kết hợp GreetingImage() sau hàm GreetingText().
  2. Truyền vào hàm GreetingImage() 2 tham số String: 1 tham số tên là message cho lời chúc sinh nhật và tham số còn lại tên là from cho chữ ký.
@Composable
fun GreetingImage(message: String, from: String) {
}
  1. Mỗi hàm có khả năng kết hợp phải chấp nhận tham số Modifier (không bắt buộc). Đối tượng sửa đổi cho thành phần trên giao diện người dùng biết cách bố trí, hiển thị hoặc hoạt động trong bố cục mẹ. Thêm một tham số khác vào thành phần kết hợp GreetingImage().
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
}

Tài nguyên trong Jetpack Compose

Tài nguyên (resource) là các tệp bổ sung và nội dung tĩnh mà mã của bạn sử dụng, chẳng hạn như bitmap, chuỗi giao diện người dùng, hướng dẫn về ảnh động, v.v. Để biết thêm thông tin về tài nguyên trong Android, hãy xem nội dung Tổng quan về tài nguyên ứng dụng.

Bạn phải luôn tách riêng các tài nguyên ứng dụng (chẳng hạn như hình ảnh và chuỗi) khỏi mã để có thể duy trì chúng một cách độc lập. Trong thời gian chạy, Android sử dụng tài nguyên phù hợp dựa trên cấu hình hiện tại. Ví dụ: bạn nên cung cấp bố cục khác của giao diện người dùng dựa trên kích thước màn hình hoặc các chuỗi khác dựa trên chế độ cài đặt ngôn ngữ.

Nhóm tài nguyên

Bạn nên luôn đặt mỗi loại tài nguyên trong một thư mục con cụ thể thuộc thư mục res/ của dự án. Ví dụ: sau đây là hệ phân cấp tệp của một dự án đơn giản:

MyProject/
    src/
        MyActivity.kt
    res/
        drawable/
            graphic.png
        mipmap/
            icon.png
        values/
            strings.xml

Như bạn có thể thấy trong ví dụ này, thư mục res/ chứa tất cả các tài nguyên trong thư mục con, bao gồm cả thư mục drawable/ cho tài nguyên hình ảnh, thư mục mipmap/ cho biểu tượng trình chạy và thư mục values/ cho tài nguyên chuỗi. Để tìm hiểu thêm về cách sử dụng, định dạng và cú pháp đối với tài nguyên ứng dụng, hãy xem nội dung Tổng quan về các loại tài nguyên.

Truy cập tài nguyên

Jetpack Compose có thể giúp bạn truy cập vào các tài nguyên đã xác định trong dự án Android của mình. Bạn có thể truy cập tài nguyên bằng mã tài nguyên được tạo trong lớp R của dự án.

Lớp R là lớp do Android tự động tạo, có chứa mã nhận dạng của tất cả tài nguyên trong dự án. Trong hầu hết các trường hợp, mã tài nguyên sẽ giống tên tệp. Ví dụ: bạn có thể truy cập hình ảnh trong hệ phân cấp tệp trước đó bằng mã này:

R.drawable.graphic

R là lớp được tạo tự động đối tượng có thể vẽ là thư mục con trong thư mục res có nội dung đồ hoạ là mã tài nguyên

Trong nhiệm vụ tiếp theo, bạn sẽ dùng hình ảnh (tệp androidparty.png) mà bạn đã thêm trong nhiệm vụ trước.

  1. Trong hàm GreetingImage(), hãy khai báo một thuộc tính val rồi đặt tên cho thuộc tính đó là image.
  2. Gọi hàm painterResource() bằng cách truyền vào tài nguyên androidparty. Chỉ định giá trị trả về cho biến image.
val image = painterResource(R.drawable.androidparty)

Android Studio làm nổi bật tệp .painterResource vì bạn cần nhập hàm này để biên dịch ứng dụng.

82323978341a0bdc.png

  1. Nhấp vào .painterResource được Android Studio làm nổi bật.
  2. Nhấp vào Import (Nhập) trong cửa sổ bật lên để thêm dữ liệu nhập cho androidx.compose.ui.res.painterResource.

Hàm painterResource() tải một tài nguyên hình ảnh có thể vẽ và lấy mã tài nguyên (R.drawable.androidparty trong trường hợp này) làm đối số.

  1. Sau khi gọi hàm painterResource(), hãy thêm thành phần kết hợp Image rồi truyền vào image làm đối số được đặt tên cho painter.
Image(
    painter = image
)

Android Studio sẽ làm nổi bật mã Image vì bạn cần nhập hàm này để biên dịch ứng dụng.

e2bead11643e0577.png

Để khắc phục cảnh báo này, hãy thêm nội dung nhập sau vào đầu tệp MainActivity.kt:

import androidx.compose.foundation.Image

Cảnh báo ban đầu hiện đã được giải quyết nhưng nếu bạn di chuột qua từ Image, Android Studio sẽ hiển thị cảnh báo mới có nội dung: "None of the following functions can be called with the arguments supplied" (Không gọi được hàm nào sau đây bằng các đối số đã cung cấp). Điều này là do đối số đã cho không khớp với bất kỳ chữ ký hàm Image nào.

ad35f0a40f8fc849.png

Cảnh báo này sẽ được khắc phục trong phần tiếp theo.

Kiểm tra khả năng hỗ trợ tiếp cận của ứng dụng

Khi làm theo các phương pháp lập trình để hỗ trợ tiếp cận, bạn giúp tất cả người dùng của mình, bao gồm cả những người dùng khuyết tật, thao tác và tương tác với ứng dụng của bạn một cách dễ dàng hơn.

Android Studio đưa ra các gợi ý và cảnh báo, giúp bạn xây dựng ứng dụng sao cho người dùng có thể tiếp cận dễ dàng hơn. Thông tin mô tả nội dung xác định mục đích của một thành phần trên giao diện người dùng, giúp ứng dụng dễ sử dụng hơn nhờ TalkBack.

Tuy nhiên, hình ảnh trong ứng dụng này chỉ được dùng cho mục đích trang trí. Thao tác thêm thông tin mô tả nội dung cho hình ảnh sẽ khiến người dùng khó sử dụng ứng dụng hơn qua TalkBack trong trường hợp cụ thể này. Thay vì viết thông tin mô tả nội dung thông báo cho người dùng, bạn có thể thiết lập đối số contentDescription của hình ảnh là null để TalkBack bỏ qua thành phần kết hợp Image.

  • Trong thành phần kết hợp Image, hãy thêm một đối số khác có tên contentDescription rồi thiết lập giá trị của đối số đó thành null.
Image(
    painter = image,
    contentDescription = null
)

Xem trước thành phần kết hợp Image

Trong nhiệm vụ này, bạn xem trước thành phần kết hợp hình ảnh rồi chạy ứng dụng trên trình mô phỏng hoặc thiết bị.

  1. Trong hàm BirthdayCardPreview(), hãy thay thế lệnh gọi hàm GreetingText() bằng lệnh gọi hàm GreetingImage().

Hàm của bạn phải trông giống như đoạn mã sau:

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        GreetingImage(
            message = "Happy Birthday Sam!",
            from = "From Emma"
        )
    }
}
  1. Ngăn Design (Thiết kế) sẽ tự động cập nhật, nếu không, hãy nhấp vào 609ccb451d05cf6b.png để tạo.

Xin lưu ý rằng bạn không thể thấy văn bản đó nữa vì hàm mới chỉ có thành phần kết hợp Image chứ không phải thành phần kết hợp Text.

acd47e25eb2a8d55.png

4. Thêm bố cục hộp

3 thành phần bố cục tiêu chuẩn, cơ bản trong Compose là các thành phần kết hợp Column, Row, và Box. Bạn đã tìm hiểu về các thành phần kết hợp ColumnRow trong các lớp học lập trình trước. Giờ đây, bạn sẽ có thể khám phá thêm về thành phần kết hợp Box.

Bố cục Box là một trong những thành phần bố cục chuẩn trong Compose. Sử dụng bố cục Box để xếp chồng các phần tử lên nhau. Bố cục Box cũng cho phép bạn định cấu hình vị trí cụ thể của các phần tử có trong bố cục đó.

4d191637aaecf374.png

  1. Trong hàm GreetingImage(), hãy thêm thành phần kết hợp Box xung quanh thành phần kết hợp Image như sau:
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
    val image = painterResource(R.drawable.androidparty)
    Box {
        Image(
            painter = image,
            contentDescription = null
        )
    }
}
  1. Nhập hàm androidx.compose.foundation.layout.Box khi Android Studio nhắc.
  2. Thêm mã để truyền tham số modifier đến thành phần kết hợp Box.
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
    val image = painterResource(R.drawable.androidparty)
    Box(modifier) {
        Image(
            painter = image,
            contentDescription = null
        )
    }
}
  1. Ở cuối thành phần kết hợp Box, hãy gọi hàm GreetingText() rồi truyền vào đó lời chúc sinh nhật, chữ ký và đối tượng sửa đổi sau:
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
    val image = painterResource(R.drawable.androidparty)
    Box(modifier) {
        Image(
            painter = image,
            contentDescription = null
        )
        GreetingText(
            message = message,
            from = from,
            modifier = Modifier
                .fillMaxSize()
                .padding(8.dp)
        )
    }
}
  1. Hãy lưu ý bản xem trước đã cập nhật trong ngăn Design (Thiết kế).

Bạn sẽ thấy văn bản và hình ảnh.

Hình nền được neo vào phía trên cùng

  1. Để những thay đổi trên được phản ánh trong trình mô phỏng hoặc thiết bị, ở hàm onCreate(), hãy thay thế lệnh gọi hàm GreetingText() bằng lệnh gọi hàm GreetingImage().

Khối setContent sẽ có dạng như đoạn mã sau:

setContent {
    HappyBirthdayTheme {
        // A surface container using the 'background' color from the theme
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background
        ) {
            GreetingImage(
                message = "Happy Birthday Sam!",
                from = "From Emma"
            )
        }
    }
}

Lưu ý rằng hình ảnh rộng bằng màn hình nhưng được neo vào đầu màn hình. Ở cuối màn hình có một khoảng trắng trông không hấp dẫn lắm. Trong nhiệm vụ tiếp theo, bạn sẽ lấp đầy chiều rộng và chiều cao của màn hình rồi điều chỉnh tỷ lệ hình ảnh để lấp đầy toàn bộ màn hình.

5. Thay đổi độ mờ và điều chỉnh tỷ lệ hình ảnh

Trong nhiệm vụ này, bạn sẽ tạo hình ảnh toàn màn hình để làm đẹp ứng dụng. Hãy sử dụng các tham số ContentScale để thực hiện.

Điều chỉnh tỷ lệ nội dung

Bạn đã thêm hình ảnh vào ứng dụng cũng như đã điều chỉnh vị trí của hình ảnh. Giờ đây, bạn cần điều chỉnh loại tỷ lệ hình ảnh (cho biết cách định kích thước hình ảnh) để hình ảnh lấp đầy toàn màn hình.

Hiện có khá nhiều loại ContentScale. Bạn sẽ sử dụng tỷ lệ tham số ContentScale.Crop để điều chỉnh tỷ lệ hình ảnh một cách đồng nhất nhằm duy trì tỷ lệ khung hình sao cho chiều rộng và chiều cao của hình ảnh bằng hoặc lớn hơn kích thước tương ứng của màn hình.

  1. Thêm đối số có tên ContentScale vào hình ảnh.
Image(
    painter = image,
    contentDescription = null,
    contentScale = ContentScale.Crop
)
  1. Nhập giao diện androidx.compose.ui.layout.ContentScale khi Android Studio nhắc.
  2. Xem ngăn Design (Thiết kế).

Bây giờ, hình ảnh sẽ lấp đầy toàn bộ màn hình như bạn có thể thấy trong ảnh chụp màn hình sau:

ae1a5ec6b294f466.png

Thay đổi độ mờ

Để cải thiện độ tương phản của ứng dụng, hãy thay đổi độ mờ của hình nền.

Thêm tham số alpha vào thành phần kết hợp Image rồi đặt tham số đó thành 0.5F.

Image(
    painter = image,
    contentDescription = null,
    contentScale = ContentScale.Crop,
    alpha = 0.5F
)

Lưu ý đến sự thay đổi về độ mờ của hình ảnh.

Vậy là lập trình khá nhiều rồi! Giờ là lúc xem trước thành quả của bạn.

Chạy ứng dụng

Chạy ứng dụng trên thiết bị hoặc trình mô phỏng.

9d1416521733e8c.png

Vậy là đã xử lý xong phần văn bản lời chúc và hình ảnh toàn màn hình. Bạn cũng đã thay đổi độ mờ của hình ảnh.

Đối tượng sửa đổi Layout (Bố cục)

Các đối tượng sửa đổi được dùng để trang trí hoặc thêm hành vi vào thành phần trên giao diện người dùng Jetpack Compose. Ví dụ: bạn có thể thêm nền, khoảng đệm hoặc hành vi vào hàng, văn bản hoặc nút. Để thiết lập các đối tượng này, thành phần kết hợp hoặc bố cục cần chấp nhận đối tượng sửa đổi làm tham số.

Trong một lớp học lập trình trước đó, bạn đã tìm hiểu về các đối tượng sửa đổi và sử dụng đối tượng sửa đổi khoảng đệm (Modifier.padding) để thêm không gian xung quanh thành phần kết hợp Text. Đối tượng sửa đổi có thể rất hữu ích và bạn sẽ thấy điều đó trong cả lộ trình này cũng như các lộ trình sắp tới.

Ví dụ: thành phần kết hợp Text này có một đối số Modifier thay đổi màu nền thành xanh lục.

// Example
Text(
    text = "Hello, World!",
    // Solid element background color
    modifier = Modifier.background(color = Color.Green)
)

Tương tự như ví dụ trên, bạn có thể thêm Đối tượng sửa đổi vào bố cục để định vị các thành phần con bằng cách sử dụng các thuộc tính sắp xếp và căn chỉnh.

Để thiết lập vị trí bố cục con trong Row, hãy thiết lập các đối số horizontalArrangementverticalAlignment. Đối với Column, hãy thiết lập các đối số verticalArrangementhorizontalAlignment.

Thuộc tính sắp xếp được dùng để sắp xếp các phần tử con khi kích thước của bố cục lớn hơn tổng kích thước các phần tử con.

Ví dụ: khi kích thước của Column lớn hơn tổng kích thước của các phần tử con, bạn có thể chỉ định verticalArrangement để xác định vị trí của phần tử con trong Column. Dưới đây là hình minh hoạ những cách sắp xếp dọc:

chiều cao bằng nhau, khoảng cách giữa, khoảng cách xung quanh, khoảng cách đồng đều, trên cùng, giữa và dưới cùng

Tương tự, khi kích thước của Row lớn hơn tổng kích thước của các phần tử con, bạn có thể chỉ định horizontalArrangement để xác định vị trí của phần tử con trong Row. Dưới đây là hình minh hoạ những cách sắp xếp ngang:

trọng số bằng nhau, khoảng cách giữa, khoảng cách xung quanh, khoảng cách đồng đều, ở cuối, bắt đầu ở giữa

Thuộc tính căn chỉnh được dùng để căn chỉnh các phần tử con ở đầu, giữa hoặc cuối bố cục.

6. Căn chỉnh và sắp xếp văn bản

Trong nhiệm vụ này, bạn sẽ quan sát đoạn mã mà bạn thêm ở trong lớp học lập trình trước để sắp xếp văn bản trong ứng dụng.

  1. Trong tệp MainActivity.kt, chuyển đến hàm GreetingText(). Thuộc tính verticalArrangement trong cột được đặt thành Arrangement.Center. Do đó, nội dung văn bản sẽ được căn giữa trên màn hình.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp,
            textAlign = TextAlign.Center
        )
        Text(
            text = from,
            fontSize = 36.sp,
            modifier = Modifier
                .padding(16.dp)
                .align(alignment = Alignment.End)
        )
    }
}

Khoảng đệm

Một thành phần trên giao diện người dùng bao bọc nội dung. Để thành phần này không bao bọc quá chật, bạn có thể chỉ định số lượng khoảng đệm mỗi bên.

Thành phần kết hợp văn bản không có khoảng đệm

Thành phần kết hợp văn bản có khoảng đệm

Khoảng đệm được dùng làm đối tượng sửa đổi, tức là bạn có thể áp dụng khoảng đệm cho thành phần kết hợp bất kỳ. Đối với mỗi bên của thành phần kết hợp, đối tượng sửa đổi padding sẽ lấy một đối số không bắt buộc giúp xác định số lượng khoảng đệm.

Sơ đồ thể hiện khoảng đệm trên cùng, bắt đầu, dưới cùng và kết thúc.

// This is an example.
Modifier.padding(
    start = 16.dp,
    top = 16.dp,
    end = 16.dp,
    bottom = 16.dp
)
  1. Đến lượt bạn! Trong tệp MainActivity.kt, hãy di chuyển đến vị trí gọi hàm GreetingText() rồi lưu ý đến thuộc tính khoảng đệm.
modifier = Modifier
    .fillMaxSize()
    .padding(8.dp)
  1. Tương tự, hãy lưu ý bên trong hàm GreetingText(), khoảng đệm cho thành phần kết hợp Text của chữ ký.
modifier = Modifier
    .padding(16.dp)
    .align(alignment = Alignment.End)

7. Áp dụng các phương pháp hay liên quan đến mã

Dịch

Khi viết ứng dụng, bạn cần nhớ là có thể sau này các ứng dụng đó sẽ được dịch sang một ngôn ngữ khác. Như đã tìm hiểu trong một lớp học lập trình trước đó, loại dữ liệu String là một trình tự các ký tự, chẳng hạn như "Happy Birthday Sam!".

Chuỗi mã hoá cứng (hardcoded string) là một chuỗi được viết trực tiếp trong mã của ứng dụng. Chuỗi mã hoá cứng sẽ gây khó khăn cho việc dịch ứng dụng sang ngôn ngữ khác cũng như việc dùng lại chuỗi cho nhiều vị trí trong ứng dụng. Bạn có thể giải quyết những vấn đề này bằng cách trích xuất chuỗi vào một tệp tài nguyên. Thay vì mã hoá cứng chuỗi trong mã, bạn đưa các chuỗi này vào một tệp, đặt tên cho tài nguyên chuỗi rồi sử dụng các tên đó mỗi khi muốn sử dụng chuỗi. Tên chuỗi vẫn được giữ nguyên, ngay cả khi bạn thay đổi nội dung chuỗi hoặc dịch sang ngôn ngữ khác.

  1. Trong tệp MainActivity.kt, hãy di chuyển đến hàm onCreate(). Chọn lời chúc sinh nhật, chuỗi Happy Birthday Sam! không có dấu ngoặc kép.
  2. Nhấp vào biểu tượng bóng đèn ở bên trái màn hình.
  3. Chọn Extract string resource (Trích xuất tài nguyên chuỗi).

eed032464b68ee5.png

Android Studio mở hộp thoại Extract Resource (Trích xuất tài nguyên). Trong hộp thoại này, bạn có thể tuỳ chỉnh tên của tài nguyên chuỗi cũng như một số thông tin chi tiết về cách lưu trữ tài nguyên đó. Trường Resource name (Tên tài nguyên) là nơi bạn nhập tên của chuỗi. Trường Resource value (Giá trị tài nguyên) là nơi bạn nhập chính chuỗi đó.

  1. Trong hộp thoại Extract Resource (Trích xuất tài nguyên), hãy thay đổi Resource name (Tên tài nguyên) thành happy_birthday_text.

Tên tài nguyên chuỗi phải viết bằng chữ thường và các từ được phân cách bằng dấu gạch dưới. Giữ nguyên các chế độ cài đặt khác theo mặc định.

d6cb11f087b79f1e.png

  1. Nhấp vào OK.
  2. Chú ý những thay đổi trong mã.

Chuỗi mã hoá cứng hiện đã được thay thế bằng lệnh gọi đến hàm getString().

GreetingImage(
    message = getString(R.string.happy_birthday_text),
    from = "From Emma",
    modifier = Modifier.padding(8.dp)
)
  1. Trong ngăn Project (Dự án), hãy mở tệp strings.xml trong đường dẫn app > res > values > strings.xml và nhận thấy Android Studio tạo một tài nguyên chuỗi có tên happy_birthday_text.
<resources>
    <string name="app_name">Happy Birthday</string>
    <string name="happy_birthday_text">Happy Birthday Sam!</string>
</resources>

Tệp strings.xml có một danh sách chuỗi mà người dùng sẽ thấy trong ứng dụng. Hãy lưu ý rằng tên ứng dụng cũng là tài nguyên chuỗi. Việc đưa tất cả chuỗi vào cùng một vị trí sẽ giúp bạn dễ dàng dịch tất cả văn bản trong ứng dụng, đồng thời dễ dàng sử dụng lại các chuỗi trong các phần khác của ứng dụng.

  1. Hãy thực hiện các bước tương tự để trích xuất văn bản cho thành phần kết hợp Text chữ ký, nhưng lần này hãy nhập signature_text trong trường Resource name (Tên tài nguyên).

Sau khi hoàn thành, tệp sẽ có dạng như đoạn mã sau:

<resources>
    <string name="app_name">Happy Birthday</string>
    <string name="happy_birthday_text">Happy Birthday Sam!</string>
    <string name="signature_text">From Emma</string>
</resources>
  1. Hãy cập nhật BirthdayCardPreview() để sử dụng stringResource() và các chuỗi đã trích xuất.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        GreetingImage(
            message = stringResource(R.string.happy_birthday_text),
            from = stringResource(R.string.signature_text)
        )
    }
}
  1. Chạy lại ứng dụng để đảm bảo ứng dụng vẫn hoạt động.

8. Tham gia thử thách này

Vậy là bạn đã biết cách thêm hình ảnh vào ứng dụng. Tiếp theo là một thử thách dành cho bạn:

  1. Sắp xếp hoặc căn chỉnh thành phần kết hợp văn bản chữ ký sao cho thành phần này được căn chỉnh ở vị trí giữa màn hình.

Ứng dụng của bạn sẽ có dạng như sau:

b681900fe13e5598.png

Bạn có thể tham khảo mã giải pháp sau đây của hàm GreetingText():

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp,
            textAlign = TextAlign.Center
        )
        Text(
            text = from,
            fontSize = 36.sp,
            modifier = Modifier
                .padding(16.dp)
                .align(alignment = Alignment.CenterHorizontally)
        )
    }
}

9. Lấy mã giải pháp

Mã giải pháp cho ứng dụng Happy Birthday có trên GitHub.

GitHub là dịch vụ cho phép nhà phát triển quản lý mã trong dự án phần mềm. Dịch vụ này sử dụng Git, một hệ thống quản lý phiên bản theo dõi các thay đổi được thực hiện cho từng phiên bản của mã. Nếu từng xem nhật ký phiên bản của một tài liệu trên Google Tài liệu thì bạn có thể xem nội dung nào đã được chỉnh sửa và thời điểm chỉnh sửa các nội dung đó. Tương tự như vậy, bạn có thể theo dõi nhật ký phiên bản mã của một dự án. Điều này rất hữu ích khi bạn làm việc trong một dự án với tư cách cá nhân hoặc nhóm.

GitHub cũng có một trang web cho phép bạn xem và quản lý dự án. Đường liên kết GitHub này cho phép bạn duyệt xem trực tuyến các tệp của dự án Happy Birthday hoặc tải những tệp này xuống máy tính.

Để tải mã cho lớp học lập trình đã kết thúc xuống, bạn có thể sử dụng lệnh git này:

$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-birthday-card-app.git

Ngoài ra, bạn có thể tải kho lưu trữ xuống dưới dạng tệp zip, sau đó giải nén và mở trong Android Studio.

Nếu bạn muốn xem mã giải pháp, hãy xem mã đó trên GitHub.

Nhánh trên GitHub

Trước khi tìm hiểu về nhánh, hãy tìm hiểu về kho lưu trữ (repository). Kho lưu trữ là toàn bộ dự án (thư mục và tệp) mà bạn nhân bản (sao chép) trên máy tính. Nhánh là một phiên bản của kho lưu trữ, hay nói cách khác là một nhánh phát triển độc lập. Ví dụ: trong khoá học này, nhánh starter (khởi động) có thể là một phiên bản của dự án mà bạn đã sử dụng để xây dựng trong lớp học lập trình. Nhánh main hoặc solution (giải pháp) là phiên bản dự án ở cuối lớp học lập trình, chứa mã giải pháp hoàn chỉnh.

Một kho lưu trữ có thể chứa nhiều nhánh, tức là có nhiều phiên bản mã trong kho lưu trữ đó.

10. Kết luận

Bạn đã thêm một hình ảnh vào ứng dụng Happy Birthday, dùng đối tượng sửa đổi để căn chỉnh văn bản, tuân theo các nguyên tắc hỗ trợ tiếp cận và giúp hoạt động dịch sang các ngôn ngữ khác trở nên dễ dàng hơn! Quan trọng hơn, bạn đã tạo xong ứng dụng Happy Birthday của riêng mình! Hãy chia sẻ thành phẩm của bạn lên mạng xã hội và dùng hashtag #AndroidBasics để chúng tôi nhìn thấy nhé!

Tóm tắt

  • Thẻ Resource Manager (Trình quản lý tài nguyên) trong Android Studio giúp bạn bổ sung và sắp xếp hình ảnh cũng như các tài nguyên khác.
  • Thành phần kết hợp Image là một thành phần trên giao diện người dùng cho thấy hình ảnh trong ứng dụng.
  • Thành phần kết hợp Image phải có thông tin mô tả nội dung riêng để giúp người dùng dễ tiếp cận hơn với ứng dụng của bạn.
  • Văn bản mà người dùng thấy (chẳng hạn như lời chúc sinh nhật) nên được trích xuất vào một tài nguyên chuỗi để giúp hệ thống dịch ứng dụng sang các ngôn ngữ khác một cách dễ dàng hơn.

Tìm hiểu thêm