Subin Babu
Subin Babu

Reputation: 1555

How to create s curve layout in android

How can create layout or view like attached image, shape that can be used for ImageView, Slider etc.

Upvotes: 2

Views: 1038

Answers (3)

sachithkn
sachithkn

Reputation: 467

Try this custom view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View

class CustomShape(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private var color = Color.YELLOW
    private var size = 300f
    private var insideColor = Color.WHITE
    private var borderWidth = 2f
    private val mouthPath = Path()
    private val background = Color.TRANSPARENT


    private fun drawCurvedShape(canvas: Canvas) {

        val paint = Paint()
        paint.color = color
        paint.style = Paint.Style.FILL
        setBackgroundColor(background);

        // 1
        mouthPath.moveTo(0f, size)
        // 2
        mouthPath.quadTo(size * 0f, size * 0.5f, size, size * 0.5f)
        mouthPath.lineTo(canvas.width-size,size * 0.5f)
        mouthPath.quadTo(canvas.width - 0.1f, size * 0.45f, canvas.width * 1f, 0f)
        mouthPath.lineTo(canvas.width * 1f,canvas.height * 1f)
        mouthPath.lineTo(0f,canvas.height * 1f)
        mouthPath.lineTo(0f,size)

        // 4
        paint.color = insideColor
        paint.strokeWidth = borderWidth
        paint.style = Paint.Style.FILL


        // 5
        canvas.drawPath(mouthPath, paint)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if(canvas != null)
            drawCurvedShape(canvas)
    }

}

XML layout

<?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/colorPrimary"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="400dp"
        android:src="@drawable/bg"
        android:scaleType="centerCrop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.sachithkn.customshape.view.CustomShape
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="300dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/imageView" />


</androidx.constraintlayout.widget.ConstraintLayout>

S-SHapeLayout

Full app S-Shape Layout(GitHub)

Upvotes: 2

Gabriele Mariotti
Gabriele Mariotti

Reputation: 364451

You can use something like.

    <FrameLayout
        android:clipChildren="false"
        android:clipToPadding="false"
        ...>

        <ImageView/>

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/card"
            android:layout_marginTop="xxdp"
            app:cardCornerRadius="48dp"
            app:cardBackgroundColor="@color/colorSecondaryLight"
            .../>

    </FrameLayout>

Then apply a ShapeAppearanceModel:

    val cardView = findViewById<MaterialCardView>(R.id.card)

    cardView.shapeAppearanceModel = cardView.shapeAppearanceModel.toBuilder()
        .setTopLeftCorner(CustomCornerTreatment())
        .setBottomLeftCorner(CornerFamily.ROUNDED, 0f)
        .setBottomRightCorner(CornerFamily.ROUNDED, 0f)
        .build()

with a custom CornerTreatment like this:

class CustomCornerTreatment : CornerTreatment() {

    override fun getCornerPath(
        shapePath: ShapePath,
        angle: Float,
        interpolation: Float,
        radius: Float
    ) {

        val interpolatedRadius = radius * interpolation
        shapePath.reset(0f, -radius * interpolation, 270f,270 -angle)
        shapePath.addArc(
            0f,
            -2*interpolatedRadius,
            2*interpolatedRadius,
            0f,
            180f,
            - angle)

    }
}

enter image description here

Upvotes: 5

Tejas Dhawale
Tejas Dhawale

Reputation: 433

This can done be in various ways.

  1. You take your top image asset curved and apply white background to your parent view.
  2. You create another curved view and attach it to your top imageView.

To solve this I have created this png you can use vector for better results. enter image description here

In you activity/fragment XML:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">


<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/top_img"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:src="@color/green_action_bar"  <-- add your img here
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/guidelineCenter"/>


    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.6" />


    <ImageView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:src="@drawable/sample"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
       app:layout_constraintTop_toBottomOf="@id/guidelineCenter" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Your end result will be like this. Replace green color with your image

enter image description here

Upvotes: 3

Related Questions