如何在android中使用XML形状创建一个向右的箭头(V形)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24723040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:38:49  来源:igfitidea点击:

How to create a right facing arrow (chevron) using XML shapes in android?

androidxmlandroid-drawableshape

提问by Sajal

How to create a right facing arrow using xml shapes in android like this??enter image description here

如何像这样在android中使用xml形状创建一个向右的箭头?在此处输入图片说明

回答by Simas

I've had a similar problem. Here's how I solved it:

我遇到了类似的问题。这是我解决它的方法:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape>
            <solid android:color="@android:color/transparent"/>
            <size android:width="2dp" android:height="50dp"/>
        </shape>
    </item>

    <item android:bottom="20dp">
        <rotate
            android:fromDegrees="-45"
            android:toDegrees="45">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/black"/>
                <corners
                    android:radius="1dp"
                    android:bottomRightRadius="0dp"
                    android:bottomLeftRadius="0dp"/>
            </shape>
        </rotate>
    </item>

    <item android:top="20dp">
        <rotate
            android:fromDegrees="45"
            android:toDegrees="45">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/black"/>
                <corners
                    android:radius="1dp"
                    android:topRightRadius="0dp"
                    android:topLeftRadius="0dp"/>
            </shape>
        </rotate>
    </item>
</layer-list>

The first item is an empty shape to expand the drawable. Then, I've used 2 rectangles. Each of them has 2 sides rounded.

第一项是用于扩展可绘制对象的空形状。然后,我使用了 2 个矩形。它们中的每一个都有 2 个圆角。

You need to use this drawable via an ImageView:

您需要通过以下方式使用此 drawable ImageView

<ImageView
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:src="@drawable/arrow"
    android:contentDescription="@string/arrow_descriptor"/>

Here's the result:

结果如下:

arrow example

箭头示例

Note:AndroidStudio doesn't render different corner sizes, but it shows up properly on devices.

注意:AndroidStudio 不会渲染不同的角尺寸,但它会在设备上正确显示。

回答by Martin Konicek

No need to write your own XML, there's a standard Material design chevron.

无需编写自己的 XML,有一个标准的材料设计 V 形标志。

In Android Studio, click File-> New-> Vector Asset, then click the icon (button with Android logo) and search for "Arrow".

在 Android Studio 中,单击File-> New-> Vector Asset,然后单击图标(带有 Android 标志的按钮)并搜索“箭头”。

Select the arrow you want, it will be added to your project. You can open the XML file and edit the dimensions and color if needed.

选择您想要的箭头,它将被添加到您的项目中。如果需要,您可以打开 XML 文件并编辑尺寸和颜色。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

回答by Apurv Kiri

It is not possible to create such shape using drawable xml only( See answer by user3249477), if you want to create such shape programmatically, either you create a custom drawable or view. Here, is the code for right side arrow shape. ( Colour and diameter can be configured in xml using styleable )

仅使用 drawable xml 无法创建此类形状请参阅 user3249477 的回答),如果您想以编程方式创建此类形状,则可以创建自定义 drawable 或视图。这是右侧箭头形状的代码。(颜色和直径可以使用 styleable 在 xml 中配置)

package com.kiriyard.stackoverflow24723040.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.util.AttributeSet;
import android.view.View;

public class ArrowView extends View {



    private Paint arrowPaint;
    private Path arrowPath;
    private int arrowColor = 0xFF888888;
    private float density;
    private int diameter = 25, diameter_calc, radius_calc;

    public ArrowView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        stuff();
    }

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

    public ArrowView(Context context) {
        super(context);
        stuff();
    }

    private void stuff() {

        //Getting density "dp"
        density = getContext().getResources().getDisplayMetrics().scaledDensity;
        //Calculating actual diameter
        diameter_calc = (int) density * diameter;
        radius_calc = diameter/2;

        //Creating paint
        arrowPaint = new Paint();
        arrowPaint.setAntiAlias(true);
        arrowPaint.setColor(arrowColor);

        //Initialize path
        arrowPath = new Path();

        this.setWillNotDraw(false);
    }

    private int startX,startY, currentX, currentY;

    protected void onDraw(Canvas c) {

        startX = c.getWidth();
        startY = c.getHeight()/2;

        c.rotate(-45, startX, startY);

        arrowPath.reset();
        currentX = startX;
        currentY = startY;
        //Move to right end side center of the canvas
        arrowPath.moveTo(currentX,currentY);
        //Lets move up
        currentY = radius_calc;
        arrowPath.lineTo(currentX, currentY);
        //Now draw circle
        currentX-=radius_calc;
        arrowPath.addCircle(currentX, radius_calc, radius_calc, Direction.CCW);
        currentX-=radius_calc;

        arrowPath.lineTo(currentX,currentY);
        // Go to inner side center point
        currentX = startX - diameter_calc;
        currentY = startY - diameter_calc;
        arrowPath.lineTo(currentX,currentY);
        // Go left
        currentX = startX - startY + radius_calc;
        arrowPath.lineTo(currentX, currentY);       
        //Draw circle
        currentY+=radius_calc;
        c.drawCircle(currentX, currentY, radius_calc, arrowPaint);
        currentY+=radius_calc;
        arrowPath.lineTo(currentX, currentY);
        //Go to start
        arrowPath.lineTo(startX, startY);

        c.drawPath(arrowPath, arrowPaint);
    }

}

Screenshot

截屏

Arrow Screenshot

箭头截图

So this is one of the way ! ... .. drawable image is easier way.

所以这是方法之一!... .. drawable 图像是更简单的方法。