web-dev-qa-db-fra.com

Faire une forme de triangle en utilisant des définitions XML?

Est-il possible de spécifier une forme de triangle dans un fichier XML?

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="triangle">
  <stroke Android:width="1dip" Android:color="#FFF" />
  <solid Android:color="#FFF" />
</shape>

pouvons-nous faire cela avec une forme de chemin ou quelque chose? J'ai juste besoin d'un triangle équilatéral.

Merci

123
user291701

Dans ce post je décris comment le faire. Et voici le triangle de définition XML:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item>
        <rotate
            Android:fromDegrees="45"
            Android:toDegrees="45"
            Android:pivotX="-40%"
            Android:pivotY="87%" >
            <shape
                Android:shape="rectangle" >
                <stroke Android:color="@color/transparent" Android:width="10dp"/>
                <solid
                    Android:color="@color/your_color_here" />
            </shape>
        </rotate>
    </item>
</layer-list>

Reportez-vous à mon message si quelque chose n'est pas clair ou si vous avez besoin d'explications sur la manière dont il est construit. Il fait pivoter un rectangle de découpe :) c'est une solution très intelligente et qui fonctionne bien.

EDIT: pour créer une flèche pointant comme -> use:

...
Android:fromDegrees="45"
Android:toDegrees="45"
Android:pivotX="13%"
Android:pivotY="-40%" >
...

Et pour créer une flèche pointant comme <- utilisez:

Android:fromDegrees="45"
Android:toDegrees="45"
Android:pivotX="87%"
Android:pivotY="140%" >
160
Jacek Milewski
<TextView 
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="▼"/>

Vous pouvez obtenir ici plus d'options.

78
Elhanan Mishraky

Vous pouvez utiliser vector pour créer un triangle comme celui-ci

ic_triangle_right.xml

<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:width="24dp"
        Android:height="24dp"
        Android:viewportWidth="24.0"
        Android:viewportHeight="24.0">
    <path
        Android:pathData="M0,12l0,12 11.5,-5.7c6.3,-3.2 11.5,-6 11.5,-6.3 0,-0.3 -5.2,-3.1 -11.5,-6.3l-11.5,-5.7 0,12z"
        Android:strokeColor="#00000000"
        Android:fillColor="#000000"/>
</vector>

Alors utilisez-le comme

<ImageView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_triangle_right"
    />

Pour changer la couleur et la direction, utilisez Android:tint et Android:rotation

<ImageView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_triangle_right"
    Android:rotation="180" // change direction
    Android:tint="#00f" // change color
    />

Résultat

enter image description here

Pour changer la forme du vecteur, vous pouvez changer la largeur/hauteur du vecteur. Exemple changer la largeur à 10dp

<vector 
        Android:width="10dp"
        Android:height="24dp"
        >
       ...
</vector>

enter image description here

52
Phan Van Linh

Vous pouvez utiliser vector drawables .

Si votre API minimale est inférieure à 21, Android Studio crée automatiquement des bitmaps PNG pour les versions les plus basses au moment de la construction (voir Vector Asset Studio ). Si vous utilisez le support bibliothèque, Android gère même les "vecteurs réels" jusqu’à l’API 7 (pour plus de détails à ce sujet dans la mise à jour de ce message en bas).

Un triangle pointant vers le haut rouge serait:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:height="100dp"
    Android:width="100dp"
    Android:viewportHeight="100"
    Android:viewportWidth="100" >
    <group
        Android:name="triableGroup">
        <path
            Android:name="triangle"
            Android:fillColor="#FF0000"
            Android:pathData="m 50,0 l 50,100 -100,0 z" />
    </group>
</vector>

Ajoutez-le à votre présentation et n'oubliez pas de définir clipChildren = "false" si vous faites pivoter le triangle.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:clipChildren="false">

    <ImageView
        Android:layout_width="130dp"
        Android:layout_height="100dp"
        Android:rotation="0"
        Android:layout_centerInParent="true"
        Android:background="@drawable/triangle"/>

