Programmatically draw lines between buttons on android - android

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.
<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
How can I use this DrawView class to add the lines?
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:
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!!!

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

Psst... Just do it in XML
<View
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#android:color/black"/>

Related

Android make canvas cover half screen

I'm trying to create an app for drawing some simple lines in a canvas. I want the canvas to take up the top 50% of the screen, leaving the bottom 50% of the screen for buttons and what not. I am currently using setContentView(canvas); which makes it so that the canvas takes up 100% of the screen.
You can create a class that extends View and do drawing inside that view on onDraw() method of that view. Add that view to your layout with any width or height you choose.
Instead of setContentView, use your layout XML to create a view to hold the canvas as shown in Error referencing an inner class View in layout/main.xml.
After that, it's a matter of using a technique in android:layout_height 50% of the screen size such as:
<LinearLayout ...>
<view
class="com.example.foo.FooActivity$Drawer"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
</LinearLayout>
You can also use, say, android:layout_weight="0.7" and "0.3" to set the canvas/button container to 70% and 30% of the screen respectively.
Here's a minimal, complete example:
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#f00"
>
<view
class="com.example.foo.FooActivity$Drawer"
android:background="#00f"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
<Button
android:id="#+id/start"
android:text="#string/start"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
<Button
android:id="#+id/stop"
android:text="#string/stop"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
</LinearLayout>
</LinearLayout>
Activity:
package com.example.foo;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
public class FooActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foo);
}
public static class Drawer extends View {
private static Paint paint;
private static int viewWidth;
private static int viewHeight;
public Drawer(Context con, AttributeSet attr) {
super(con, attr);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
}
// https://stackoverflow.com/a/9718512/6243352
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
protected void onDraw(final Canvas c) {
super.onDraw(c);
paint.setARGB(255, 0, 0, 0);
int cx = viewWidth / 2;
int cy = viewHeight / 2;
c.drawCircle(cx, cy,viewWidth / 4, paint);
}
}
}
Result:

Custom View not giving margin

I am working on an activity where I created a custom view that I am adding dynamically within a LinearLayout. The problem is that I am unable to give margin between the custom views I add.
Here is a look at the two views I added which are next to each other.
Screentshot:
Code for creating the views dynamically:
private void AddSelectedTagUI(final com.main.feedify.serializers.Tags tag){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.tags,tags_section_selectedtags,false);
TextView tagName = (TextView)v.findViewById(R.id.customview_tags_name);
tagName.setText(tag.getTagName());
ImageView close_button = (ImageView)v.findViewById(R.id.customview_tags_close);
close_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RemoveTag(tag.getTagID(), selectedTags);
}
});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
tags_section_selectedtags.addView(v, params);
// cast view to tags and add it in our layout.
// this will help us find out the tag we wanna delete.
view_selectedTags.add(v);
this.UpdateMessage(true);
}
tags.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:padding="5dp"
android:id="#+id/custom_tag"
>
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp"
/>
</RelativeLayout>
activity_tags.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background">
<TextView
android:id="#+id/tags_lbl_taginfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Add at least 4 favorite topics"
android:layout_marginTop="20dp"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_below="#+id/tags_lbl_taginfo"
android:layout_width="match_parent"
android:layout_height="190dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:id="#+id/tags_section_selectedtags">
</LinearLayout>
<EditText
android:id="#+id/tags_txt_tags"
android:layout_below="#+id/tags_section_selectedtags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:hint="Add tags ..."
android:textColor="#color/tags_edittext"
android:paddingTop="15dp"
android:singleLine="true"
android:paddingLeft="9dp"
android:paddingBottom="15dp"
android:background="#drawable/tags_edittext"
/>
<TextView
android:id="#+id/tags_lbl_tagsuggestion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Suggestions"
android:layout_marginTop="15dp"
android:layout_below="#id/tags_txt_tags"
/>
</RelativeLayout>
Custom Tags Class:
package com.main.feedify.custom_views;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.main.feedify.feedify_mockup.R;
import com.tokenautocomplete.TokenCompleteTextView;
/**
* Created by Muazzam on 10/17/2015.
*/
public class Tags extends RelativeLayout{
private com.main.feedify.serializers.Tags tag;
public Tags(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.tags,this);
}
public void setTag(com.main.feedify.serializers.Tags t){
this.tag = t;
}
public com.main.feedify.serializers.Tags getTag(){
return this.tag;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
}
You are setting margins in Pixels. Try converting them into dp, so that the margins value becomes independent of display density.
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = pxToDp(5);
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
private int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
EDIT:
Get rid of the margin code in onLayout() and set those margins, when you are puting this view inside a viewgroup like LinearLayout or RelativeLayout etc.
You should try setting the layout_margin to your RelativeLayoutin your XML file, same as you did with the padding.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:layout_margin="5dp"
android:padding="5dp"
android:id="#+id/custom_tag">
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp" />
</RelativeLayout>
You should add left margin to view while adding it.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//add this line
params.leftMargin=50;
//end
tags_section_selectedtags.addView(v, params);
I think that the problem lays in this piece of code:
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
Here you change the layout parameters inside the onLayout() method and it should lead to the infinite layout of your view: custom view's parent view calls onLayout() which calls setLayoutParams() which results in onLayout()... And so it goes.
One way to prevent this behavior is to add your margins in tags.xml file, just like you did with the paddings. The infinite layout loop will be gone and your view will have a chance to set its margins.
I have designed a view dynamically and have given parameters such like yours, have a look at this code:
https://stackoverflow.com/a/33339420/5479863
and to convert into dp from pixel use this method
private int getPixelsToDP(int dp) {
float scale = getResources().getDisplayMetrics().density;
int pixels = (int) (dp * scale + 0.5f);
return pixels;
}

Scrolling the custom views - Android

Below is the image of the menu I need to make.
I have drawn the triangles using canvas in custom views. I also need to scroll this menu, when custom views are added in the scroll view it takes each View as a rectangular item not allowing the triangles to be drawn like this.
Is there anyway to achieve this?
Thanks in advance.
At first you must create 2 custom views, with different draws of triangles. Then in your RelativeLayout or another create those triangles and set the, negative margin_top value for correct presentation, like in my example:
So, now lets look at code.
Dont critic my code. It`s just example for you without true OOP structure :)
CustomShapeLeft.class:
/**
* Created by gigamole on 07.02.15.
*/
public class CustomShapeLeft extends RelativeLayout {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
int backgroundColor;
int viewWidth; // width of parent(CustomShape layout)
int viewHeight;
public CustomShapeLeft(Context context) {
super(context);
this.setWillNotDraw(false);
}
public CustomShapeLeft(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWillNotDraw(false);
TypedArray ta = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.background});
this.backgroundColor = ((ColorDrawable) ta.getDrawable(0)).getColor();
this.setBackgroundColor(Color.TRANSPARENT);
}
public CustomShapeLeft(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setWillNotDraw(false);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Path path = new Path();
Point[] points = new Point[3];
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(backgroundColor);
paint.setStyle(Paint.Style.FILL);
points[0] = new Point(0, 0);
points[1] = new Point(viewWidth, (viewHeight / 2));
points[2] = new Point(0, (viewHeight));
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(points[0].x, points[0].y);
path.lineTo(points[1].x, points[1].y);
path.lineTo(points[2].x, points[2].y);
path.close();
canvas.drawPath(path, paint);
}
public boolean isTouched(final float X, final float Y){
final Polygon p = new Polygon(points);
return p.contains(X, Y);
}
}
Method isTouched() need for know when the user tap on shape, but not on View, cause when on last, its problematic to take correct action, cause they lay down like layer-layer-layer system.
This method get the position of tap and calculate is on shape or not. In your way you will dont have onClickListener, just onTouchListener.
CustomShapeRight.class:
They are almost similar, but different draw methods:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(backgroundColor);
paint.setStyle(Paint.Style.FILL);
points[0] = new Point(viewWidth, 0);
points[1] = new Point(0, (viewHeight / 2));
points[2] = new Point(viewWidth, (viewHeight));
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(points[0].x, points[0].y);
path.lineTo(points[1].x, points[1].y);
path.lineTo(points[2].x, points[2].y);
path.close();
canvas.drawPath(path, paint);
}
Layout.xml:
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_1"
android:background="#android:color/holo_red_dark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="MEN"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_2"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_orange_dark"
android:layout_below="#+id/triangle_1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="HOME"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_3"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_purple"
android:layout_below="#+id/triangle_2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="WOMEN"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_4"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_green_dark"
android:layout_below="#+id/triangle_3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="ART"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_5"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_blue_dark"
android:layout_below="#+id/triangle_4">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="KIDS"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_6"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_blue_bright"
android:layout_below="#+id/triangle_5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="MUSIC"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
And in activity set them onTouchListener():
CustomShapeRight customShapeRight = (CustomShapeRight) findViewById(R.id.triangle_6);
customShapeRight.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (((CustomShapeRight)v).isTouched(event.getX(), event.getY())) {
Toast.makeText(getApplicationContext(), ((TextView)((CustomShapeRight) v).getChildAt(0)).getText(), Toast.LENGTH_SHORT).show();
}
return false;
}
});
And all. I`d hope this will help you and with delete items "X" item in your layout you will deal with it alone. And thanks for cool question. Like it.

Drawing lines between views in a TableLayout

Firstly - sorry if you saw my other question which I deleted. My question was flawed. Here is a better version
If I have two views, how do I draw a (straight) line between them when one of them is touched? The line needs to be dynamic so it can follow the finger until it reaches the second view where it "locks on". So, when view1 is touched a straight line is drawn which then follows the finger until it reaches view2.
I created a LineView class that extends view, but I don't how to proceed. I read some tutorials but none show how to do this. I think I need to get the coordinates of both view, and then create a path which "updates" on MotionEvent. I can get the coordinates and the ids of the views I want to draw a line between, but the line that I try to draw between them either goes above it, or the line does not reach past the width and height of the view.
Any advice/code/clarity would be much appreciated!
Here is some code:
My layout. I want to draw a line between two views contained in theTableLayout.#
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_game_relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TableLayout
android:layout_marginTop="35dp"
android:layout_marginBottom="35dp"
android:id="#+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<TableRow
android:id="#+id/table_row_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip" >
<com.example.view.DotView
android:id="#+id/game_dot_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<com.example.view.DotView
android:id="#+id/game_dot_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<com.example.view.DotView
android:id="#+id/game_dot_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
</TableRow>
<TableRow
android:id="#+id/table_row_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip" >
<com.example.view.DotView
android:id="#+id/game_dot_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<com.example.view.DotView
android:id="#+id/game_dot_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<com.example.dotte.DotView
android:id="#+id/game_dot_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
</TableRow>
</TableLayout>
</RelativeLayout>
This is my LineView class. I use this to try and draw the actual line between the points.
public class LineView extends View {
Paint paint = new Paint();
float startingX, startingY, endingX, endingY;
public LineView(Context context) {
super(context);
// TODO Auto-generated constructor stub
paint.setColor(Color.BLACK);
paint.setStrokeWidth(10);
}
public void setPoints(float startX, float startY, float endX, float endY) {
startingX = startX;
startingY = startY;
endingX = endX;
endingY = endY;
invalidate();
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(startingX, startingY, endingX, endingY, paint);
}
}
And this is my Activity.
public class Game extends Activity {
DotView dv1, dv2, dv3, dv4, dv5, dv6, dv7;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LOW_PROFILE);
findDotIds();
RelativeLayout rl = (RelativeLayout) findViewById(R.id.activity_game_relative_layout);
LineView lv = new LineView(this);
lv.setPoints(dv1.getLeft(), dv1.getTop(), dv7.getLeft(), dv7.getTop());
rl.addView(lv);
// TODO: Get the coordinates of all the dots in the TableLayout. Use view tree observer.
}
private void findDotIds() {
// TODO Auto-generated method stub
dv1 = (DotView) findViewById(R.id.game_dot_1);
dv2 = (DotView) findViewById(R.id.game_dot_2);
dv3 = (DotView) findViewById(R.id.game_dot_3);
dv4 = (DotView) findViewById(R.id.game_dot_4);
dv5 = (DotView) findViewById(R.id.game_dot_5);
dv6 = (DotView) findViewById(R.id.game_dot_6);
dv7 = (DotView) findViewById(R.id.game_dot_7);
}
}
The views I want to draw lines between are in the TableLayout.
So the following process you would like to take would be to recognise when a user puts a finger down, Motion_Event.ACTION_DOWN, moves along the screen Motion_Event.ACTION_MOVE and lifts there finger up Motion_Event.ACTION_MOVE.
For more information on the above see the accepted answer here
What you want to do is if in Motion_Event.ACTION_DOWN the user is inside a view (see here for more info) start drawing a line.
Then in Motion_Event.ACTION_MOVE carry on drawing the line until they stop.
In Motion_Event.ACTION_UP if they are in another view do what you gotta do. If they arent then you erase the line and pretend it never happened.

Drawing a new view into a relative layout

