以编程方式在android上的按钮之间绘制线条

时间:2023-02-02 23:20:37

I am trying to create a tree graph based on user data. There is no library or anything to help and im just a beginner. I just created 8 image buttons and after the app calculates the data, it needs to draw lines between these nodes to connect them. I have no idea how to use canvas or drawline so any help would be much appreciated. 以编程方式在android上的按钮之间绘制线条

我正在尝试根据用户数据创建树形图。没有图书馆或任何可以帮助的东西,我只是一个初学者。我刚创建了8个图像按钮,在应用程序计算数据后,需要在这些节点之间绘制线条以连接它们。我不知道如何使用画布或画线,所以任何帮助将非常感激。

         <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_margin="20dp"
                android:id="@+id/nodesImages">

                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="1"
                        android:layout_margin="20dp"
                        android:id="@+id/node1"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="2"
                        android:id="@+id/node2"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="5"
                        android:id="@+id/node5"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="6"
                        android:id="@+id/node6"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="3"
                        android:layout_margin="20dp"
                        android:id="@+id/node3"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="4"
                        android:id="@+id/node4"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="7"
                        android:id="@+id/node7"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
                    <Button
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:text="8"
                        android:id="@+id/node8"
                        android:layout_margin="20dp"
                        android:background="@drawable/node"/>
            ![enter image description here][1]</LinearLayout>

Edit - DrawView Class

编辑 - DrawView类

How can I use this DrawView class to add the lines?

如何使用此DrawView类添加行?

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class DrawView extends View
{
    Paint paint = new Paint();
    static int startX, startY, endX, endY;

    public DrawView(Context context,int startX, int startY, int endX, int endY)
    {
        super(context);
        this.startX = startX;
        this.startY = startY;
        this.endX = endX;
        this.endY = endY;
        paint.setColor(Color.BLACK);
    }
    public DrawView(Context context)
    {
        super(context);
        paint.setColor(Color.BLACK);
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        canvas.drawLine(startX, startY, endX, endY,paint); 
    }
}

Edit 2: This is not working for some reason:

编辑2:由于某些原因,这不起作用:

LinearLayout myLayout = (LinearLayout) findViewById(R.id.nodesImages);

DrawView drawView = new DrawView(getApplicationContext(),(int)node1.getX(),(int)node1.getY(),(int)node2.getX(),(int)node2.getY());

myLayout.addView(drawView);

Edit 3

There are so many libraries for creating complex graphs (line,bar,scatter,etc) . Why can't somebody create a library for tree graphs???? seems easy for those people!!!

有很多库用于创建复杂的图形(线条,条形图,散点图等)。为什么有人不能为树形图创建一个库????对那些人来说似乎很容易!

2 个解决方案

#1


based on your provide width and height of your button in layout. I use translation to do that. See the below code and the ugly Image for explain @@!

根据您在布局中提供按钮的宽度和高度。我用翻译来做到这一点。请参阅以下代码和丑陋的图片解释@@!

LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);

View v = new View(this); //this, because I write this code in the Activity class
//yah, try to understand values 20, 30,... 
v.setLayoutParams(new ViewGroup.LayoutParams(dpToPx(20+20),dpToPx(2)));
v.setBackgroundColor(Color.BLACK);
nodesImages.addView(v);
v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
v.setTranslationX(dpToPx(20+30));

with:

private int dpToPx(int dp) {
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}

Ugly Image for explain: 以编程方式在android上的按钮之间绘制线条

丑陋的图像解释:

UPDATE get location of view:

更新获取视图的位置:

    final LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);

    //using addOnGlobalLayoutListener to make sure layout is happened.
    nodesImages.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //Remove the listener before proceeding
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    nodesImages.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    nodesImages.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                Button node1 = (Button)findViewById(R.id.node1);
                int[] loc1 = new int[2];
                node1.getLocationInWindow(loc1);//loc1[0] is x and loc1[1] is y
                //for more information about this method, in Android Studio, just right-click -> Go To -> Declaration
                Button node2 = (Button)findViewById(R.id.node2);
                int[] loc2 = new int[2];
                node2.getLocationInWindow(loc2);

                View v = new View(getApplication());
                v.setLayoutParams(new ViewGroup.LayoutParams(loc2[0]-loc1[0]-node1.getWidth(),dpToPx(2)));//dpToPx(20 + 20), dpToPx(2)));
                v.setBackgroundColor(Color.BLACK);
                nodesImages.addView(v);
                v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
                v.setTranslationX(dpToPx(20+30));
            }
        }
    );

#2


Psst... Just do it in XML

Psst ...用XML做

   <View 
        android:layout_height="1dp"
        android:layout_width="match_parent"
        android:background="@android:color/black"/>

#1


based on your provide width and height of your button in layout. I use translation to do that. See the below code and the ugly Image for explain @@!

根据您在布局中提供按钮的宽度和高度。我用翻译来做到这一点。请参阅以下代码和丑陋的图片解释@@!

LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);

View v = new View(this); //this, because I write this code in the Activity class
//yah, try to understand values 20, 30,... 
v.setLayoutParams(new ViewGroup.LayoutParams(dpToPx(20+20),dpToPx(2)));
v.setBackgroundColor(Color.BLACK);
nodesImages.addView(v);
v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
v.setTranslationX(dpToPx(20+30));

with:

private int dpToPx(int dp) {
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}

Ugly Image for explain: 以编程方式在android上的按钮之间绘制线条

丑陋的图像解释:

UPDATE get location of view:

更新获取视图的位置:

    final LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);

    //using addOnGlobalLayoutListener to make sure layout is happened.
    nodesImages.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //Remove the listener before proceeding
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    nodesImages.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    nodesImages.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                Button node1 = (Button)findViewById(R.id.node1);
                int[] loc1 = new int[2];
                node1.getLocationInWindow(loc1);//loc1[0] is x and loc1[1] is y
                //for more information about this method, in Android Studio, just right-click -> Go To -> Declaration
                Button node2 = (Button)findViewById(R.id.node2);
                int[] loc2 = new int[2];
                node2.getLocationInWindow(loc2);

                View v = new View(getApplication());
                v.setLayoutParams(new ViewGroup.LayoutParams(loc2[0]-loc1[0]-node1.getWidth(),dpToPx(2)));//dpToPx(20 + 20), dpToPx(2)));
                v.setBackgroundColor(Color.BLACK);
                nodesImages.addView(v);
                v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
                v.setTranslationX(dpToPx(20+30));
            }
        }
    );

#2


Psst... Just do it in XML

Psst ...用XML做

   <View 
        android:layout_height="1dp"
        android:layout_width="match_parent"
        android:background="@android:color/black"/>