Android: how to clip only top rounded corners

Jan*_*ers 10 android clip

I'm creating a ScrollView with a FrameLayout inside. I want to design it so that only the top corners are rounded on the ScrollView. I've created a drawable shape as follows

<shape>
    <solid android:color="@color/white"/>
    <corners
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        android:topLeftRadius="16dp"
        android:topRightRadius="16dp"/>
    <padding android:padding="0dp"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

I've then set the following on the ScrollView

 scrollView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
 scrollView.setClipToOutline(true);
Run Code Online (Sandbox Code Playgroud)

When i try scrolling, the elements in my FrameLayout end up protruding through the outline of my scrollview

Excuse the drawing, but what i'm looking to achieve

However if i instead create a shape like so

<shape>
    <solid android:color="@color/white"/>
    <corners
        android:radius="16dp"/>
    <padding android:padding="0dp"/>
</shape> 
Run Code Online (Sandbox Code Playgroud)

它剪辑得很好。

那么如果我只想要顶部被拐弯,我将如何剪辑它。

Jan*_*ers 17

我设法通过创建自定义 ViewOutlineProvider 并使用它而不是背景值来实现此目的

ViewOutlineProvider mViewOutlineProvider = new ViewOutlineProvider() {
    @Override
    public void getOutline(final View view, final Outline outline) {
        float cornerRadiusDP = 16f;
        float cornerRadius = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, cornerRadiusDP, getResources().getDisplayMetrics());
            outline.setRoundRect(0, 0, view.getWidth(), (int)(view.getHeight() + cornerRadius), cornerRadius);
        }
};
scrollView.setOutlineProvider(mViewOutlineProvider);
scrollView.setClipToOutline(true);
Run Code Online (Sandbox Code Playgroud)

  • 只针对一个角怎么办 (2认同)

Dra*_*nov 15

这是@Jankers 答案的 Kotlin 变体,也是@Tony 问题的答案。解释如何仅放置一个圆角或两个相邻的圆角。

  fun setCorners() {
        
        val outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {

                val left = 0
                val top = 0;
                val right = view.width
                val bottom = view.height
                val cornerRadiusDP = 16f
                val cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, cornerRadiusDP, resources.displayMetrics).toInt()

                // all corners
                outline.setRoundRect(left, top, right, bottom, cornerRadius.toFloat())

                /* top corners
                outline.setRoundRect(left, top, right, bottom+cornerRadius, cornerRadius.toFloat())*/

                /* bottom corners
                outline.setRoundRect(left, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

                /* left corners
                outline.setRoundRect(left, top, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* right corners
                outline.setRoundRect(left - cornerRadius, top, right, bottom, cornerRadius.toFloat())*/

                /* top left corner
                outline.setRoundRect(left , top, right+ cornerRadius, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* top right corner
                outline.setRoundRect(left - cornerRadius , top, right, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* bottom left corner
                outline.setRoundRect(left, top - cornerRadius, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* bottom right corner
                outline.setRoundRect(left - cornerRadius, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

            }
        }

        myView.outlineProvider = outlineProvider
        myView.clipToOutline = true

    }
Run Code Online (Sandbox Code Playgroud)