Bài 3.09. Sử dụng ImageView
Nội dung bài học
- Tổng quan về ImageView
- Sử dụng ImageView cơ bản
- Sử dụng ImageView để ẩn, hiện mật khẩu
- Cá nhân hóa mặt nạ mã hóa mật khẩu
Tổng quan về ImageView.
- ImageView là một loại view chuyên dùng để hiển thị ảnh.
- Trong nội dung bài này ta sẽ ứng dụng ImageView ở mức cơ bản.
- Cụ thể chi tiết hơn về ImageView ta sẽ vận dụng trong bài học tạo album ảnh về sau.
- Ta có thể thiết lập sự kiện view được nhấn/click để thực hiện hành động nào đó tương tự các view khác trong Android.
- Khi sử dụng, ta sử dụng kiến thức về các thuộc tính khác đã biết của một view trong Android.
- Chú ý thuộc tính srcCompat. Đây là thuộc tính dùng để liên kết ImageView với một tài nguyên có thể hiển thị trong drawable của Android.
- Trong code Kotlin ta có thể thiết lập tài nguyên hiển thị lên ImageView thông qua phương thức setImageResource(int sourceId).
Sử dụng ImageView cơ bản
- Ta có thể sử dụng thuộc tính scaleType để kiểm soát cách thức nội dung ảnh được vẽ trong ImageView.
- Các chế độ có thể sử dụng gồm:
- fitXY: căng ảnh ra cho vừa khớp với chiều rộng và cao của ImageView.
- fitStart: khớp ảnh với phần đầu của ImageView.
- fitEnd: khớp ảnh với phần cuối của ImageView.
- centerCrop: phóng to ảnh cho lớn hơn hoặc bằng cả hai chiều(rộng/cao) của ImageView và cắt lấy phần trung tâm ảnh.
- matrix: co dãn ảnh sử dụng ma trận, thường sẽ lấy kích thước ban đầu của ảnh đặt vào gốc tọa độ góc trái trên của ImageView.
- center: cắt lấy phần trung tâm ảnh không co dãn ảnh gốc ban đầu.
- fitCenter: co dãn ảnh để vừa khớp với một chiều của ImageView và lấy phần trung tâm.
- centerInside: co dãn ảnh để kích thước ảnh nhỏ hơn hoặc bằng hai chiều của ImageView sau đó lấy phần trung tâm ảnh.
- Kết quả cần đạt:

- File activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<ImageView
android:id="@+id/image_pet"
android:layout_width="280dp"
android:layout_height="280dp"
android:contentDescription="@string/img_desc"
android:scaleType="centerInside"
android:src="@drawable/cat1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ImageContrastCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
- File MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val imageViewPet = findViewById<ImageView>(R.id.image_pet)
var counter = 0
imageViewPet.setOnClickListener {
if (counter % 2 == 0) {
imageViewPet.setImageResource(R.drawable.android_0)
} else {
imageViewPet.setImageResource(R.drawable.cat1)
}
counter++
}
}
}
- Project mẫu: nhấn vào đây
Sử dụng ImageView để ẩn, hiện mật khẩu
- Trên giao diện của view nhập mật khẩu, có những lúc ta cần kiểm tra xem liệu mật khẩu của mình đã đúng chưa.
- Lúc này ta cần có tính năng hiển thị mật khẩu cho người dùng đối chiếu.
- Sau đó ta cần cho phép người dùng ẩn mật khẩu đi bằng tính năng ngược lại tính năng trên.
- Để mô phỏng trường hợp trên ta sử dụng ImageView để ẩn hiện mật khẩu.
- Có 2 khả năng xảy ra:
- Khả năng 1: mật khẩu đang mã hóa, ta sẽ hiển thị hình con mắt để người dùng nhấn vào thì hiện mật khẩu và đổi hình con mắt thành con mắt gạch chéo.
- Khả năng 2: mật khẩu đang hiển thị tường minh. Lúc này ta phải hiển thị hình con mắt gạch chéo để người dùng nhấn vào nó mã hóa mật khẩu ẩn đi tránh bị lộ.
- Để kiểm tra mật khẩu có đang được mã hóa bằng mặt nạ không, ta gọi thuộc tính transformationMethod và đối chiếu với lớp tạo mặt nạ đang sử dụng để ẩn mật khẩu đi.
- Để bật lại chế độ mặt nạ mã hóa cho mật khẩu ta gán đối tượng transformation cho thuộc tính transformationMethod.

