[英]Android MaterialCardView's drop shadow/elevation disappears when rotating it 180 degrees
總結問題:
我正在開發一個繪畫應用程序,在這個應用程序中,用戶可以選擇旋轉 canvas,這個功能在某些情況下很有用。
我遇到的問題是,當我將承載畫布/位圖的CardView
旋轉 180 度時,陰影會丟失。 當我將CardView
旋轉 90 度時,我沒有遇到這個問題,只有 180 度。
描述你嘗試過的東西
我嘗試了很多東西,例如給 CardView 更多空間以便顯示投影,或者在將代碼旋轉 180 度后手動應用代碼中的投影,但它沒有奏效。
顯示一些代碼
這是負責旋轉CardView
的代碼(非常簡單):
fun CanvasActivity.rotate(rotationValue: RotationValue, animate: Boolean = false) {
rotate(rotationValue.degrees, rotationValue.clockwise, animate)
}
fun CanvasActivity.rotate(degrees: Int, clockwise: Boolean = true, animate: Boolean = false) {
val rotationAmount = if (clockwise) {
(binding.activityCanvasCardView.rotation + degrees)
} else {
(binding.activityCanvasCardView.rotation - degrees)
}
if (animate) {
binding.activityCanvasCardView
.animate()
.rotation(rotationAmount)
} else {
binding.activityCanvasCardView.rotation = rotationAmount
}
}
activity_canvas
:
<?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"
android:background="@color/fragment_background_color_daynight"
tools:context=".activities.canvas.CanvasActivity">
<!-- This view is here to ensure that when the user zooms in, there is no overlap -->
<View
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_topView"
android:layout_width="0dp"
android:layout_height="90dp"
android:background="@color/fragment_background_color_daynight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- The ColorSwitcherView is a view I created which helps
simplify the code for controlling the user's primary/secondary color -->
<com.therealbluepandabear.pixapencil.customviews.colorswitcherview.ColorSwitcherView
android:id="@+id/activityCanvas_colorSwitcherView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:elevation="20dp"
android:outlineProvider="none"
app:isPrimarySelected="true"
app:layout_constraintEnd_toEndOf="@+id/activityCanvas_topView"
app:layout_constraintTop_toTopOf="@+id/activityCanvas_colorPickerRecyclerView" />
<!-- The user's color palette data will be displayed in this RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_colorPickerRecyclerView"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="@+id/activityCanvas_topView"
app:layout_constraintEnd_toStartOf="@+id/activityCanvas_colorSwitcherView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/activityCanvas_primaryFragmentHost"
tools:listitem="@layout/color_picker_layout" />
<!-- This FrameLayout is crucial when it comes to the calculation of the TransparentBackgroundView and PixelGridView -->
<FrameLayout
android:id="@+id/activityCanvas_distanceContainer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/activityCanvas_tabLayout"
app:layout_constraintEnd_toEndOf="@+id/activityCanvas_primaryFragmentHost"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/activityCanvas_topView" />
<!-- This gives both views (the PixelGridView and TransparentBackgroundView) a nice drop shadow -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/activityCanvas_cardView"
style="@style/activityCanvas_canvasFragmentHostCardViewParent_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/activityCanvas_tabLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/activityCanvas_topView">
<!-- At runtime, the width and height of the TransparentBackgroundView and PixelGridView will be calculated -->
<com.therealbluepandabear.pixapencil.customviews.transparentbackgroundview.TransparentBackgroundView
android:id="@+id/activityCanvas_transparentBackgroundView"
android:layout_width="0dp"
android:layout_height="0dp" />
<com.therealbluepandabear.pixapencil.customviews.pixelgridview.PixelGridView
android:id="@+id/activityCanvas_pixelGridView"
android:layout_width="0dp"
android:layout_height="0dp" />
</com.google.android.material.card.MaterialCardView>
<!-- The primary tab layout -->
<com.google.android.material.tabs.TabLayout
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_tabLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:tabStripEnabled="false"
app:layout_constraintBottom_toTopOf="@+id/activityCanvas_viewPager2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activityCanvas_tab_tools_str" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activityCanvas_tab_filters_str" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activityCanvas_tab_color_palettes_str" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activityCanvas_tab_brushes_str" />
</com.google.android.material.tabs.TabLayout>
<!-- This view allows move functionality -->
<View
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_moveView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@+id/activityCanvas_distanceContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/activityCanvas_topView" />
<!-- The tools, palettes, brushes, and filters fragment will be displayed inside this ViewPager -->
<androidx.viewpager2.widget.ViewPager2
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_viewPager2"
android:layout_width="0dp"
android:layout_height="110dp"
app:layout_constraintBottom_toBottomOf="@+id/activityCanvas_primaryFragmentHost"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- This CoordinatorLayout is responsible for ensuring that the app's snackbars can be swiped -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- All of the full page fragments will be displayed in this fragment host -->
<FrameLayout
android:elevation="20dp"
android:outlineProvider="none"
android:id="@+id/activityCanvas_primaryFragmentHost"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
0度:
90度:
180度:
如您所見,旋轉 180 度時(原點為 0 度時)沒有陰影。
任何幫助將不勝感激為什么我會遇到這個問題,這不是主要問題,但它使我的應用程序的 UI 不一致。
注意:由於某種原因,我只在手機上遇到問題,而不是平板設備。
您在大多數項目上設置android:outlineProvider="none"
...而正在使用的投影可能具有錯誤的偏移坐標 - 您需要減去而不是添加偏移量。 提供的代碼太少,無法更准確地回答這個問題 - 但由於所述原因,陰影很可能只是隱藏在畫布下方。 我建議提供您自己的ViewOutlineProvider
實現,然后通過 this 而不是none
。
您需要在android:layout_margin="16dp"
的每一側設置總計(左、右、下和上)16dp 並設置app:cardElevation="4dp"
,它會起作用。
實際上,這是一件很奇怪的事情。 我試圖旋轉一個簡單的陰影視圖,它似乎在沒有任何邏輯原因的情況下在旋轉角度為 180/-180 時切斷了陰影。 我也嘗試與大綱提供者一起玩,但沒有。 所以這與 CardView 無關,而是來自在 View class 中繪制陰影的實現。
我搜索了一下,它已經直接報告給谷歌並修復了,但可能一些兼容庫仍然存在這個問題,這就是你面臨它的原因。
https://issuetracker.google.com/issues/173730323
https://issuetracker.google.com/issues/137454913
我可以建議您創建一個拐杖(是的,我知道,這不是解決方案)並留下評論。 如果你的旋轉大約是 -180/180,你可以用“-179.9/179.9”“標准化”它。 就用戶體驗而言,就漂亮的代碼而言,它是不可見的——嗯,但我在這里看不到任何其他方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.