77 votes

Comment utiliser le canevas Android pour dessiner un rectangle dont seuls les coins supérieur gauche et supérieur droit sont arrondis ?

J'ai trouvé une fonction pour les rectangles dont les 4 coins sont arrondis, mais je veux que seuls les 2 coins supérieurs soient arrondis. Que puis-je faire ?

canvas.drawRoundRect(new RectF(0, 100, 100, 300), 6, 6, paint);

1 votes

Ne pouvez-vous pas simplement dessiner un rectangle arrondi puis un rectangle ordinaire sur la moitié inférieure (en remplaçant les coins arrondis par des coins normaux) ?

11voto

Vadim Akhmerov Points 251

Fonction d'aide simple écrite en Kotlin.

private fun Canvas.drawTopRoundRect(rect: RectF, paint: Paint, radius: Float) {
    // Step 1. Draw rect with rounded corners.
    drawRoundRect(rect, radius, radius, paint)

    // Step 2. Draw simple rect with reduced height,
    // so it wont cover top rounded corners.
    drawRect(
            rect.left,
            rect.top + radius,
            rect.right,
            rect.bottom,
            paint
    )
}

Utilisation :

canvas.drawTopRoundRect(rect, paint, radius)

6 votes

I

0 votes

D

10voto

Kvant Points 151
public static Path composeRoundedRectPath(RectF rect, float topLeftDiameter, float topRightDiameter,float bottomRightDiameter, float bottomLeftDiameter){
    Path path = new Path();
    topLeftDiameter = topLeftDiameter < 0 ? 0 : topLeftDiameter;
    topRightDiameter = topRightDiameter < 0 ? 0 : topRightDiameter;
    bottomLeftDiameter = bottomLeftDiameter < 0 ? 0 : bottomLeftDiameter;
    bottomRightDiameter = bottomRightDiameter < 0 ? 0 : bottomRightDiameter;

    path.moveTo(rect.left + topLeftDiameter/2 ,rect.top);
    path.lineTo(rect.right - topRightDiameter/2,rect.top);
    path.quadTo(rect.right, rect.top, rect.right, rect.top + topRightDiameter/2);
    path.lineTo(rect.right ,rect.bottom - bottomRightDiameter/2);
    path.quadTo(rect.right ,rect.bottom, rect.right - bottomRightDiameter/2, rect.bottom);
    path.lineTo(rect.left + bottomLeftDiameter/2,rect.bottom);
    path.quadTo(rect.left,rect.bottom,rect.left, rect.bottom - bottomLeftDiameter/2);
    path.lineTo(rect.left,rect.top + topLeftDiameter/2);
    path.quadTo(rect.left,rect.top, rect.left + topLeftDiameter/2, rect.top);
    path.close();

    return path;
}

2 votes

T

7voto

Bhargav Points 11

J'y suis parvenu en suivant les étapes suivantes.

Ce sont les conditions préalables pour que le rectangle arrondi ait un aspect soigné.

  • Le rayon des bords doit être égal à la (hauteur du rectangle / 2). En effet, si la valeur est différente, l'endroit où la courbe rencontre la ligne droite du rectangle ne sera pas égal à la hauteur du rectangle.

Voici les étapes pour dessiner le rectangle arrondi.

  • Tout d'abord, nous dessinons 2 cercles sur les côtés gauche et droit, avec le rayon = hauteur du rectangle / 2

  • Ensuite, nous dessinons un rectangle entre ces cercles pour obtenir le rectangle arrondi souhaité.

J'affiche le code ci-dessous

private void drawRoundedRect(Canvas canvas, float left, float top, float right, float bottom) {
    float radius = getHeight() / 2;
    canvas.drawCircle(radius, radius, radius, mainPaint);
    canvas.drawCircle(right - radius, radius, radius, mainPaint);
    canvas.drawRect(left + radius, top, right - radius, bottom, mainPaint);
}

Le résultat est un joli rectangle arrondi comme celui qui est montré ci-dessous enter image description here

7voto

drspaceboo Points 971

C'est une vieille question, mais je voulais ajouter ma solution parce qu'elle utilise le SDK natif sans beaucoup de code personnalisé ou de dessin bricolé. Cette solution est prise en charge depuis l'API 1.

La façon de procéder correctement est de créer un chemin (comme mentionné dans d'autres réponses), mais les réponses précédentes semblent négliger l'étape suivante. addRoundedRect appel de fonction qui prend les rayons pour chaque coin.

Variables

private val path = Path()
private val paint = Paint()

Peinture de configuration

paint.color = Color.RED
paint.style = Paint.Style.FILL

Mise à jour du chemin avec les changements de taille

Appelez ceci quelque part qui n'est pas onDraw, tel que onMeasure pour une vue ou onBoundChange pour un dessinateur. S'il ne change pas (comme dans cet exemple), vous pouvez placer ce code là où vous configurez votre peinture.

val radii = floatArrayOf(
    25f, 25f, //Top left corner
    25f, 25f, //Top right corner
    0f, 0f,   //Bottom right corner
    0f, 0f,   //Bottom left corner
)

path.reset() //Clears the previously set path
path.addRoundedRect(0f, 0f, 100f, 100f, radii, Path.Direction.CW)

Ce code crée un rectangle arrondi de 100x100 dont les coins supérieurs sont arrondis avec un rayon de 25.

Dessiner un chemin

Appelez ça en onDraw pour une vue ou draw pour un dessinateur.

canvas.drawPath(path, paint)

7voto

Yu-Long Chen Points 1038

A Chemin#arcTo() version pour dessiner le côté arrondi si le rayon est la moitié de la hauteur.

fun getPathOfRoundedRectF(
    rect: RectF,
    topLeftRadius: Float = 0f,
    topRightRadius: Float = 0f,
    bottomRightRadius: Float = 0f,
    bottomLeftRadius: Float = 0f
): Path {
    val tlRadius = topLeftRadius.coerceAtLeast(0f)
    val trRadius = topRightRadius.coerceAtLeast(0f)
    val brRadius = bottomRightRadius.coerceAtLeast(0f)
    val blRadius = bottomLeftRadius.coerceAtLeast(0f)

    with(Path()) {
        moveTo(rect.left + tlRadius, rect.top)

        //setup top border
        lineTo(rect.right - trRadius, rect.top)

        //setup top-right corner
        arcTo(
            RectF(
                rect.right - trRadius * 2f,
                rect.top,
                rect.right,
                rect.top + trRadius * 2f
            ), -90f, 90f
        )

        //setup right border
        lineTo(rect.right, rect.bottom - trRadius)

        //setup bottom-right corner
        arcTo(
            RectF(
                rect.right - brRadius * 2f,
                rect.bottom - brRadius * 2f,
                rect.right,
                rect.bottom
            ), 0f, 90f
        )

        //setup bottom border
        lineTo(rect.left + blRadius, rect.bottom)

        //setup bottom-left corner
        arcTo(
            RectF(
                rect.left,
                rect.bottom - blRadius * 2f,
                rect.left + blRadius * 2f,
                rect.bottom
            ), 90f, 90f
        )

        //setup left border
        lineTo(rect.left, rect.top + tlRadius)

        //setup top-left corner
        arcTo(
            RectF(
                rect.left,
                rect.top,
                rect.left + tlRadius * 2f,
                rect.top + tlRadius * 2f
            ),
            180f,
            90f
        )

        close()

        return this
    }
}

Two rounded corners Three rounded corners Three rounded corners

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X