Android如何通过编程创建三角形和矩形形状?

57
我们如何创建以下的气球形状,其中我们可以动态地更改其颜色。请参考下面的html标签内容。
```

如何创建以下的气球形状,其中我们可以动态地更改其颜色。 enter image description here

```

3
扩展Drawable类。 - pskink
你能给我一个简单的示例提示如何绘制任何视图吗?我以前没有做过。 - Dory
只需扩展Drawable并在draw(Canvas)方法中进行绘图即可。 - pskink
1
@Jewel,但说实话,如果我是你,我会创建一个九宫格可绘制对象,简单易行,完全不需要XML。 - pskink
1
@Jewel 不是的,看 Drawable.setColorFilter - pskink
显示剩余4条评论
7个回答

61

这是用于三角形和矩形的XML代码,将其保存在可绘制文件夹中。

triangle.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="@android:color/transparent" android:width="10dp"/>
                <solid
                    android:color="#000000"  />
            </shape>
        </rotate>
    </item>
</layer-list>

矩形.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item> 
    <shape android:shape="rectangle">
      <solid android:color="#B2E3FA" /> 
    </shape>
  </item>
</layer-list>

您需要的形状和布局

<RelativeLayout
        android:id="@+id/rlv1"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="@drawable/rectangle" />

    <RelativeLayout
        android:id="@+id/rlv2"
        android:layout_width="50dp"
        android:layout_height="50dp"  
        android:layout_below="@+id/rlv1"
        android:background="@drawable/triangle"
        android:rotation="180" />

enter image description here

根据需要设置边距。

来源


4
如果您无法使用 "android:orientation"(API级别11),则可以在现有的旋转标签外再添加另一个旋转标签。<rotate android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" > ... </rotate> - Marina.Eariel
1
我知道这不是我应该评论的方式,但我在寻找答案时发现了这个问题,我想@Sanket Kachhela可能能够回答吗?https://dev59.com/2V8d5IYBdhLWcg3wpzn4 - uesports135
3
这是与此处相同的答案,但链接提供了更多解释:https://looksok.wordpress.com/2013/08/24/android-triangle-arrow-defined-as-an-xml-shape/注:本翻译文本仅供参考,如有歧义,请以原始英文版本为准。 - dhaag23
我们不能在单个XML中创建气球形状吗? - Prashanth Debbadwar
我猜我们需要使用9 patch图像来制作气球。 - Sanket Kachhela
显示剩余3条评论

21
如果您想为您的布局添加边框。

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_root"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/text_message"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_rectangle"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:padding="8dp"
        android:text="Abc"
        />

    <ImageView
        android:id="@+id/image_arrow"
        android:layout_marginTop="-1.5dp"
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:layout_gravity="center_horizontal"
        android:background="@drawable/icon_arrow_down"
        />
</LinearLayout>

bg_rectangle

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#eaeaea" />
    <stroke
        android:width="1dp"
        android:color="#f00" />
    <corners android:radius="8dp" />

</shape>

icon_arrow_down,或者你可以像这里一样,通过向量创建三角形。


<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <rotate
            android:fromDegrees="45"
            android:pivotX="135%"
            android:pivotY="15%"
            android:toDegrees="45"
            >
            <shape android:shape="rectangle">
                <solid android:color="#eaeaea"/>
                <stroke
                    android:width="1dp"
                    android:color="#f00" />
            </shape>
        </rotate>
    </item>
</layer-list>

如何处理应用程序箭头(带有向上箭头的三角形)?我尝试了这段代码,但是没有成功,请问您能告诉我该怎么做吗? - uma

6

保持动态性的清晰正确方法是扩展View类。

然后在onDraw中,您可以这样做:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    drawBackground(canvas);
}

private void drawBackground(Canvas canvas) {
    int width = (int) mWidth;
    int height = (int) mHeight;

    Point a = new Point(0, 0);
    Point b = new Point(width, 0);
    Point c = new Point(width, height - mPointHeight);//mPointedHeight is the length of the triangle... in this case we have it dynamic and can be changed.
    Point d = new Point((width/2)+(mPointedHeight/2), height - mPointHeight);
    Point e = new Point((width/2), height);// this is the sharp point of the triangle
    Point f = new Point((width/2)-(mPointedHeight/2), height - mPointHeight);
    Point g = new Point(0, height - mPointHeight);

    Path path = new Path();
    path.moveTo(a.x, a.y);
    path.lineTo(b.x, b.y);
    path.lineTo(c.x, c.y);
    path.lineTo(d.x, d.y);
    path.lineTo(e.x, e.y);
    path.lineTo(f.x, f.y);
    path.lineTo(g.x, g.y);

    canvas.drawPath(path, mPointedBackgroundPaint);// mPointedBackgroundPaint is whatever color you want as the fill.
}