- Code minh họa cho tính năng trên. Trong đó PasswordMaskTransformation là lớp tạo mặt nạ cho mật khẩu:
private fun processPassword() {
if (textPassword.transformationMethod.equals(transformation)) {
textPassword.transformationMethod =
HideReturnsTransformationMethod.getInstance()
imgShowPassword.setImageResource(R.drawable.ic_hide_pwd_24)
} else {
textPassword.transformationMethod = transformation
imgShowPassword.setImageResource(R.drawable.ic_show_password)
}
}
Cá nhân hóa mặt nạ mã hóa mật khẩu
- File activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_64"
android:text="@string/label_login"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edt_email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_32"
android:layout_marginEnd="@dimen/margin_32"
android:layout_marginBottom="8dp"
android:ems="10"
android:hint="@string/hint_enter_email"
android:importantForAutofill="no"
android:inputType="text|textEmailAddress"
android:minHeight="48dp"
android:textColorHint="#8D6E63"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="VisualLintTextFieldSize,TextContrastCheck" />
<EditText
android:id="@+id/edt_pwd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="@string/hint_enter_pwd"
android:importantForAutofill="no"
android:inputType="text"
android:minHeight="48dp"
android:textColorHint="#8D6E63"
app:layout_constraintEnd_toEndOf="@+id/edt_email"
app:layout_constraintStart_toStartOf="@+id/edt_email"
app:layout_constraintTop_toTopOf="@+id/guideline"
tools:ignore="VisualLintTextFieldSize" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.36" />
<Button
android:id="@+id/btn_register"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_32"
android:layout_marginTop="@dimen/margin_64"
android:layout_marginEnd="16dp"
android:text="@string/action_register"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edt_pwd"
tools:ignore="VisualLintButtonSize" />
<Button
android:id="@+id/btn_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="@dimen/margin_32"
android:text="@string/action_login"
app:layout_constraintBottom_toBottomOf="@+id/btn_register"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="@+id/btn_register"
tools:ignore="VisualLintButtonSize" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<ImageView
android:id="@+id/img_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:importantForAccessibility="no"
app:layout_constraintBottom_toBottomOf="@+id/edt_pwd"
app:layout_constraintEnd_toEndOf="@+id/edt_pwd"
app:layout_constraintTop_toTopOf="@+id/edt_pwd"
app:srcCompat="@drawable/ic_show_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
- File MainActivity.kt:
class MainActivity : AppCompatActivity() {
private lateinit var textEmail: EditText
private lateinit var textPassword: EditText
private lateinit var imgShowPassword: ImageView
private lateinit var transformation: PasswordMaskTransformation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupViews()
transformation = PasswordMaskTransformation()
textPassword.transformationMethod = transformation
}
private fun setupViews() {
textEmail = findViewById(R.id.edt_email)
textPassword = findViewById(R.id.edt_pwd)
imgShowPassword = findViewById(R.id.img_pwd)
imgShowPassword.setOnClickListener {
processPassword()
}
}
private fun processPassword() {
if (textPassword.transformationMethod.equals(transformation)) {
textPassword.transformationMethod =
HideReturnsTransformationMethod.getInstance()
imgShowPassword.setImageResource(R.drawable.ic_hide_pwd_24)
} else {
textPassword.transformationMethod = transformation
imgShowPassword.setImageResource(R.drawable.ic_show_password)
}
}
}
- File PasswordMaskTransformation.kt:
class PasswordMaskTransformation : PasswordTransformationMethod() {
override fun getTransformation(source: CharSequence, view: View?): CharSequence {
return PasswordCharSequence(source)
}
class PasswordCharSequence(private val source: CharSequence) : CharSequence {
override val length: Int
get() = source.length
override fun get(index: Int): Char {
return '*'
}
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
return source.subSequence(startIndex, endIndex)
}
}
}
- Project mẫu: nhấn vào đây