</RelativeLayout>

enter image description here

Modifiez la taille (largeur/hauteur) du triangle en définissant les attributs Vues layout_width/layout_height. De cette façon, vous pouvez également obtenir un triagle équilatéral si vous faites les calculs correctement.

UPDATE 25.11.2017

Si vous utilisez la bibliothèque de support, vous pouvez utiliser de vrais vecteurs (au lieu de créer des images bitmap) depuis l’API 7 . Ajoutez simplement:

vectorDrawables.useSupportLibrary = true

faites votre defaultConfig dans le build.gradle de votre module.

Puis définissez le dessin (vector xml) comme suit:

<ImageView
    Android:layout_height="wrap_content"
    Android:layout_width="wrap_content"
    app:srcCompat="@drawable/triangle" />

Tout est très bien documenté sur la page Vector Asset Studio .

Depuis cette fonctionnalité, je travaille entièrement sans images bitmap en termes d’icônes. Ceci réduit également un peu la taille de l'APK.

40
Oliver Metz

J'irais certainement pour implémenter une vue dans ce cas:

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;

public class TriangleShapeView extends View {

    public TriangleShapeView(Context context) {
        super(context);
    }

    public TriangleShapeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public TriangleShapeView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int w = getWidth() / 2;

        Path path = new Path();
        path.moveTo( w, 0);
        path.lineTo( 2 * w , 0);
        path.lineTo( 2 * w , w);
        path.lineTo( w , 0);
        path.close();

        Paint p = new Paint();
        p.setColor( Color.RED );

        canvas.drawPath(path, p);
    }
}

Utilisez-le dans vos mises en page comme suit:

<TriangleShapeView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#ff487fff">
</TriangleShapeView>

L'utilisation de cette implémentation vous donnera le résultat suivant:

enter image description here

39
Peter

Le solution de Jacek Milewski fonctionne pour moi et, sur la base de sa solution, si vous avez besoin d’un triangle inversé, vous pouvez utiliser ceci:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item>
        <rotate
            Android:fromDegrees="45"
            Android:toDegrees="45"
            Android:pivotX="135%" 
            Android:pivotY="15%">
            <shape Android:shape="rectangle">    
                <solid Android:color="@color/aquamarine" />
            </shape>
        </rotate>
    </item>
</layer-list>
38
senechaux

Voir la réponse ici: Flèches personnalisées sans image: Android

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:width="32dp"
        Android:height="24dp"
        Android:viewportWidth="32.0"
        Android:viewportHeight="24.0">
    <path Android:fillColor="#e4e4e8"
          Android:pathData="M0 0 h32 l-16 24 Z"/>
</vector>

arrow

19
zed

Puis-je vous aider sans en utilisant XML?


Simplement,

Mise en page personnalisée (tranche):

import Android.content.Context;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.Paint.Style;
import Android.graphics.Path;
import Android.graphics.Point;
import Android.util.AttributeSet;
import Android.view.View;

public class Slice extends View {

    Paint mPaint;

    Path mPath;

    public enum Direction {
        NORTH, SOUTH, EAST, WEST
    }

    public Slice(Context context) {
        super(context);
        create();
    }

    public Slice(Context context, AttributeSet attrs) {
        super(context, attrs);
        create();
    }

    public void setColor(int color) {
        mPaint.setColor(color);
        invalidate();
    }

    private void create() {
        mPaint = new Paint();
        mPaint.setStyle(Style.FILL);
        mPaint.setColor(Color.RED);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPath = calculate(Direction.SOUTH);
        canvas.drawPath(mPath, mPaint);
    }

    private Path calculate(Direction direction) {
        Point p1 = new Point();
        p1.x = 0;
        p1.y = 0;

        Point p2 = null, p3 = null;

        int width = getWidth();

        if (direction == Direction.NORTH) {
            p2 = new Point(p1.x + width, p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y - width);
        } else if (direction == Direction.SOUTH) {
            p2 = new Point(p1.x + width, p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y + width);
        } else if (direction == Direction.EAST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x - width, p1.y + (width / 2));
        } else if (direction == Direction.WEST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x + width, p1.y + (width / 2));
        }

        Path path = new Path();
        path.moveTo(p1.x, p1.y);
        path.lineTo(p2.x, p2.y);
        path.lineTo(p3.x, p3.y);

        return path;
    }
}