这里没有不必要的层次结构或不具有动态性或清晰度的代码。您还可以在框中添加文本。


9
由于您强调需要一个干净的解决方案,所以我想提醒您,在onDraw方法中不要创建太多对象,因为我们需要每秒执行60次。请注意保持原意并尽可能通俗易懂。 - LostPuppy
2
我会更进一步地说,在onDraw中不要创建任何对象。 - tir38
那些对象可以被移除并替换为每个路径的x和y的原始变量。这只是为了避免在lineTo()方法内部有无意义的值。 - Jessicardo

1
创建自定义视图并使用画布绘制三角形。
package com.example.dickbutt;

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 int colorCode = Color.MAGENTA;

    public int getColorCode() {
        return colorCode;
    }

    public void setColorCode(int colorCode) {
        this.colorCode = colorCode;
    }

    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;
        int h = getHeight() / 2;

        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(w, 2 * h);
        path.lineTo(2 * w, 0);
        path.lineTo(0, 0);

        path.close();

        Paint p = new Paint();
        p.setColor(colorCode);
        p.setAntiAlias(true);

        canvas.drawPath(path, p);
    }
}

Result

enter image description here

使用方法

<TextView
    android:id="@+id/progress_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:background="@android:color/holo_purple"
    android:gravity="center_horizontal"
    android:text="200,0000000"
    android:textColor="#fff" />

<com.example.dickbutt.TriangleShapeView
    android:id="@+id/textView1"
    android:layout_width="10dp"
    android:layout_height="20dp"
    android:layout_below="@+id/progress_value"
    android:layout_centerHorizontal="true"
    android:background="@drawable/rectangle"
    android:gravity="center_horizontal"
    android:textSize="10sp" />

优点

  • 根据视图的宽度和高度改变形状。
  • 高度可定制化。
  • 看起来更加清洁。

1
使用三角形图像和矩形图像,并在上述格式中进行数学对齐。使用色彩过滤器动态更改其颜色。
您甚至可以在自定义视图上绘制它们,使用矢量图形,使用自定义颜色,这将是解决此问题的另一种方法。

我们能动态地改变图像颜色吗? - Dory
您可以使用颜色滤镜来改变图像的外观。如果您有一张单色图像,只要对其进行适当的过滤,就可以将其更改为任何您喜欢的颜色。 - Aman Agnihotri
是的,drawable只能是单色的。我需要动态地将其更改为不同的颜色。我想你建议我使用setColorFilter()来将图像更改为新的颜色。我是对的吗? - Dory
是的。你可以在这里查找颜色过滤器(https://dev59.com/yWkw5IYBdhLWcg3wJHCF#10141607)。希望能有所帮助。 :) - Aman Agnihotri
1
谢谢伙计的指导 :) - Dory

0
首先,您可以在drawable文件夹中创建一个xml
xml将负责矩形形状的边框颜色。
您可以使用以下代码创建这种边框形状。
<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item> 
    <shape android:shape="rectangle">
      <solid android:color="#B2E3FA" /> 
    </shape>
  </item>   
    <item android:left="5dp" android:bottom="5dp"  android:top="5dp" >  
     <shape android:shape="rectangle"> 
      <solid android:color="#D8D8D8" />
    </shape>
   </item>    
 </layer-list> 

好的,这将为矩形形状创建一个必需的边框,您需要像这样将该矩形形状的背景分配给此可绘制对象

android:background="@drawable/bg"

bg 是一个 XML 文件名,已保存在 drawable 文件夹中。

之后,您需要将该三角形放置在矩形对象的正下方。

希望您能理解我的逻辑。


我不能使用XML,因为我需要动态更改可绘制对象的颜色。 - Dory
@Jewel,你的图像颜色会改变,但是你可以使用这个xml来给图像边框设置形状,有什么问题吗? - Aamirkhan

0

在自定义的View类中的onDraw方法中使用Canvas

另一种方法是使用Path类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接