Android 剪辑到背景
Posted
技术标签:
【中文标题】Android 剪辑到背景【英文标题】:Android clip to background 【发布时间】:2019-03-08 09:27:20 【问题描述】:我有以下可绘制的squared_card_background.xml
,我希望将其用作不同视图的背景,并让视图子项以及视图本身在之后被剪辑。
squared_card_background_left.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:
android:
android:viewportHeight="1"
android:viewportWidth="1">
<path
android:name="left"
android:fillColor="@color/colorSurface"
android:pathData="M0,1 L1,0 L1,1z" />
<clip-path android:name="leftClip"
android:pathData="M0,1 L1,0 L1,1z"/>
</vector>
squared_card_background_right.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:
android:
android:viewportHeight="1"
android:viewportWidth="1" >
<path
android:name="v"
android:fillColor="@color/colorSurface"
android:pathData="M1,1 L0,0 L0,1z" />
</vector>
squared_card_background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:gravity="fill|top|clip_horizontal|clip_vertical"
android:start="16dp"
android:end="16dp"
android:>
<shape android:shape="rectangle"
android:useLevel="false">
<solid android:color="@color/colorSurface"/>
</shape>
</item>
<item android:drawable="@drawable/squared_card_background_left"
android:gravity="start|top|clip_horizontal|clip_vertical"
android:
android:>
</item>
<item android:drawable="@drawable/squared_card_background_right"
android:gravity="end|top|clip_horizontal|clip_vertical"
android:
android:>
</item>
<item android:top="16dp">
<color android:color="@color/colorSurface"/>
<scale android:scaleGravity="fill"/>
</item>
</layer-list>
我尝试将视图设置为剪切子项和轮廓背景,但它似乎无法识别正确的剪切路径,有什么想法吗?
我当前尝试设置视图背景的布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:background="@color/colorBackground"
android:orientation="vertical">
<com.mobile.indico.indicomobile.views.Toolbar
android:id="@+id/sync_toolbar"
android:layout_
android:layout_
app:toolbarTitle="@string/title_sync"
app:showNavigationIcon="false"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/sync_start"
android:layout_
android:layout_
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="@drawable/preview_button_background"
android:tint="@color/colorOnPrimary"
android:src="@drawable/ic_refresh_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</com.mobile.indico.indicomobile.views.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="@+id/sync_recycler"
android:layout_
android:layout_
app:layout_constraintTop_toBottomOf="@id/sync_toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@drawable/squared_card_background"
android:clipChildren="true"/>
</android.support.constraint.ConstraintLayout>
最后,我尝试创建一个父 FrameLayout 将单个子剪辑剪辑到背景,但结果相同,我不知道如何从可绘制对象创建剪辑路径并插入到 onDraw
方法中。
【问题讨论】:
【参考方案1】:最终使用了这个......感谢我猜的反对
override fun onDraw(canvas: Canvas?) = super.onDraw(canvas?.also
it.clipPath(Path().apply
moveTo(0f, height.toFloat())
lineTo(0f, _cornerRadius)
lineTo(_cornerRadius, 0f)
lineTo(width - _cornerRadius, 0f)
lineTo(width.toFloat(), _cornerRadius)
lineTo(width.toFloat(), height.toFloat())
lineTo(0f, height.toFloat())
close()
)
)
【讨论】:
请注意,每次调用 onDraw 时都会创建一个新的 Path 对象,这对性能非常不利,因为会创建大量对象,而这些对象又需要被垃圾回收。以上是关于Android 剪辑到背景的主要内容,如果未能解决你的问题,请参考以下文章