Feat: Implement floating advanced sliders inside camera view finder with scale animation (9_FEAT_UI.md)
This commit is contained in:
+214
@@ -0,0 +1,214 @@
|
||||
# 🎨 KẾ HOẠCH ĐIỀU CHỈNH: BẢNG SLIDERS FLOATING & HIỂN THỊ TRANSPARENT FRAME
|
||||
|
||||
Mục tiêu: Đưa bảng chỉnh sửa thành một khối mờ floating nằm gọn bên trong khung hình camera, cho phép cuộn dọc nội dung sliders. Đồng thời, cấu trúc lại hệ thống hiển thị để phần trong suốt (Transparent) của file Frame PNG lọt lòng đúng luồng camera.
|
||||
|
||||
---
|
||||
|
||||
## 📐 1. Cấu Trúc Lại Phân Tầng Giao Diện (`activity_main.xml`)
|
||||
|
||||
Để bảng điều khiển nằm lọt vào bên trong phần hình ảnh, chúng ta phải đưa nó vào làm con trực tiếp của `FrameLayout` quản lý camera (`cameraContainer`). Thứ tự khai báo trong XML sẽ quyết định tầng hiển thị (Z-index):
|
||||
|
||||
```
|
||||
[FrameLayout: cameraContainer] (Tỉ lệ 3:4)
|
||||
├── Lớp 1 (Đáy): PreviewView (Luồng camera gốc từ phần cứng)
|
||||
├── Lớp 2 (Giữa): ImageView (Khung ảnh PNG trong suốt)
|
||||
└── Lớp 3 (Trên cùng): CardView / ScrollView (Bảng Sliders mờ floating)
|
||||
|
||||
```
|
||||
|
||||
### 💻 Đoạn mã XML chỉnh sửa chi tiết:
|
||||
|
||||
```xml
|
||||
<!-- KHU VỰC HÌNH ẢNH CAMERA CHÍNH (Tỉ lệ 3:4) -->
|
||||
<FrameLayout
|
||||
android:id="@+id/cameraContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintDimensionRatio="3:4"
|
||||
app:layout_constraintTop_toBottomOf="@id/topBar">
|
||||
|
||||
<!-- LỚP 1: Kính ngắm Camera -->
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/viewFinder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<!-- LỚP 2: Khung Frame PNG (Phần ruột trong suốt sẽ tự động lộ Camera ở Lớp 1 ra) -->
|
||||
<ImageView
|
||||
android:id="@+id/imgFrameOverlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<!-- LỚP 3: BẢNG SLIDERS FLOATING (Nằm lọt vào giữa hình ảnh như image_2be399.jpg) -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardAdvancedSliders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="24dp" <!-- Tạo khoảng trống lọt lòng xung quanh giống ảnh mẫu -->
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="8dp"
|
||||
android:visibility="gone" <!-- Mặc định ẩn -->
|
||||
app:strokeWidth="0dp"
|
||||
android:backgroundTint="#A6000000"> <!-- Màu nền đen mờ tỉ lệ nén Alpha mịn -->
|
||||
|
||||
<!-- ScrollView cho phép cuộn lên xuống tự do để chỉnh tất cả các thông số -->
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Tiêu đề & Nút X (Đóng) -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:id="@+id/tvEditPresetName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Chỉnh sửa: Instax Nắng Chiều"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:textSize="15sp" />
|
||||
<ImageButton
|
||||
android:id="@+id/btnCancelEdit"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@null"
|
||||
android:src="@drawable/ic_close_white"
|
||||
app:tint="#FFFFFF" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- ================= DANH SÁCH CÁC CỤM SLIDERS ĐỂ CUỘN ================= -->
|
||||
<!-- 1. VIBRANCE -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Vibrance (Bão hòa thông minh): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800" />
|
||||
|
||||
<!-- 2. CLARITY -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clarity (Độ rõ nét vùng trung tính): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800" />
|
||||
|
||||
<!-- 3. DEHAZE -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dehaze (Độ trong suốt / Sương mù): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800" />
|
||||
|
||||
<!-- Bổ sung thêm các Slider khác (Brightness, Saturation, Grain) vào đây để cuộn... -->
|
||||
|
||||
<!-- NÚT LƯU THÀNH PRESET MỚI -->
|
||||
<Button
|
||||
android:id="@+id/btnSaveCustomPreset"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="LƯU THÀNH PRESET MỚI"
|
||||
android:textColor="#FFFFFF"
|
||||
android:backgroundTint="#FF9800"
|
||||
android:textStyle="bold"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
app:cornerRadius="4dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</FrameLayout>
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💻 2. Kịch Bản Xử Lý Kỹ Thuật (Kotlin)
|
||||
|
||||
### 🔹 2.1. Hiện thực hóa việc hiện thị Frame suốt (Transparent Layer)
|
||||
|
||||
Để luồng camera hiện lên ở phần ruột trong suốt của khung hình:
|
||||
|
||||
1. Các file asset khung ảnh (ví dụ: `instaxframe.png`) thiết kế trên phần mềm đồ họa phải được đục lỗ rỗng (Alpha channel = 0) ở khu vực hiển thị ảnh chụp.
|
||||
2. Trong Android, khi người dùng chọn mẫu từ Timeline, ta nạp trực tiếp bằng luồng luân chuyển nhẹ:
|
||||
```kotlin
|
||||
val bitmap = BitmapFactory.decodeStream(assets.open("frames/instaxframe.png"))
|
||||
binding.imgFrameOverlay.setImageBitmap(bitmap)
|
||||
|
||||
```
|
||||
|
||||
|
||||
Do cơ chế xếp chồng tầng của `FrameLayout`, luồng CameraX hoạt động ở `viewFinder` (Lớp 1) sẽ tự động xuyên thấu và hiển thị mượt mà qua các vùng trống của `imgFrameOverlay` (Lớp 2).
|
||||
|
||||
### 🔹 2.2. Logic cập nhật Text hiển thị chỉ số thời gian thực (Real-time Value Indicator)
|
||||
|
||||
Bám sát thiết kế hiển thị số ở nhãn text (ví dụ: `Vibrance (...): -0.23`), ta cập nhật chuỗi text liên tục khi con trỏ di chuyển:
|
||||
|
||||
```kotlin
|
||||
binding.sliderVibrance.addOnChangeListener { slider, value, fromUser ->
|
||||
// 1. Cập nhật chữ hiển thị giá trị số thực tế
|
||||
binding.tvLabelVibrance.text = String.format("Vibrance (Bão hòa thông minh): %.2f", value)
|
||||
|
||||
// 2. Cập nhật Object tạm thời
|
||||
editingPreset?.basic?.vibrance = value
|
||||
|
||||
// 3. Đẩy sang GPU render lập tức lên ViewFinder
|
||||
applyLiveFilterToCamera(editingPreset)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 3. Các Đầu Việc Cần Triển Khai (Checklist)
|
||||
|
||||
* [ ] **Kiểm tra độ trong suốt Asset:** Đảm bảo tất cả các file khung ảnh trong thư mục `assets/frames/` là định dạng **PNG-24** hỗ trợ Transparent hoàn toàn.
|
||||
* [ ] **Cập nhật hiệu ứng hiển thị Card:** Khi mở bảng sliders, áp dụng hiệu ứng phóng to nhẹ từ tâm (`ScaleAnimation`) thay vì trượt từ dưới lên để phù hợp hơn với kiểu giao diện hộp Floating Card cố định.
|
||||
* [ ] **Tối ưu hóa ScrollView:** Cài đặt thuộc tính ngăn chặn xung đột vuốt (`Touch Interception`) giữa thanh cuộn của `ScrollView` và các con trỏ trượt của `Slider Mechanism` của Material Component, giúp việc kéo thông số không bị trượt nhầm làm cuộn cả bảng.
|
||||
@@ -311,21 +311,21 @@ class MainActivity : AppCompatActivity() {
|
||||
binding.sliderVibrance.addOnChangeListener { _, value, _ ->
|
||||
editingPreset?.let { preset ->
|
||||
preset.basic.vibrance = value
|
||||
binding.lblVibrance.text = "Vibrance (Bão hòa thông minh): ${String.format("%.2f", value)}"
|
||||
binding.tvLabelVibrance.text = "Vibrance (Bão hòa thông minh): ${String.format("%.2f", value)}"
|
||||
applyPresetFilter(preset)
|
||||
}
|
||||
}
|
||||
binding.sliderClarity.addOnChangeListener { _, value, _ ->
|
||||
editingPreset?.let { preset ->
|
||||
preset.advanced.clarity = value
|
||||
binding.lblClarity.text = "Clarity (Độ rõ nét vùng trung tính): ${String.format("%.2f", value)}"
|
||||
binding.tvLabelClarity.text = "Clarity (Độ rõ nét vùng trung tính): ${String.format("%.2f", value)}"
|
||||
applyPresetFilter(preset)
|
||||
}
|
||||
}
|
||||
binding.sliderDehaze.addOnChangeListener { _, value, _ ->
|
||||
editingPreset?.let { preset ->
|
||||
preset.advanced.dehaze = value
|
||||
binding.lblDehaze.text = "Dehaze (Độ trong suốt / Sương mù): ${String.format("%.2f", value)}"
|
||||
binding.tvLabelDehaze.text = "Dehaze (Độ trong suốt / Sương mù): ${String.format("%.2f", value)}"
|
||||
applyPresetFilter(preset)
|
||||
}
|
||||
}
|
||||
@@ -438,30 +438,34 @@ class MainActivity : AppCompatActivity() {
|
||||
binding.sliderDehaze.value = editingPreset!!.advanced.dehaze
|
||||
|
||||
// Update text labels
|
||||
binding.lblVibrance.text = "Vibrance (Bão hòa thông minh): ${String.format("%.2f", editingPreset!!.basic.vibrance)}"
|
||||
binding.lblClarity.text = "Clarity (Độ rõ nét vùng trung tính): ${String.format("%.2f", editingPreset!!.advanced.clarity)}"
|
||||
binding.lblDehaze.text = "Dehaze (Độ trong suốt / Sương mù): ${String.format("%.2f", editingPreset!!.advanced.dehaze)}"
|
||||
binding.tvLabelVibrance.text = "Vibrance (Bão hòa thông minh): ${String.format("%.2f", editingPreset!!.basic.vibrance)}"
|
||||
binding.tvLabelClarity.text = "Clarity (Độ rõ nét vùng trung tính): ${String.format("%.2f", editingPreset!!.advanced.clarity)}"
|
||||
binding.tvLabelDehaze.text = "Dehaze (Độ trong suốt / Sương mù): ${String.format("%.2f", editingPreset!!.advanced.dehaze)}"
|
||||
|
||||
// Slide up overlay panel animation
|
||||
binding.layoutAdvancedSliders.apply {
|
||||
// Scale animation from center
|
||||
binding.cardAdvancedSliders.apply {
|
||||
visibility = android.view.View.VISIBLE
|
||||
alpha = 0f
|
||||
translationY = 200f
|
||||
scaleX = 0.8f
|
||||
scaleY = 0.8f
|
||||
animate()
|
||||
.alpha(1f)
|
||||
.translationY(0f)
|
||||
.setDuration(300)
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.setDuration(250)
|
||||
.setInterpolator(android.view.animation.OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun closeAdvancedSliders() {
|
||||
binding.layoutAdvancedSliders.animate()
|
||||
binding.cardAdvancedSliders.animate()
|
||||
.alpha(0f)
|
||||
.translationY(200f)
|
||||
.setDuration(250)
|
||||
.scaleX(0.8f)
|
||||
.scaleY(0.8f)
|
||||
.setDuration(200)
|
||||
.withEndAction {
|
||||
binding.layoutAdvancedSliders.visibility = android.view.View.GONE
|
||||
binding.cardAdvancedSliders.visibility = android.view.View.GONE
|
||||
currentSelectedPreset?.let { applyPresetFilter(it) }
|
||||
}
|
||||
.start()
|
||||
|
||||
@@ -101,117 +101,135 @@
|
||||
android:shadowRadius="10"
|
||||
android:visibility="gone"
|
||||
android:text="3" />
|
||||
|
||||
<!-- LỚP 4: BẢNG SLIDERS FLOATING (Nằm lọt vào giữa hình ảnh camera) -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardAdvancedSliders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="24dp"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="8dp"
|
||||
android:visibility="gone"
|
||||
app:strokeWidth="0dp"
|
||||
android:backgroundTint="#A6000000">
|
||||
|
||||
<!-- ScrollView cho phép cuộn lên xuống tự do để chỉnh tất cả các thông số -->
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Tiêu đề & Nút X (Đóng) -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:id="@+id/tvEditPresetName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Chỉnh sửa: Instax Nắng Chiều"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:textSize="15sp" />
|
||||
<ImageButton
|
||||
android:id="@+id/btnCancelEdit"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:src="@drawable/ic_close_white"
|
||||
app:tint="#FFFFFF"
|
||||
android:contentDescription="Cancel Edit" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- ================= DANH SÁCH CÁC CỤM SLIDERS ĐỂ CUỘN ================= -->
|
||||
<!-- 1. VIBRANCE -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Vibrance (Bão hòa thông minh): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- 2. CLARITY -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clarity (Độ rõ nét vùng trung tính): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- 3. DEHAZE -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabelDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dehaze (Độ trong suốt / Sương mù): 0.0"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- NÚT LƯU THÀNH PRESET MỚI -->
|
||||
<Button
|
||||
android:id="@+id/btnSaveCustomPreset"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="LƯU THÀNH PRESET MỚI"
|
||||
android:textColor="#FFFFFF"
|
||||
android:backgroundTint="#FF9800"
|
||||
android:textStyle="bold"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
app:cornerRadius="4dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- ================= BẢNG SLIDERS TÙY CHỈNH MÀU THỜI GIAN THỰC ================= -->
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutAdvancedSliders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="#D9000000"
|
||||
android:padding="20dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/panelSelectionContainer">
|
||||
|
||||
<!-- Thanh tiêu đề & Nút thao tác nhanh -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
<TextView
|
||||
android:id="@+id/tvEditPresetName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Chỉnh sửa: Instax Warm"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp" />
|
||||
<ImageButton
|
||||
android:id="@+id/btnCancelEdit"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:src="@drawable/ic_close_white"
|
||||
app:tint="@color/theme_white"
|
||||
android:contentDescription="Cancel Edit" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- KHU VỰC CÁC THANH KÉO (SLIDERS) -->
|
||||
<!-- 1. Thanh chỉnh VIBRANCE -->
|
||||
<TextView
|
||||
android:id="@+id/lblVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Vibrance (Bão hòa thông minh): 0.0"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="12sp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderVibrance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- 2. Thanh chỉnh CLARITY -->
|
||||
<TextView
|
||||
android:id="@+id/lblClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clarity (Độ rõ nét vùng trung tính): 0.0"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderClarity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- 3. Thanh chỉnh DEHAZE -->
|
||||
<TextView
|
||||
android:id="@+id/lblDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dehaze (Độ trong suốt / Sương mù): 0.0"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderDehaze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="-1.0"
|
||||
android:valueTo="1.0"
|
||||
android:value="0.0"
|
||||
app:thumbColor="#FF9800"
|
||||
app:trackColorActive="#FF9800"
|
||||
app:trackColorInactive="#333333" />
|
||||
|
||||
<!-- NÚT LƯU THÀNH PRESET MỚI -->
|
||||
<Button
|
||||
android:id="@+id/btnSaveCustomPreset"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="LƯU THÀNH PRESET MỚI"
|
||||
android:textColor="#FFFFFF"
|
||||
android:backgroundTint="#FF9800"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- ================= KHỐI 1: TIMELINE FRAMES & PRESETS ================= -->
|
||||
<!-- Đặt ngay phía dưới Camera và không bị ai đè lên nữa -->
|
||||
<FrameLayout
|
||||
|
||||
Reference in New Issue
Block a user