Создание формы треугольника с использованием определений xml? - программирование
Подтвердить что ты не робот

Создание формы треугольника с использованием определений xml?

Есть ли способ, которым я могу указать форму треугольника в 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>

можем ли мы сделать это с помощью формы пути или чего-то еще? Мне нужен только равносторонний треугольник.

Спасибо

4b9b3361

Ответ 1

В этот пост Я описываю, как это сделать. И вот треугольник, определяющий 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>

Обратитесь к моему сообщению, если что-то неясно или вам нужно объяснение, как оно построено. Он поворачивает прямоугольник выреза:) это очень умное и хорошо работающее решение.

EDIT: для создания стрелки, указывающей как → use:

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

И для создания стрелки, указывающей как < - use:

android:fromDegrees="45"
android:toDegrees="45"
android:pivotX="87%"
android:pivotY="140%" >

Ответ 2

<TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="▼"/>

Вы можете получить здесь дополнительные параметры.

Ответ 3

Вы можете использовать vector чтобы сделать треугольник, как это

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>

Тогда используйте это как

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

Для изменения цвета и направления используйте android:tint и 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
    />

Результат

enter image description here

Для изменения формы вектора, вы можете изменить ширину/высоту вектора. Пример изменения ширины до 10dp

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

enter image description here

Ответ 4

Я бы определенно пошел на реализацию представления в этом случае:

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);
    }
}

Используйте его в своих макетах следующим образом:

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

Использование этой реализации даст вам следующий результат:

enter image description here

Ответ 5

Вы можете использовать векторные рисунки.

Если ваш минимальный API меньше 21, Android Studio автоматически создает растровые изображения PNG для этих более низких версий во время сборки (см. Vector Asset Studio). Если вы используете библиотеку поддержки, Android даже управляет "реальными векторами" вплоть до API 7 (подробнее об этом в обновлении этого поста внизу).

Красный треугольник, направленный вверх:

<?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>

Добавьте его в свой макет и не забудьте установить clipChildren = "false", если вы поворачиваете треугольник.

<?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

Измените размер (ширину/высоту) треугольника, установив атрибуты Views layout_width/layout_height. Таким образом, вы также можете получить трехсторонний треугольник, если вы все сделаете правильно.

ОБНОВЛЕНИЕ 25.11.2017

Если вы используете библиотеку поддержки, вы можете использовать реальные векторы (вместо создания растрового изображения) еще в API 7. Просто добавьте:

vectorDrawables.useSupportLibrary = true

сделайте ваш defaultConfig в вашем модуле build.gradle.

Затем установите (векторный xml) объект рисования следующим образом:

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

Все очень хорошо описано на странице Vector Asset Studio.

С тех пор, как эта функция, я работаю совершенно без растровых изображений с точки зрения иконок. Это также немного уменьшает размер APK.

Ответ 6

Решение Jacek Milewski работает для меня и, основываясь на его решении, если вам нужно и инвертированный треугольник, вы можете использовать это:

<?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>

Ответ 7

Смотрите ответ здесь: Пользовательские стрелки без изображения: 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

Ответ 8

Могу ли я помочь вам без с помощью XML?


Просто

Пользовательский макет (фрагмент):

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;
    }
}

Ваша деятельность (пример):

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));
    }
}

Рабочий пример:

enter image description here


Еще одна абсолютно простая функция Calculate, которую вы можете заинтересовать.

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;
}

Ответ 9

Для тех, кто хочет стрелку правого треугольника, здесь вы идете:

ШАГ 1: Создайте гибкий XML файл, скопируйте и вставьте следующий XML-контент в свой гибкий XML-код. (Пожалуйста, имейте в виду, что вы можете использовать любое имя для вашего гибкого XML файла. В моем случае я называю его "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>

ШАГ 2: В вашем макете XML создайте представление и привяжите его фон к извлекаемому XML, который вы только что создали, в ШАГ 1. В моем случае я привязываю v_right_arrow к свойству background фона View.

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

Пример вывода:

введите описание изображения здесь

Надеюсь, это поможет, удачи!

Ответ 10

<?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>

Ответ 11

 <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>

Ответ 13

Я опаздываю на вечеринку, и я столкнулся с той же проблемой, и Google указал мне на этот поток StackOverflow как первый результат.

Я попробовал использовать xml способ добавить треугольник и выяснить, что треугольник форма через xml-подход занимает больше места, чем кажется.

Смотрите снимок экрана с ограничениями на

введите описание изображения здесь

Таким образом, этот класс пользовательского вида, который может рисовать Треугольник любого из следующих типов, может выглядеть следующим образом: -

  • вверх, указав
  • вниз, указав
  • слева и
  • правое указание

АСАС

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;
    }
}

Вы можете просто использовать его в XML-макете, например

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

Я знаю, что OP хочет решения в xml-решении, но поскольку я указал на проблему с подходом xml. Я надеюсь, что это может помочь кому-то.

Ответ 14

Вы можете добавить следующий треугольник в фоновом режиме, используя следующий XML

bQPZt.png

<?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>

Вся логика для настройки дизайна XML находится в данных пути. Рассмотрим верхний левый как (0,0) и спроектируем макет в соответствии с вашими требованиями. Проверьте этот ответ.

Ответ 15

  <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>

Ответ 16

Google предоставляет Равносторонний треугольник здесь.
Выберите VectorDrawable, чтобы размер был гибким.
Он интегрирован в Android Studio как плагин.

Если у вас есть изображение SVG, вы также можете использовать его для преобразования в VectorDrawable.

Если у вас есть VectorDrawable, изменить его цвет и вращение легко, как уже упоминали другие.

Ответ 17

Используя решение Яцека Милевского, я сделал ориентированный угол вниз с прозрачным фоном.

<?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>

Вы можете изменить android:pivotX и android:pivotY чтобы сместить угол.

Использование:

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

enter image description here

Параметры зависят от размера изображения. Например, если ImageView имеет размер 100dp * 80dp, вы должны использовать эти константы:

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

enter image description here

Ответ 18

Я пытаюсь создать треугольное изображение, как кнопка возврата на панели навигации Android, но я не нашел никакого решения.

Теперь я нашел решение для себя и хотел бы поделиться им.

triangle navigation bar android

используйте xml ниже

<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>

Ответ 19

Использование векторного рисования:

<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"
        android:strokeColor="@color/color"
        android:fillColor="@color/color"/>
</vector>

enter image description here