Делая треугольную форму, используя определения XML? - PullRequest
119 голосов
/ 25 марта 2010

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

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

Спасибо

Ответы [ 19 ]

158 голосов
/ 24 августа 2013

В этот пост Я опишу, как это сделать. А вот 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: чтобы создать стрелку, указывающую как -> использовать:

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

И чтобы создать стрелку, указывающую как <- используйте: </p>

android:fromDegrees="45"
android:toDegrees="45"
android:pivotX="87%"
android:pivotY="140%" >
78 голосов
/ 27 августа 2014
<TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="▼"/>

Вы можете получить здесь больше опций.

49 голосов
/ 12 декабря 2016

Вы можете использовать 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

39 голосов
/ 29 июля 2015

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

Если ваш минимальный 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.

39 голосов
/ 26 октября 2014

Я бы определенно пошел на реализацию 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;

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

38 голосов
/ 22 января 2014

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

<?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>
19 голосов
/ 16 мая 2016

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

11 голосов
/ 12 августа 2013

Могу ли я помочь вам без с использованием 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;
}
6 голосов
/ 29 июня 2016

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

ШАГ 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 вашего макета создайте View и свяжите его фон с нарисованным XML, который вы только что создали в STEP 1 . Для моего случая я связываю v_right_arrow со свойством background моего вида.

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

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

enter image description here

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

4 голосов
/ 12 августа 2014
<?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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...