Votre activité (exemple):

import Android.app.Activity;
import Android.graphics.Color;
import Android.os.Bundle;
import Android.view.ViewGroup.LayoutParams;
import Android.widget.LinearLayout;

public class Layout extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Slice mySlice = new Slice(getApplicationContext());
        mySlice.setBackgroundColor(Color.WHITE);
        setContentView(mySlice, new LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    }
}

Exemple de travail:

enter image description here


Une autre fonction Calculate absolument simple qui pourrait vous intéresser ..

private Path Calculate(Point A, Point B, Point C) {
    Path Pencil = new Path();
    Pencil.moveTo(A.x, A.y);
    Pencil.lineTo(B.x, B.y);
    Pencil.lineTo(C.x, C.y);
    return Pencil;
}
11
Ahmed Ghoneim

Pour ceux qui veulent une flèche en triangle rectangle, voici:

ÉTAPE 1: Créez un fichier XML dessinable, copiez et collez le contenu XML suivant dans votre fichier XML dessinable. (Veuillez noter que vous pouvez utiliser n'importe quel nom pour votre fichier XML extractible. Pour mon cas, je le nomme "v_right_arrow")

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item >
        <rotate
            Android:fromDegrees="45"
            Android:toDegrees="-45"
            Android:pivotX="15%"
            Android:pivotY="-36%" >
            <shape
                Android:shape="rectangle"  >
                <stroke Android:color="@Android:color/transparent" Android:width="1dp"/>
                <solid
                    Android:color="#000000"  />
            </shape>
        </rotate>
    </item>
</layer-list>

ÉTAPE 2: Dans le code XML de votre mise en page, créez une vue et liez son arrière-plan au fichier XML dessinable que vous venez de créer ÉTAPE 1 . Dans mon cas, je lie v_right_arrow à la propriété background de ma vue.

<View
    Android:layout_width="200dp"
    Android:layout_height="200dp"
    Android:background="@drawable/v_right_arrow">
</View>

Exemple de sortie:

enter image description here

En espérant que ça aide, bonne chance!

6
Chong Chern Dong

Vous pouvez ajouter le triangle suivant en arrière-plan en utilisant le code XML suivant

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:height="100dp"
    Android:width="100dp"
    Android:viewportHeight="100"
    Android:viewportWidth="100" >
    <group
        Android:name="triableGroup">
        <path
            Android:name="triangle"
            Android:fillColor="#848af8"
            Android:pathData="M 0,20 L 0,0 L 100,0 L 100,20 L 54,55  l -1,0.6  l -1,0.4  l -1,0.2  l -1,0   l -1,-0  l -1,-0.2  l -1,-0.4  l -1,-0.6    L 46,55   L 0,20 -100,-100 Z" />
    </group>
</vector>

Toute la logique pour personnaliser la conception XML se trouve dans les données de chemin. Considérez en haut à gauche (0,0) et concevez la mise en page selon vos besoins. Vérifiez this réponse.

4
snj
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item>
        <rotate
            Android:fromDegrees="45"
            Android:toDegrees="45"
            Android:pivotX="-40%"
            Android:pivotY="87%" >
            <shape
                Android:shape="rectangle" >
                <stroke Android:color="@Android:color/transparent" Android:width="0dp"/>
                <solid
                    Android:color="#fff" />
            </shape>
        </rotate>
    </item>
</layer-list>
4
Arunkumar

En utilisant un vecteur dessinable:

<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
   Android:width="24dp"
   Android:height="24dp"
   Android:viewportWidth="24.0"
   Android:viewportHeight="24.0">
   <path
        Android:pathData="M0,0 L24,0 L0,24 z"
        Android:strokeColor="@color/color"
        Android:fillColor="@color/color"/>
</vector>

enter image description here

4
Zygi
 <layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item>
            <rotate
                Android:fromDegrees="45"
                Android:pivotX="135%"
                Android:pivotY="1%"
                Android:toDegrees="45">
                <shape Android:shape="rectangle">
                    <stroke
                        Android:width="-60dp"
                        Android:color="@Android:color/transparent" />
                    <solid Android:color="@color/orange" />
                </shape>
            </rotate>
        </item>
    </layer-list>
4
Shivam Kumar

Je suis en retard pour faire la fête et je suis tombé sur le même problème et Google m'a indiqué ce fil StackOverflow comme premier résultat.

J'ai essayé d'utiliser xml pour ajouter un triangle et trouver un problème: la forme du triangle via l'approche xml prend plus de place qu'il n'y parait.

Voir la capture d'écran avec les limites de la mise en page sur

enter image description here

Nous avons donc fini par créer cette classe de vue personnalisée qui peut dessiner Triangle de l’un des types suivants: -

  1. pointant vers le haut
  2. vers le bas
  3. à gauche et
  4. pointant à droite

asas

package com.hiteshsahu.materialupvotewidget;    
import Android.content.Context;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.Path;
import Android.support.annotation.NonNull;
import Android.util.AttributeSet;
import Android.view.View;

public class TriangleShapeView extends View {

    private int colorCode = Color.DKGRAY;

    public int getColorCode() {
        return colorCode;
    }

    public void setColorCode(int colorCode) {
        this.colorCode = colorCode;
    }

    public TriangleShapeView(Context context) {
        super(context);
        if (isInEditMode())
            return;
    }

    public TriangleShapeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (isInEditMode())
            return;
    }

    public TriangleShapeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        if (isInEditMode())
            return;
    }


    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int w = getWidth() / 2;
        int h = getHeight() / 2;

        //Choose what type of triangle you want here
        Path path = getLeftTriangle(w, h);

        path.close();
        Paint p = new Paint();
        p.setColor(colorCode);
        p.setAntiAlias(true);

        canvas.drawPath(path, p);
    }

    @NonNull
    /**
     * Return Path for down facing triangle
     */
    private Path getInvertedTriangle(int w, int h) {
        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(w, 2 * h);
        path.lineTo(2 * w, 0);
        path.lineTo(0, 0);
        return path;
    }

    @NonNull
    /**
     * Return Path for Up facing triangle
     */
    private Path getUpTriangle(int w, int h) {
        Path path = new Path();
        path.moveTo(0, 2 * h);
        path.lineTo(w, 0);
        path.lineTo(2 * w, 2 * h);
        path.lineTo(0, 2 * h);
        return path;
    }

    @NonNull
    /**
     * Return Path for Right pointing triangle
     */
    private Path getRightTriangle(int w, int h) {
        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(2 * w, h);
        path.lineTo(0, 2 * h);
        path.lineTo(0, 0);
        return path;
    }

    @NonNull
    /**
     * Return Path for Left pointing triangle
     */
    private Path getLeftTriangle(int w, int h) {
        Path path = new Path();
        path.moveTo(2 * w, 0);
        path.lineTo(0, h);
        path.lineTo(2 * w, 2 * h);
        path.lineTo(2 * w, 0);
        return path;
    }
}

