สร้างรูปร่างสามเหลี่ยมโดยใช้นิยาม xml?


138

มีวิธีที่ฉันสามารถระบุรูปทรงสามเหลี่ยมในไฟล์ 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>

เราจะทำแบบนี้กับรูปร่างเส้นทางหรืออะไรได้ไหม ฉันแค่ต้องการสามเหลี่ยมด้านเท่า

ขอบคุณ


คุณพบวิธีแก้ปัญหาหรือไม่? ฉันมีปัญหาเดียวกัน
Mike Bevz

ดูเหมือนว่าจะได้ผลสำหรับคนที่เขียนคำแนะนำ (และผู้แสดงความคิดเห็นเล็กน้อย): Android: Draw Equilateral Triangle Shapes In Canvas
Diegum

คำตอบ:


167

ในโพสต์นี้ฉันอธิบายวิธีการทำ และนี่คือสามเหลี่ยมกำหนด 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>

อ้างถึงโพสต์ของฉันหากมีบางอย่างไม่ชัดเจนหรือคุณต้องการคำอธิบายว่ามันถูกสร้างขึ้นอย่างไร มันหมุนเป็นรูปสี่เหลี่ยมผืนผ้าคัตเอาท์ :) เป็นโซลูชันที่ชาญฉลาดและใช้งานได้ดี

แก้ไข: เพื่อสร้างลูกศรชี้เช่น -> ใช้:

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

และเพื่อสร้างลูกศรชี้เช่น <- ใช้:

android:fromDegrees="45"
android:toDegrees="45"
android:pivotX="87%"
android:pivotY="140%" >

4
ขอโทษนะ .. แต่สามเหลี่ยมด้านเท่าไม่สามารถเป็นสามเหลี่ยมมุมฉากได้
lilbyrdie

3
@JacekMilewski - ขอบคุณมาก! สนใจที่จะแบ่งปันว่าพารามิเตอร์ pivotX / pivotY ของคุณคืออะไรสำหรับลูกศรลง? ซ้าย? ขวา?
JohnnyLambada

2
ในการหมุนฉันเปลี่ยนการหมุนในไฟล์ xml เค้าโครงไม่ใช่ในนิยามสามเหลี่ยมเอง
Jacek Milewski

1
-1. สิ่งนี้ไม่ดี ขนาดจริงของมุมมองจะใหญ่กว่าเมื่อเทียบกับสิ่งที่ปรากฏบนหน้าจอ มันควรจะห่อขอบเขต
Javanator

1
คุณช่วยแบ่งปันวิธีที่คุณได้รับค่าของคุณสำหรับ fromDegrees, toDegrees, pivotX และ pivotY ได้อย่างไร ฉันมีกรณีการใช้งานที่ไม่สามารถเปลี่ยนการหมุนในไฟล์เลย์เอาต์ได้
Patrick Brennan

84
<TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="▼"/>

คุณสามารถรับตัวเลือกเพิ่มเติมได้ที่นี่


3
คุณใส่ค่านั้นใน xml ได้อย่างไร?
user531069

2
คัดลอก TextView นี้และวางลงใน xml ของคุณ
Elhanan Mishraky

6
@ user531069: ใส่ไว้ใน strings.xml ของคุณ:<string name="bottom_arrow">&#9660;</string>

1
ฉันต้องการลูกศรอื่นจากลิงก์ฉันคัดลอกและวาง & # 129032; เป็นข้อความแสดงอักขระที่ไม่รู้จัก เหรอ?
M. Usman Khan

3
โซลูชันนี้สร้างปัญหาใหม่ในการจัดการ Font Padding ภายใน Text View
Salman Khakwani

63

ใช้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
    />

ผลลัพธ์

ป้อนคำอธิบายภาพที่นี่

สำหรับการเปลี่ยนรูปร่างของเวกเตอร์คุณสามารถเปลี่ยนความกว้าง / ความสูงของเวกเตอร์ได้ ตัวอย่างเปลี่ยนความกว้างเป็น 10dp

