简体   繁体   English

Android如何以编程方式创建三角形和矩形形状?

[英]Android how to create triangle and rectangle shape programmatically?

How can we create ballon drawable shape as below. 我们如何创建如下的ballon drawable形状。 where we can change the color of it dynamically. 我们可以动态地改变它的颜色。 在此输入图像描述

Here it is XML for triangle and rectangle . 这里是trianglerectangle XML save it inside drawable folder. 将其保存在drawable文件夹中。

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

rectangle.xml rectangle.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>

and layout for shape you require. 和您需要的形状布局

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

在此输入图像描述

set margin according you required. 根据您的要求设定保证金。

Source 资源

If you want a border for your layout 如果您想要布局的边框

在此输入图像描述

<?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 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 , or you can create triangle by vector like here 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>

The clean and right way to do this whilst keeping it dynamic is to extend the View class. 在保持动态的同时,干净正确的方法是扩展View类。

Then in the onDraw you would do something like this: 然后在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.
}

There you go, no unnecessary layering or code that isn't dynamic or clean. 你去,没有不必要的分层或代码不动态或干净。 You could also add the text in the box too. 您也可以在框中添加文本。

Use a triangle image and a rectangular image and mathematically align them in the above mentioned format. 使用三角形图像和矩形图像,并以上述格式对其进行数学对齐。 Use color filtering to dynamically change its color. 使用颜色过滤动态更改其颜色。

You can even draw them on a custom view, using vector graphics, using custom colors, and that would be another way of solving this problem. 您甚至可以使用矢量图形,使用自定义颜色在自定义视图上绘制它们,这将是解决此问题的另一种方法。

Create custom view and draw traingle with canvas 创建自定义视图并使用画布绘制traingle

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

在此输入图像描述

Usage 用法

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

Advantages 好处

  • Change shape according to width and height of view . 根据视图的宽度和高度更改形状。
  • Highly customization possible. 高度定制可能。
  • Look cleaner 看起来更干净

Use Canvas in onDraw method inside custom View class. 在自定义View类中的onDraw方法中使用Canvas

Other way is to use Path class. 其他方法是使用Path类。

First you can create one xml inside drawable folder 首先,您可以在drawable文件夹中创建一个xml

That xml will be responsible for the border color of rectangle shape 那个xml将负责矩形形状的边框颜色

You can create such border shape with below code 您可以使用以下代码创建此类边框形状

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

well this will create a required border to rectangle shape, you need to assign background of that rectangle shape with this drawable like this 这将为矩形形状创建一个必需的边框,你需要像这样用这个drawable分配那个矩形形状的背景

android:background="@drawable/bg"

where bg is xml file name which has been saved on drawable folder 其中bg是已保存在drawable文件夹中的xml文件名

After that you need to put that triangle exactly below to rectangle object. 之后,您需要将三角形正好放在矩形对象下方。

I hope you understood my logic 我希望你理解我的逻辑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM