7

I'm trying to make a rounded shaped surfaceview. I've searched a lot but i couldn't find a good solution. what i'm doing right now is that, I've put the SurfaceView into a FrameLayout, then another View on top of it, either with a PNG mask, or a shape xml drawable. here it is

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:layout_width="140dp"
        android:layout_height="140dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="#000"
        android:orientation="vertical"
        android:visibility="visible" >

        <FrameLayout
            android:id="@+id/videorecordview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight=".2" >

            <SurfaceView
            android:id="@+id/surfaceView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="@drawable/rounded"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

But this is not a good solution and it is also not working perfectly. I want to customize surfaceview to a rounded shape. any help would be much appreciated. Thank you :)

fadden
  • 51,356
  • 5
  • 116
  • 166
Tashen Jazbi
  • 1,068
  • 1
  • 16
  • 41
  • 1
    http://stackoverflow.com/questions/26074784/how-to-make-a-view-in-android-with-rounded-corners ... try this ..Change FrameLayout to SurfaceView – Sunil Sunny Apr 12 '16 at 05:19
  • Thank you for your participation. @sunilsunny you can make any view rounded by using this but not surfaceview. I've already tried that :) – Tashen Jazbi Apr 12 '16 at 05:35
  • @TashenJazbi: yes right, then how did you implement this ? – user2234 Nov 12 '17 at 02:02
  • @Sneha it can be done by putting circularview on top of surfaceview and then placing another view on it. its not perfect but can work to some extent :p – Tashen Jazbi Nov 12 '17 at 02:41
  • Might be the REAL answer: https://stackoverflow.com/a/31064523/1819810 And there is a full example. – Weekend Aug 08 '18 at 08:36

4 Answers4

28

A little hack. Put your surface view inside card view.

<android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/margin_normal" 
        app:cardCornerRadius="10dp"     
        app:cardPreventCornerOverlap="false">

        <SurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/margin_normal" />

    </android.support.v7.widget.CardView>

Don't forget to add this to your gradle file to use CardView

compile 'com.android.support:cardview-v7:25.0.1'

Also this two line inside card view

app:cardCornerRadius="10dp"     
app:cardPreventCornerOverlap="false"

Cheers happy coding

ralphgabb
  • 10,298
  • 3
  • 47
  • 56
  • 21
    Nice, however doesn't work when the SurfaceView is on top of another SurfaceView – aberaud Sep 03 '18 at 01:51
  • 1
    This is working indeed. Practically it is same as overriding `dispatchDraw` and clipping canvas. But I have to agree with @ralphgabb, both tricks (dispatchDraw and cardView) are not working for SurfaceView is on top of another SurfaceView. – vigilancer Jul 11 '19 at 09:41
  • 2
    It is not actually :) because in my case I need to draw SurfaceView above another SurfaceView. In all other cases your solution should work just fine. – vigilancer Jul 14 '19 at 08:13
  • 1
    you can also have a layout, like a `FrameLayout`, with a background using round corners. Then add your SurfaceView as a child of the frame layout and set `setClipToOutline` to true on the FrameLayout. It won't work on top of another SurfaceView though – Carlisg Sep 26 '19 at 07:45
  • If you're using a `Camerax PreviewView`, set the `implementationMode` of PreviewView to `compatible` which forces it to use a `TextureView` instead of a `SurfaceView` and you'll get the rounded corners. – Vikram Gupta Dec 17 '20 at 01:11
  • are there still Kitkat users? I think I only tested it on Lollipop (21) and above. – ralphgabb Jan 10 '21 at 08:05
  • it works fine with `TextureView`, just create `val surface = Surface(binding.textureView.surfaceTexture)` and pass this surface to `camera2` API, but in this case need to implement logic with orientation on your own – user924 May 17 '22 at 14:09
10

You can't change the shape of the SurfaceView's Surface.

A SurfaceView has two parts, the Surface and the View. The View part works like any other View. By default, it just acts as a transparent "hole", creating a window in the layout. All Views are rendered by the app onto a single layer.

The Surface part is a separate layer that sits behind the View layer (unless you explicitly change the Surface's Z order), so you only see it where it "shows through" transparent areas of the View layer. You can draw on the View layer to mask portions of the Surface, but you can't change the shape of the Surface layer itself. Layers are rectangular.

In many situations a TextureView can be used in place of a SurfaceView. TextureView offers greater flexibility because it's rendered by the app onto the View layer, but can be less efficient than SurfaceView.

More information can be found in the Android graphics architecture doc.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • My use case is to display a camera preview using `CameraX` `PreviewView` on top of another surface view. The `PreviewView` uses either a `TextureView` or a `SurfaceView` which it decides during runtime. When set to explicitly use a `TextureView` (by setting `implementationMode` property to `compatible`), I am able to get rounded corners. I placed my PreviewView inside a CardView like @ralphgabb suggested. – Vikram Gupta Dec 17 '20 at 01:09
2

To achieve what you ask, it is very easy to do it. You only need to use the next XML:

<androidx.cardview.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:cardCornerRadius="12dp">
        <SurfaceView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />
    </androidx.cardview.widget.CardView>

And to use this CardView, add this dependency on your build.gradle app:

implementation 'androidx.cardview:cardview:1.0.0'

Nessie
  • 102
  • 4
-2

try this

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
    <gradient
        android:startColor="#FFFF0000"
        android:endColor="#80FF00FF"
        android:angle="270"/>
</shape>

<SurfaceView
    android:background="@drawable/circle"
    android:id="@+id/surfaceView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />
Manaus
  • 407
  • 5
  • 9