<vector 
        android:width="10dp"
        android:height="24dp"
        >
       ...
</vector>

ป้อนคำอธิบายภาพที่นี่


ขอบคุณฉันไม่รู้จริงๆว่าเวกเตอร์เหล่านี้ทำงานอย่างไร ฉันต้องการผลลัพธ์
Hossein Shahdoost

ฉันจะเพิ่มและลดขนาดของสามเหลี่ยมเหล่านี้ได้อย่างไร การระบุความสูงและความกว้างจะใช้ไม่ได้
Aayushi

47

คุณสามารถใช้ภาพวาดเวกเตอร์

หาก 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>

ป้อนคำอธิบายภาพที่นี่

เปลี่ยนขนาด (ความกว้าง / ความสูง) ของสามเหลี่ยมโดยการตั้งค่าแอ็ตทริบิวต์ Views layout_width / layout_height วิธีนี้คุณจะได้ triagle eqilateral ถ้าคุณทำคณิตศาสตร์ได้ถูกต้อง

อัพเดท 25.11.2017

หากคุณใช้ห้องสมุดการสนับสนุนที่คุณสามารถใช้เวกเตอร์ที่แท้จริง (แทนถ้าสร้างบิตแมป) ไกลกลับเป็น API 7 เพียงเพิ่ม:

vectorDrawables.useSupportLibrary = true

ทำของคุณdefaultConfigใน build.gradle ของโมดูลของคุณ

จากนั้นตั้งค่า (vector xml) ที่วาดได้ดังนี้:

<ImageView
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    app:srcCompat="@drawable/triangle" />

ทุกอย่างเป็นเอกสารอย่างมากในเวกเตอร์สตูดิโอสินทรัพย์หน้า

นับตั้งแต่คุณลักษณะนี้ฉันทำงานโดยไม่มีบิตแมปในแง่ของไอคอน นอกจากนี้ยังช่วยลดขนาด APK ได้เล็กน้อย


1
โพสต์ลิงค์และใครบางคนจะอัปโหลดให้คุณ :-)
GabrielOshiro

1
+1 vectorDrawables.useSupportLibrary = trueมีประโยชน์พิเศษที่คุณสามารถใช้สีที่กำหนดไว้ได้colors.xmlเนื่องจากบิตแมปถูกสร้างขึ้นในระหว่างการสร้าง (เมื่อไม่มีสีที่กำหนดไว้)
Rob

1
คุณช่วยฉันไว้. ขอบคุณ
viper

39

ฉันจะไปใช้มุมมองในกรณีนี้อย่างแน่นอน:

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>

การใช้การใช้งานนี้จะให้ผลลัพธ์ดังต่อไปนี้:

ป้อนคำอธิบายภาพที่นี่


<com.your.path.to.view.TriangleShapeView ... />
ทำงาน

เป็นสิ่งที่ดี. ฉันจะเปลี่ยนสีสามเหลี่ยมได้อย่างไร บอกว่าสีเริ่มต้นเป็นสีเทา แต่เปลี่ยนเป็นสีแดงเมื่อ onTouch หรือ onClick?
Fshamri

วิธีนี้ดีกว่าการแฮ็กใน xml
dorsz

@ ปีเตอร์หวัดดี คุณสามารถช่วยฉันปรับปรุงเล็กน้อยได้ไหม ฉันต้องการให้มุมขวาบนปัด ฉันจะบรรลุสิ่งนี้ได้อย่างไร
Barterio

1
ฉันจะเพิ่มข้อความภายในสามเหลี่ยมได้อย่างไร
Sakiboy

39

การแก้ปัญหาของ Jacek Milewskiทำงานสำหรับฉันและขึ้นอยู่กับวิธีการแก้ปัญหาของเขาถ้าคุณต้องการและสามเหลี่ยม inversed คุณสามารถใช้นี้

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

-1 วิธีนี้จะทำให้คุณไม่ได้สามเหลี่ยม eqilateral และอย่างไรก็ตามมันกำลังมีปัญหามากมายเช่น stackoverflow.com/questions/20805826/…
j_kubik


