fix: chỉnh sửa button cho phần chỉnh presets
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
|
||||
# 🎨 KẾ HOẠCH BỔ SUNG THUỘC TÍNH EDITOR & HIỂN THỊ TÊN ĐỘNG TRÊN TOP BAR
|
||||
|
||||
Mục tiêu: Đưa toàn bộ 14 thông số cấu hình vào `rvAttributeIcons` dạng danh sách cuộn ngang không giới hạn. Đồng bộ hóa việc chọn icon để hiển thị tên tiếng Việt tương ứng lên vùng văn bản phía trên ảnh và gán chính xác sự kiện vuốt trên ảnh cho thuộc tính đó.
|
||||
|
||||
---
|
||||
|
||||
## 📐 1. Cấu Trúc Lại XML Layout Để Thêm Dải Hiển Thị Tên (`activity_main.xml`)
|
||||
|
||||
Bám sát ảnh `image.png`, chúng ta cần thêm một `TextView` nằm ở dải đen phía trên bức ảnh để làm nhiệm vụ hiển thị tên nút đang chọn.
|
||||
|
||||
```xml
|
||||
<!-- DẢI ĐEN PHÍA TRÊN ẢNH CAMERA (Như mô tả trong image.png) -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/layoutEditorTitleBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:background="#000000"
|
||||
app:layout_bottom_toTopOf="@id/cameraContainer"
|
||||
app:layout_constraintTop_toBottomOf="@id/topBar">
|
||||
|
||||
<!-- Văn bản hiển thị động tên nút đang được chọn -->
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentAttributeName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="Brightness (Độ sáng)" <!-- Tên động hiển thị ở đây -->
|
||||
android:textColor="#FF9800" <!-- Màu cam nổi bật hoặc trắng tùy chọn -->
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
</RelativeLayout>
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 2. Khai Báo Toàn Bộ Bản Đồ Thuộc Tính & Icons (Kotlin Model)
|
||||
|
||||
Để quản lý 14 nút thuộc tính một cách khoa học, chúng ta tạo một danh sách Model bao gồm: ID thuộc tính, Tên hiển thị (Tiếng Việt), và File định dạng Icon tương ứng trong `res/drawable`.
|
||||
|
||||
### 🔹 2.1. Định nghĩa Data Class cho nút thuộc tính
|
||||
|
||||
```kotlin
|
||||
data class AttributeNode(
|
||||
val type: EditAttribute,
|
||||
val displayName: String,
|
||||
val iconResId: Int
|
||||
)
|
||||
|
||||
enum class EditAttribute {
|
||||
BRIGHTNESS, CONTRAST, SATURATION, VIBRANCE, TEMPERATURE, TINT, // Nhóm 1: Cơ bản
|
||||
CLARITY, DEHAZE, VIGNETTE_AMOUNT, // Nhóm 2: Nâng cao
|
||||
FADED_BLACK_LEVEL, SHADOWS_TINT_R, SHADOWS_TINT_G, SHADOWS_TINT_B, // Nhóm 3: Tone Curve
|
||||
GRAIN_AMOUNT, GRAIN_SIZE // Nhóm 4: Nhiễu hạt
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 🔹 2.2. Khởi tạo mảng dữ liệu 14 nút đầy đủ
|
||||
|
||||
```kotlin
|
||||
val editorAttributes = listOf(
|
||||
AttributeNode(EditAttribute.BRIGHTNESS, "Brightness (Độ sáng)", R.drawable.ic_attr_brightness),
|
||||
AttributeNode(EditAttribute.CONTRAST, "Contrast (Tương phản)", R.drawable.ic_attr_contrast),
|
||||
AttributeNode(EditAttribute.SATURATION, "Saturation (Bão hòa màu)", R.drawable.ic_attr_saturation),
|
||||
AttributeNode(EditAttribute.VIBRANCE, "Vibrance (Bão hòa thông minh)", R.drawable.ic_attr_vibrance),
|
||||
AttributeNode(EditAttribute.TEMPERATURE, "Temperature (Nhiệt màu)", R.drawable.ic_attr_temperature),
|
||||
AttributeNode(EditAttribute.TINT, "Tint (Sắc độ hồng/xanh)", R.drawable.ic_attr_tint),
|
||||
AttributeNode(EditAttribute.CLARITY, "Clarity (Độ rõ nét)", R.drawable.ic_attr_clarity),
|
||||
AttributeNode(EditAttribute.DEHAZE, "Dehaze (Độ trong suốt / Sương mù)", R.drawable.ic_attr_dehaze),
|
||||
AttributeNode(EditAttribute.VIGNETTE_AMOUNT, "Vignette Amount (Bo tối góc)", R.drawable.ic_attr_vignette),
|
||||
AttributeNode(EditAttribute.FADED_BLACK_LEVEL, "Faded Black Level (Độ mờ vùng đen)", R.drawable.ic_attr_fade),
|
||||
AttributeNode(EditAttribute.SHADOWS_TINT_R, "Shadows Tint R (Sắc Đỏ vùng tối)", R.drawable.ic_attr_tint_r),
|
||||
AttributeNode(EditAttribute.SHADOWS_TINT_G, "Shadows Tint G (Sắc Lục vùng tối)", R.drawable.ic_attr_tint_g),
|
||||
AttributeNode(EditAttribute.SHADOWS_TINT_B, "Shadows Tint B (Sắc Lam vùng tối)", R.drawable.ic_attr_tint_b),
|
||||
AttributeNode(EditAttribute.GRAIN_AMOUNT, "Grain Amount (Mật độ hạt)", R.drawable.ic_attr_grain_amount),
|
||||
AttributeNode(EditAttribute.GRAIN_SIZE, "Grain Size (Kích thước hạt)", R.drawable.ic_attr_grain_size)
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💻 3. Xử Lý Logic Tương Tác & Đồng Bộ Trạng Thái Động
|
||||
|
||||
Khi gán danh sách này vào `rvAttributeIcons` dưới dạng LayoutManager cuộn ngang (`LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)`), người dùng có thể thoải mái vuốt lướt sang phải để tìm các nút bị ẩn như mũi tên chỉ dẫn trong ảnh `image.png`.
|
||||
|
||||
### 🔹 3.1. Sự kiện Click đổi màu và đồng bộ Tên lên Top Bar
|
||||
|
||||
Trong sự kiện bấm chọn một Icon thuộc tính bên trong Adapter của RecyclerView:
|
||||
|
||||
```kotlin
|
||||
fun onAttributeSelected(selectedNode: AttributeNode) {
|
||||
// 1. Lưu lại thuộc tính đang chỉnh sửa hiện tại
|
||||
currentAttribute = selectedNode.type
|
||||
|
||||
// 2. Cập nhật văn bản lên dải đen phía trên ảnh đúng theo thiết kế image_44ee6b.jpg
|
||||
binding.tvCurrentAttributeName.text = selectedNode.displayName
|
||||
|
||||
// 3. Đọc giá trị hiện tại của thuộc tính này trong file JSON tạm thời để nạp lên thước đo
|
||||
val currentValue = getCurrentAttributeValue(selectedNode.type)
|
||||
binding.tvRulerValue.text = String.format("%.0f", currentValue * 100f)
|
||||
|
||||
// 4. Ra lệnh cho Adapter vẽ lại (Notify) để đổi màu Icon được chọn thành MÀU CAM
|
||||
attributeAdapter.updateSelection(selectedNode.type)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 🔹 3.2. Cập nhật hàm điều phối Vuốt trên ảnh (Swipe Logic Matrix)
|
||||
|
||||
Hàm tiếp nhận giá trị `deltaX` khi người dùng vuốt trên màn hình ảnh giờ đây sẽ phân nhánh chính xác sang cả 14 thông số, không còn tình trạng gán nhầm hàm:
|
||||
|
||||
```kotlin
|
||||
private fun updateAttributeBySwipe(newValue: Float) {
|
||||
// newValue có dải giá trị từ -1.0f đến 1.0f sau khi đã chia cho 100
|
||||
when (currentAttribute) {
|
||||
EditAttribute.BRIGHTNESS -> editingPreset?.basic?.brightness = newValue
|
||||
EditAttribute.CONTRAST -> editingPreset?.basic?.contrast = newValue
|
||||
EditAttribute.SATURATION -> editingPreset?.basic?.saturation = newValue
|
||||
EditAttribute.VIBRANCE -> editingPreset?.basic?.vibrance = newValue
|
||||
EditAttribute.TEMPERATURE -> editingPreset?.basic?.temperature = newValue
|
||||
EditAttribute.TINT -> editingPreset?.basic?.tint = newValue
|
||||
|
||||
EditAttribute.CLARITY -> editingPreset?.advanced?.clarity = newValue
|
||||
EditAttribute.DEHAZE -> editingPreset?.advanced?.dehaze = newValue
|
||||
EditAttribute.VIGNETTE_AMOUNT -> editingPreset?.advanced?.vignetteAmount = newValue.coerceIn(0f, 1f)
|
||||
|
||||
EditAttribute.FADED_BLACK_LEVEL -> editingPreset?.toneCurve?.fadedBlackLevel = newValue.coerceIn(0f, 1f)
|
||||
EditAttribute.SHADOWS_TINT_R -> editingPreset?.toneCurve?.shadowsTintR = newValue.coerceIn(0f, 1f)
|
||||
EditAttribute.SHADOWS_TINT_G -> editingPreset?.toneCurve?.shadowsTintG = newValue.coerceIn(0f, 1f)
|
||||
EditAttribute.SHADOWS_TINT_B -> editingPreset?.toneCurve?.shadowsTintB = newValue.coerceIn(0f, 1f)
|
||||
|
||||
EditAttribute.GRAIN_AMOUNT -> editingPreset?.grain?.grainAmount = newValue.coerceIn(0f, 1f)
|
||||
EditAttribute.GRAIN_SIZE -> editingPreset?.grain?.grainSize = newValue.coerceIn(0f, 1f)
|
||||
}
|
||||
|
||||
// Luôn luôn gọi render cập nhật đồ họa thời gian thực lên Camera ngay lập tức
|
||||
applyLiveFilterToCamera(editingPreset)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 4. Các Đầu Việc Cần Triển Khai (Checklist)
|
||||
|
||||
* [ ] **Chuẩn bị 14 cặp Icons tương ứng:** Tạo hoặc import các asset dạng vector đơn sắc trắng vào thư mục dự án trên Linux.
|
||||
* [ ] **Cấu hình `clipToPadding="false"` cho RecyclerView:** Thiết lập thuộc tính này cho thanh icon để khi cuộn, các icon ở hai đầu rìa có khoảng không trượt mượt mà, không bị cắt cụt đột ngột.
|
||||
* [ ] **Kiểm thử liên kết:** Đảm bảo khi mở màn hình Editor lên, mặc định app sẽ tự động giả lập click vào nút đầu tiên (Brightness), icon sáng cam và dải chữ phía trên hiển thị đúng chữ `"Brightness (Độ sáng)"` như ảnh `image.png`.
|
||||
Reference in New Issue
Block a user