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
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%" >
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="▼"/>
Vous pouvez obtenir ici plus d'options.
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
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>
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>
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.
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:
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>
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>
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:
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;
}
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:
En espérant que ça aide, bonne chance!
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.
<?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>
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>
<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>
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
Nous avons donc fini par créer cette classe de vue personnalisée qui peut dessiner Triangle de l’un des types suivants: -
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.
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
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"
/>
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"
>
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é.
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.
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>
<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>