17

ใช้เวกเตอร์ที่วาดได้:

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

ป้อนคำอธิบายภาพที่นี่


การใช้Lและzในตอนท้ายแก้ไขปัญหาของฉันขอบคุณ!
oxied

11

ฉันขอช่วยคุณโดยไม่ต้องใช้ XML ได้ไหม


เพียงแค่

เค้าโครงที่กำหนดเอง (Slice):

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));
    }
}

ตัวอย่างการทำงาน:

ป้อนคำอธิบายภาพที่นี่


อีกหนึ่ง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;
}

11
+1 ใช่คุณทำได้ และขอบคุณ. มีคนอื่น ๆ นอกเหนือจาก OP ที่กำลังมองหาวิธีแก้ปัญหาที่ไม่ได้ขอ XML โดยเฉพาะ - เหมือนฉัน
johndodo

1
onDraw จะไม่ถูกเรียกบนคลาสที่มาจาก ViewGroup ไม่ใช่ค่าเริ่มต้น คุณต้องเปิดใช้งานการวาดโดย setWillNotDraw (false) หรือรับช่วงจาก View แทน
Blago

7

คุณสามารถเพิ่มสามเหลี่ยมต่อไปนี้ในพื้นหลังโดยใช้ 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) และออกแบบเค้าโครงตามความต้องการของคุณ ตรวจสอบนี้คำตอบ


6

สำหรับผู้ที่ต้องการลูกศรสามเหลี่ยมขวาไปที่นี่:

ขั้นตอนที่ 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 ของคุณสร้างดูและผูกพื้นหลังให้กับ XML drawable ที่คุณได้สร้างเพียงในขั้นตอนที่ 1 สำหรับกรณีของฉันฉันผูก v_right_arrow กับคุณสมบัติพื้นหลัง View ของฉัน

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

ตัวอย่างผลลัพธ์:

ป้อนคำอธิบายภาพที่นี่

หวังว่านี่จะช่วยได้โชคดี!


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

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

3

ฉันไม่เคยทำสิ่งนี้ แต่จากสิ่งที่ฉันเข้าใจคุณสามารถใช้คลาส PathShape: http://developer.android.com/reference/android/graphics/drawable/shapes/PathShape.html


2
วิธีใช้รูปร่างเส้นทางใน XML?
Sebastian Roth

สิ่งนี้มีประโยชน์สำหรับการค้นหาส่วนที่เหมาะสมที่จะใช้ แต่ไม่มีคำอธิบายเกี่ยวกับวิธีการใช้งานที่เพียงพอ ขอบคุณอย่างไรก็ตาม
Navarr

ขออภัย Sebastian และ Navarr ... ฉันระบุในคำตอบของฉันว่าฉันไม่เคยใช้มันดังนั้นฉันไม่แน่ใจว่าจะใช้มันอย่างไร ดูเหมือนว่าชั้นจะได้งานทำ ฉันยอมรับว่าไม่มีเอกสารเพียงพอสำหรับมัน
Justin

3
PathShape ดูเหมือนจะไม่มีไวยากรณ์ XML ที่เกี่ยวข้อง XML Shape-tag รองรับเฉพาะสี่เหลี่ยมผืนผ้าวงรีเส้นและวงแหวน developer.android.com/guide/topics/resources/…
Nilzor

3

ฉันไปปาร์ตี้ช้าและเจอปัญหาเดียวกันและ Google ก็ชี้ให้ฉันไปที่เธรด StackOverflow นี้เป็นผลลัพธ์แรก

ฉันลองใช้วิธี xml เพื่อเพิ่มสามเหลี่ยมและพบปัญหาว่ารูปทรงสามเหลี่ยมผ่านวิธี xml ใช้พื้นที่มากกว่าที่ปรากฏ

ดูภาพหน้าจอที่มีขอบเขตการจัดวาง

ป้อนคำอธิบายภาพที่นี่

