Android 使用XML定义生成三角形形状?
有没有一种方法可以在XML文件中指定三角形形状Android 使用XML定义生成三角形形状?,android,xml,Android,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=&
<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>
我们可以用路径形状或其他什么来做吗?我只需要一个等边三角形
<?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>
谢谢我从未这样做过,但据我所知,您可以使用PathShape类:
我可以帮你不使用XML吗
简单地说 自定义布局(切片): 您的活动(示例): 工作示例:
另一个您可能感兴趣的绝对简单的
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;
}
在本文中,我描述了如何做到这一点。这是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>
并创建一个像
根据他的解决方案,如果您需要反向三角形,您可以使用:
<?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>
您可以获得更多选项。在这种情况下,我肯定会实现视图:
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>
使用此实现将获得以下结果:
您可以使用
如果您的最小API低于21,Android Studio会在构建时自动为这些较低版本创建PNG位图(请参阅)。如果您使用支持库,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>
在模块的build.gradle中执行defaultConfig
然后将(矢量xml)设置为可绘制,如下所示:
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:srcCompat="@drawable/triangle" />
页面上的所有内容都记录得很好
从这项功能开始,我就一直在工作,在图标方面完全没有位图这也大大减少了APK大小。请参见此处的答案:
对于那些想要直角三角形箭头的人,这里是: 步骤1:创建一个可绘制的XML文件,将以下XML内容复制并粘贴到可绘制的XML中。(请注意,您可以为您的可绘制XML文件使用任何名称。对于我的情况,我将其命名为“v_right_arrow”)
步骤2:在布局的XML中,创建一个视图,并将其背景绑定到刚才在步骤1中创建的可绘制XML。在我的例子中,我将v_right_arrow绑定到视图的background属性
<View
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/v_right_arrow">
</View>
样本输出:
希望这有帮助,祝你好运 我的聚会可能会迟到,我遇到了同样的问题,谷歌给我指出了这个StackOverflow线程作为第一个结果 我尝试使用xml的方式添加三角形,并发现了三角形 通过xml实现形状的方法占用的空间比看起来的要大 请参见打开布局边界的屏幕截图 因此,我们制作了这个自定义视图类,它可以绘制以下任意类型的三角形:-
<com.hiteshsahu.materialupvote.TriangleShapeView
android:layout_width="50dp"
android:layout_height="50dp"></com.hiteshsahu.materialupvote.TriangleShapeView>
我知道OP想要xml解决方案中的解决方案,但正如我指出的xml方法的问题。我希望它可能会帮助某些人。您可以使用
向量
来制作这样的三角形
<com.hiteshsahu.materialupvote.TriangleShapeView
android:layout_width="50dp"
android:layout_height="50dp"></com.hiteshsahu.materialupvote.TriangleShapeView>
ic\u triangle\u 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>
结果
要更改向量的形状,可以更改向量的宽度/高度。示例将宽度更改为10dp
<vector
android:width="10dp"
android:height="24dp"
>
...
</vector>
...
谷歌提供了一个等边三角形。
选择VectorDrawable,使大小灵活。
它作为插件集成到Android Studio中 如果您有SVG图像,也可以使用将其转换为VectorDrawable
一旦你有了矢量绘图,改变它的颜色和旋转就很容易了,就像其他人提到的那样 您可以使用以下xml在后台添加以下三角形
<?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设计的整个逻辑在pathData
中。考虑左上角为(0,0),根据您的要求设计布局。
检查答案。使用的解决方案,我制作了一个带有透明背景的定向向下的角度
<?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>
参数取决于图像的大小。例如,如果ImageView
的大小为100dp*80dp,则应使用以下常量:
<rotate
android:fromDegrees="135"
android:pivotX="64.5%"
android:pivotY="19%"
android:toDegrees="135"
>
我尝试创建类似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>
使用矢量绘图:
<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>
如果您不想破坏xml,我将在下面提供此customView。 请试一试
/**
*三角视图
*
*@author-Veer
*@日期2020-09-03
*/
类TriangalView@JVM重载构造函数(
上下文:上下文,
属性集?=null,
defStyleAttr:Int=0
):视图(上下文、属性、defStyleAttr){
私有变量三角形颜色:Int=0
private var direction=direction.Bottom
偷懒者的私人绘画{
涂上油漆{
Isatarias=真
style=Paint.style.FILL
颜色=t
<?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>
<View
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/v_right_arrow">
</View>
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;
}
}
<com.hiteshsahu.materialupvote.TriangleShapeView
android:layout_width="50dp"
android:layout_height="50dp"></com.hiteshsahu.materialupvote.TriangleShapeView>
<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"
/>
<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
/>
<vector
android:width="10dp"
android:height="24dp"
>
...
</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>
<?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 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>
<ImageView
android:layout_width="10dp"
android:layout_height="10dp"
android:src="@drawable/ic_angle_down"
/>
<rotate
android:fromDegrees="135"
android:pivotX="64.5%"
android:pivotY="19%"
android:toDegrees="135"
>
<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>
<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>
/**
* TriangleView
*
* @author Veer
* @date 2020-09-03
*/
class TriangleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private var triangleColor: Int = 0
private var direction = Direction.Bottom
private val paint by lazy {
Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = triangleColor
}
}
init {
initStyle(context, attrs, defStyleAttr)
}
private fun initStyle(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int
) {
val ta = context.obtainStyledAttributes(attrs, R.styleable.TriangleView, defStyleAttr, 0)
with(ta) {
triangleColor =
getColor(R.styleable.TriangleView_triangle_background, Color.parseColor("#000000"))
val directionValue =
getInt(R.styleable.TriangleView_triangle_direction, Direction.Bottom.value)
direction = when (directionValue) {
Direction.Top.value -> Direction.Top
Direction.Bottom.value -> Direction.Bottom
Direction.Left.value -> Direction.Left
Direction.Right.value -> Direction.Right
else -> Direction.Bottom
}
recycle()
}
}
override fun onDraw(canvas: Canvas) {
calculatePath(direction).let {
canvas.drawPath(it, paint)
}
}
private fun calculatePath(direction: Direction): Path {
var p1: Point? = null
var p2: Point? = null
var p3: Point? = null
val width = width
val height = height
when (direction) {
Direction.Top -> {
p1 = Point(0, height)
p2 = Point(width / 2, 0)
p3 = Point(width, height)
}
Direction.Bottom -> {
p1 = Point(0, 0)
p2 = Point(width / 2, height)
p3 = Point(width, 0)
}
Direction.Left -> {
p1 = Point(width, 0)
p2 = Point(0, height / 2)
p3 = Point(width, height)
}
Direction.Right -> {
p1 = Point(0, 0)
p2 = Point(width, height / 2)
p3 = Point(0, height)
}
}
val path = Path()
path.moveTo(p1.x.toFloat(), p1.y.toFloat())
path.lineTo(p2.x.toFloat(), p2.y.toFloat())
path.lineTo(p3.x.toFloat(), p3.y.toFloat())
return path
}
private enum class Direction(val value: Int) {
Top(0),
Bottom(1),
Left(2),
Right(3)
}
}
<declare-styleable name="TriangleView">
<attr name="triangle_direction" format="enum">
<enum name="top" value="0" />
<enum name="bottom" value="1" />
<enum name="left" value="2" />
<enum name="right" value="3" />
</attr>
<attr name="triangle_background" format="reference|color" />
</declare-styleable>