Feat: Implement floating advanced sliders inside camera view finder with scale animation (9_FEAT_UI.md)

This commit is contained in:
2026-07-05 18:10:42 +07:00
parent 2308fe6fa9
commit 1a74887fe0
3 changed files with 360 additions and 124 deletions
@@ -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