ดังนั้นจึงลงเอยด้วยการสร้างคลาสมุมมองที่กำหนดเองซึ่งสามารถวาด Triangle ประเภทใดก็ได้ต่อไปนี้:

  1. ชี้ขึ้น
  2. ชี้ลง
  3. ชี้ไปทางซ้าย &
  4. ชี้ไปทางขวา

เท่า

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;
    }
}

คุณสามารถใช้มันในรูปแบบ xml เช่นนี้

 <com.hiteshsahu.materialupvote.TriangleShapeView
            android:layout_width="50dp"
            android:layout_height="50dp"></com.hiteshsahu.materialupvote.TriangleShapeView>

ฉันรู้ว่า OP ต้องการโซลูชันในโซลูชัน xml แต่เมื่อฉันชี้ให้เห็นปัญหาเกี่ยวกับวิธี xml ฉันหวังว่ามันอาจช่วยใครสักคนได้


2

การใช้วิธีแก้ปัญหาของJacek Milewskiฉันสร้างมุมที่เน้นลงโดยมีพื้นหลังโปร่งใส

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

คุณสามารถเปลี่ยนandroid:pivotXและandroid:pivotYเปลี่ยนมุมได้

การใช้งาน:

<ImageView
    android:layout_width="10dp"
    android:layout_height="10dp"
    android:src="@drawable/ic_angle_down"
    />

ป้อนคำอธิบายภาพที่นี่

พารามิเตอร์ขึ้นอยู่กับขนาดของรูปภาพ ตัวอย่างเช่นหากImageViewมีขนาด 100dp * 80dp คุณควรใช้ค่าคงที่เหล่านี้:

<rotate
    android:fromDegrees="135"
    android:pivotX="64.5%"
    android:pivotY="19%"
    android:toDegrees="135"
    >

ป้อนคำอธิบายภาพที่นี่


2

ฉันพยายามสร้างภาพสามเหลี่ยมเช่นปุ่มย้อนกลับของแถบนำทางของ Android แต่ไม่พบวิธีแก้ปัญหาใด ๆ

ตอนนี้ฉันพบวิธีแก้ปัญหาด้วยตัวเองแล้วและอยากจะแบ่งปัน

แถบนำทางรูปสามเหลี่ยม 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>


0
  <LinearLayout
        android:id="@+id/ly_fill_color_shape"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:background="@drawable/shape_triangle"
        android:gravity="center"
        android:orientation="horizontal" >
    </LinearLayout>

<item>
    <rotate
        android:fromDegrees="45"
        android:pivotX="-15%"
        android:pivotY="77%"
        android:toDegrees="45" >
        <shape android:shape="rectangle" >
            <stroke
                android:width="2dp"
                android:color="@color/black_color" />

            <solid android:color="@color/white" />

            <padding android:left="1dp" />
        </shape>
    </rotate>
</item>
<item android:top="200dp">
    <shape android:shape="line" >
        <stroke
            android:width="1dp"
            android:color="@color/black_color" />

        <solid android:color="@color/white" /> 
    </shape>
</item>


-1 วิธีนี้จะทำให้คุณไม่ได้สามเหลี่ยม eqilateral และอย่างไรก็ตามมันกำลังมีปัญหามากมายเช่นstackoverflow.com/questions/20805826/…
j_kubik

0

Google มีรูปสามเหลี่ยมด้านเท่าที่นี่
เลือก VectorDrawable เพื่อให้ขนาดมีความยืดหยุ่น
มันรวมเข้ากับ Android Studio เป็นปลั๊กอิน

หากคุณมีภาพ SVG คุณสามารถใช้สิ่งนี้เพื่อแปลงเป็น VectorDrawable ได้เช่นกัน

เมื่อคุณมี VectorDrawable แล้วการเปลี่ยนสีและการหมุนก็ทำได้ง่ายเหมือนที่คนอื่น ๆ พูดถึง


0

ฉันให้ customView ด้านล่างนี้หากคุณไม่ต้องการแฮ็ก xml โปรดได้ลอง


/**
 * 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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.