Vous pouvez simplement l'utiliser dans la mise en page XML comme ceci

 <com.hiteshsahu.materialupvote.TriangleShapeView
            Android:layout_width="50dp"
            Android:layout_height="50dp"></com.hiteshsahu.materialupvote.TriangleShapeView>

Je sais que OP veut des solutions dans la solution xml, mais comme je l'ai signalé le problème avec l'approche xml. J'espère que cela pourrait aider quelqu'un.

3
Hitesh Sahu

Je n'ai jamais fait cela, mais d'après ce que j'ai compris, vous pouvez utiliser la classe PathShape: http://developer.Android.com/reference/Android/graphics/drawable/shapes/PathShape.html

3
Justin

En utilisant la solution de Jacek Milewski je fis un angle orienté vers le bas avec un fond transparent.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <rotate
            Android:fromDegrees="135"
            Android:pivotX="65%"
            Android:pivotY="20%"
            Android:toDegrees="135"
            >
            <shape Android:shape="rectangle">
                <stroke
                    Android:width="1dp"
                    Android:color="@color/blue"
                    />
                <solid Android:color="@color/transparent" />
            </shape>
        </rotate>
    </item>
</layer-list>

Vous pouvez changer Android:pivotX et Android:pivotY pour décaler l'angle.

Usage:

<ImageView
    Android:layout_width="10dp"
    Android:layout_height="10dp"
    Android:src="@drawable/ic_angle_down"
    />

enter image description here

Les paramètres dépendent de la taille de l'image. Par exemple, si ImageView a une taille de 100dp * 80dp, vous devez utiliser ces constantes:

<rotate
    Android:fromDegrees="135"
    Android:pivotX="64.5%"
    Android:pivotY="19%"
    Android:toDegrees="135"
    >

enter image description here

1
CoolMind

Google fournit un triangle équilatéral ici .
Choisissez VectorDrawable pour que la taille soit flexible.
Il est intégré dans Android Studio en tant que plugin.

Si vous avez une image SVG, vous pouvez aussi utiliser this pour la convertir en VectorDrawable.

Une fois que vous avez un VectorDrawable, il est facile de changer sa couleur et sa rotation comme d'autres l'ont mentionné.

0
ericn

J'essaie de créer une image en triangle comme le bouton précédent de la barre de navigation Android mais je n'ai trouvé aucune solution.

Maintenant, j'ai trouvé la solution avec moi-même et j'aimerais la partager.

triangle navigation bar Android

utiliser xml ci-dessous

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
    Android:bottom="20dp"
    Android:left="480dp"
    Android:right="60dp"
    Android:top="20dp">
    <shape>
        <size Android:width="60dp" />
        <corners Android:radius="80dp"/>
        <solid Android:color="#AAA" />
    </shape>
</item>
<item
    Android:bottom="480dp"
    Android:right="70dp"
    Android:top="20dp">
    <rotate
        Android:fromDegrees="-28"
        Android:pivotX="96%"
        Android:pivotY="50%"
        Android:toDegrees="-20">
        <shape>
            <corners Android:radius="80dp"/>
            <size Android:height="60dp" />
            <solid Android:color="#AAA" />
        </shape>
    </rotate>
</item>

<item
    Android:bottom="20dp"
    Android:right="70dp"
    Android:top="480dp">
    <rotate
        Android:fromDegrees="28"
        Android:pivotX="96%"
        Android:pivotY="50%"
        Android:toDegrees="-20">
        <shape>
            <corners Android:radius="80dp"/>
            <size Android:height="60dp" />
            <solid Android:color="#AAA" />
        </shape>
    </rotate>
</item>
0
rattisuk
  <LinearLayout
        Android:id="@+id/ly_fill_color_shape"
        Android:layout_width="300dp"
        Android:layout_height="300dp"
        Android:layout_gravity="center"
        Android:background="@drawable/shape_triangle"
        Android:gravity="center"
        Android:orientation="horizontal" >
    </LinearLayout>
<item>
    <rotate
        Android:fromDegrees="45"
        Android:pivotX="-15%"
        Android:pivotY="77%"
        Android:toDegrees="45" >
        <shape Android:shape="rectangle" >
            <stroke
                Android:width="2dp"
                Android:color="@color/black_color" />

            <solid Android:color="@color/white" />

            <padding Android:left="1dp" />
        </shape>
    </rotate>
</item>
<item Android:top="200dp">
    <shape Android:shape="line" >
        <stroke
            Android:width="1dp"
            Android:color="@color/black_color" />

        <solid Android:color="@color/white" /> 
    </shape>
</item>
0
Kena Patel