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.
我正在尝试根据用户数据创建树形图。没有图书馆或任何可以帮助的东西,我只是一个初学者。我刚创建了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:
丑陋的图像解释:
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:
丑陋的图像解释:
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"/>