We are writing a "dashboard" for a car. The code for calculating/drawing the speedometer was done separate from the rest of the code, and now I am trying to combine the two.
They both work separately, and with the speedometer view code in, the main portion of the UI is still functioning, I just can't see the speedometer.
I have it compiling, and there are no obvious errors. However, when the app is run, I don't see the speedometer showing up in the main view, even though I have added it using the addView method.
For Reference:
My code to create and add the view:
setContentView(R.layout.main);
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.RelativeLayout1);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.CENTER_VERTICAL);
myView v = new myView(this);
v.setLayoutParams(lp);
relativeLayout.addView(v, lp);
The code for the myView class:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.view.View;
public class myView extends View {
private Paint mPaints;
private Paint textpaint;
private boolean mUseCenters;
private RectF mBigOval;
private float mStart;
private float mSweep;
public float SPEED_raw;
public int SPEED = 0; //initialized to 0 just for loop. Remove initialization when IF statement below is deleted
public static Bitmap gaugefront;
public static Bitmap gaugeback;
public myView(Context context) {
super(context);
mPaints = new Paint();
mPaints.setAntiAlias(true);
mPaints.setColor(Color.YELLOW);
textpaint = new Paint();
textpaint.setAntiAlias(true);
textpaint.setColor(Color.WHITE);
textpaint.setTextSize(150);
textpaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
gaugefront = BitmapFactory.decodeResource(context.getResources(),R.drawable.gaugefront); //Load gaugefront.png
gaugeback = BitmapFactory.decodeResource(context.getResources(),R.drawable.gaugeback); //Load gaugeback.png
mUseCenters = true;
mBigOval = new RectF(400, 10, 880, 490); //left[x-coordinate],top[y-coordinate],right[x],bottom[y]
}
private void drawArcs(Canvas canvas, RectF oval, boolean useCenter, Paint paint) {
canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(myView.gaugeback, 400, 10, null); //draw gauge background, X coordinate:400, Y coordinate: 10
drawArcs(canvas, mBigOval, mUseCenters, mPaints);
//SPEED_raw = 70; //Raw float data from CCS. Uncomment when the IF statement below is deleted.
SPEED = Math.round(SPEED_raw); //SPEED integer. Units km/h - Top speed of 135. Used for digital readout
mStart = 90; //Start drawing from -90 degrees (Counter clockwise)
mSweep = SPEED_raw*2; //Draw stop point
if(SPEED >= 135){ //JUST FOR SHOW. Delete this for actual speedo
SPEED_raw = 0; // "
} // "
else // "
SPEED_raw += 0.5; // "
canvas.drawBitmap(myView.gaugefront, 400, 10, null); //draw gauge foreground, X coordinate:400, Y coordinate: 10
String speed_string = String.valueOf(SPEED); //Convert int SPEED to String for display
// while (speed_string.endsWith(".0") || speed_string.endsWith(".")){ //Erase trailing ".0" for float types. Don't need if SPEED is an int
// speed_string = (speed_string.substring(0, speed_string.length() - 1));
// }
canvas.drawText(speed_string, 640, 420, textpaint); //arguments: (string, x-coordinate, y-coordinate, paint)
invalidate();
}
}
Here's my XML File:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:keepScreenOn="true"
android:orientation="vertical" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/solarbg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/solarbg" />
</LinearLayout>
<ImageView
android:id="#+id/l_lamp"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_gravity="left"
android:src="#drawable/l_arrow_dim" />
<DigitalClock
android:id="#+id/digitalClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="50dp" />
<ImageView
android:id="#+id/r_lamp"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/r_arrow_dim" />
<TextView
android:id="#+id/setAmps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:gravity="left"
android:text="#string/setAmps"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/setAmpsVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_below = "#+id/setAmps"
android:layout_alignParentLeft="true"
android:maxEms = "5"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/setVelocity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/setAmps"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="right"
android:text="#string/setVelocity"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/setVelocityVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_below = "#+id/setVelocity"
android:layout_alignParentRight="true"
android:maxEms = "5"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/actVelocity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/setVelocityVal"
android:gravity="right"
android:text="#string/actVelocity"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/actVelocityVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below = "#+id/actVelocity"
android:layout_alignParentRight="true"
android:gravity="right"
android:maxEms = "5"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/busAmps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/setAmpsVal"
android:gravity="left"
android:text="#string/busAmps"
android:textColor="#ffffff"
android:textSize="30dp" /><TextView
android:id="#+id/busAmpsVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_below = "#+id/busAmps"
android:maxEms = "5"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/powerVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom = "true"
android:gravity="right"
android:textColor="#ffffff"
android:textSize="30dp" />
<TextView
android:id="#+id/power"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_above = "#+id/powerVal"
android:gravity="left"
android:text="#string/power"
android:textColor="#ffffff"
android:textSize="30dp" />
<TableLayout
android:id="#+id/msgCenterLayout"
android:layout_width="600dp"
android:layout_height="200dp"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:orientation = "vertical"
android:visibility = "invisible">
<ScrollView
android:id="#+id/messageCenterText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:text="#string/busAmps"
android:textColor="#ffffff"
android:textSize="30dp" />
</TableLayout>
</RelativeLayout>
edit:
I'm using an XML file for the main layout, and trying to add this new view to a relativelayout inside that XML file.
Try writing
LayoutParams p = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.FILL_PARENT);
v.setLayoutParams(lp);
relativeLayout.addView(v);

Categories

Resources