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.
Related
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"/>
I'm trying to add a SurfaceView to the background of my main activity to draw some funky images that'll wander about. (mainly used for a screensaver as our screens are on all the time). I've set it all out and setup the drawing thread and it run really well... But, the SurfaceView refuses to draw anything at all?!
As per this SO thread I've set .setWillNotDraw(false); but still no change!
I then thought maybe it's the image I was using, so got a completely random one from the app and tried with that, but still nothing.. So then I tried just drawing a 32x32 yellow rectangle...Nothing :(
Any help is very much appreciated, as I'm clearly missing something.
LogCat states that:
11-27 16:20:26.854 8801-8869/com.goosesys.gaggle I/FLOAT﹕ Drawing f=176/194
11-27 16:20:26.854 8801-8869/com.goosesys.gaggle I/FLOAT﹕ Drawing f=342/759
etc ... etc ...
Here's some code:
protected void drawFloaters(Canvas canvas){
canvas.drawColor(Color.BLACK, Mode.MULTIPLY);
for(Floater f : mIcons) {
canvas.drawBitmap(f.getImage(), f.getX(), f.getY(), null);
canvas.drawRect(f.getX(), f.getY(), 32, 32, new Paint(Color.YELLOW));
//canvas.drawBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_photo), 100, 100, null);
Log.i("FLOAT", "Drawing f=" + f.getX() + "/" + f.getY());
}
}
}
class Floater {
private int x = 0;
private int y = 0;
private Bitmap mImage;
private Context mContext;
public Floater(Bitmap img, Context c){
mImage = img;
this.x = getRandomX();
this.y = getRandomY();
mContext = c;
}
public Floater(Bitmap img, int x, int y, Context c){
mImage = img;
this.x = x;
this.y = y;
mContext = c;
}
public int getX() { return x; }
public void setX(int x) { this.x = x; }
public int getY() { return y; }
public void setY(int y) { this.y = y; }
public Bitmap getImage(){ return mImage; }
private int getRandomX(){
return new Random().nextInt(400);
}
private int getRandomY(){
return new Random().nextInt(800);
}
}
And my Screensaver thread
public class ScreensaverThread extends Thread {
private GaggleSurfaceView mSurface = null;
private boolean mRunning = false;
public ScreensaverThread(GaggleSurfaceView sv){
mSurface = sv;
}
public void setRunning(boolean run){
mRunning = run;
}
#Override
public void run(){
while(mRunning){
Canvas canvas = mSurface.getHolder().lockCanvas();
if(canvas != null){
synchronized(mSurface.getHolder()){
mSurface.drawFloaters(canvas);
}
mSurface.getHolder().unlockCanvasAndPost(canvas);
}
try{
sleep(30);
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
The main activity XML
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<view
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.goosesys.gaggle.screensaver.GaggleSurfaceView"
android:id="#+id/view"
android:background="#color/Black" />
</FrameLayout>
<TextView
android:id="#+id/txtForShort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/txtFriendlyName"
android:layout_below="#+id/txtFriendlyName"
android:text="#string/orinoco_for_short"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
<ImageView
android:id="#+id/imgBubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:maxHeight="128dp"
android:maxWidth="128dp"
android:src="#drawable/orinoco_bubble" />
<TextView
android:id="#+id/txtDesignatedId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtOrinocoHeader"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="#string/orinoco_id_placeholder"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Orange" />
<TextView
android:id="#+id/txtOr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtDesignatedId"
android:layout_centerHorizontal="true"
android:text="#string/orinoco_or"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
<TextView
android:id="#+id/txtFriendlyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtOr"
android:layout_centerHorizontal="true"
android:text="#string/orinoco_friendly_name_placeholder"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Orange" />
<TextView
android:id="#+id/txtAssignedTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtForShort"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="#string/orinoco_assigned_header"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="26sp"
android:textStyle="bold" />
<TextView
android:id="#+id/txtAssignedDriver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtAssignedTo"
android:layout_centerHorizontal="true"
android:text="#string/orinoco_assigned_driver_placeholder"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Orange"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="#+id/txtOrinocoHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imgBubble"
android:layout_centerHorizontal="true"
android:gravity="center_vertical|center_horizontal"
android:text="#string/orinoco_greeting"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold"
android:typeface="normal" />
<Button
android:id="#+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_login"
android:textStyle="bold"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/btnTrainingMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/orinoco_training_button"
android:textColor="#color/green"
android:textStyle="bold|italic"
android:visibility="invisible"
android:layout_above="#+id/btnLogin"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:id="#+id/txtVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imgBubble"
android:layout_alignRight="#+id/txtAssignedTo"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
The first thing to try when you can't see anything at all is to just fill the entire surface with a single obvious color (e.g. red). That way, if any part of the surface is visible, you'll see it.
For a SurfaceView, the next thing to try is to move the surface from being behind everything, to being in front of everything, by calling setZOrderOnTop(true) from the point where the SurfaceView object is created. That way if your drawing code is doing anything you'll see the surface on top of the UI.
The third thing to try is to get rid of android:background="#color/Black", which is probably the source of your trouble. SurfaceViews have two parts, the View and the Surface. The Surface part is a separate layer that sits behind everything else; the View part is supposed to be a place-holder that the layout code uses to provide a transparent "window" to the surface behind, but you've made it opaque, so nothing can show through.
I have a Relative layout with title centered and cancel button right aligned.
I want to check if the title overlaps with the cancel button and if so, i will have shift the title left based of how much it overlaps.
This is how my xml looks:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.app.mobile"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="#dimen/actionBarHeight"
android:layout_alignParentTop="true"
android:id="#+id/actionbar"
android:background="#F8F8F8">
<com.app.mobile.subview.CustomButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/cancel_btn"
android:text="Cancel"
app:typeface="fonts/HelveticaNeue"
app:customStyle="Regular"
android:textSize="#dimen/titleTextSize"
android:textColor="#378BFB"
android:background="#android:color/transparent"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:visibility="gone"/>
<com.app.mobile.subview.CustomButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/share_btn"
app:typeface="fonts/HelveticaNeue"
app:customStyle="Regular"
android:textColor="#378BFB"
android:visibility="gone"/>
<com.app.mobile.subview.CustomTextView
android:id="#+id/title"
android:gravity="center"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface="fonts/HelveticaNeue"
app:customStyle="Medium"
android:textSize="#dimen/titleTextSize"
android:textColor="#000"
android:text="Test Title"/>
</RelativeLayout>
And I'm trying to get the positions like below
float xPos = screenTitle.getX();
float titleEnd = xPos + screenTitle.getWidth();
xPos = cancelButton.getX();
if(titleEnd > xPos){
Log.e("Title","Title overlaps cancel button");
}
cancelButton.getX() is returning me 0.0 whereas title is returning correct value.
1.This is how the layout is with small title
http://i.stack.imgur.com/3TFdg.jpg
it depends on where in your Java code you're attempting to get the value of getX()
If Android has not already completed drawing the entire layout, cancelButton has not been drawn and the X is 0.0.
I've found that getting the value in onCreate() or onCreateView() is very easy with a post and runnable
cancelButton.post( new Runnable() {
#Override
public void run() {
float x = cancelButton.getX();
}
});
this ensures the button has been fully drawn before you attempt to use the value
I have the following picture and I want create layout like it, and I need in place of the rectangles to put EditText views. But I can't figure out which is the best way I can achieve this layout, should I make background of the lines or I make relative layout and try align things?
So if someone is experienced with such layouts, please tell how can I do this.
Thanks in advance.
Looking at that image, it looks like you are trying to cram a lot of EditText's into a single screen. That's a pretty unusual layout... unless your application has a very, very specific use case in mind where another layout is inadmissible, I'd advise you to try using one of the more "standard" layouts in Android, as that will likely enhance usability.
However, if you decide that that's really what you need, then I'd take a look at GridLayout, where the rightmost component is expandable and contains a LinearLayout or something like that.
That layout is relatively simple to make, it will be a lot more work to make it work across the large number of Android devices. For example:
<?xml version="1.0" encoding="utf-8"?>
<com.luksprog.ds.views.RelativeLayoutExtension xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/et10"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="X" />
<EditText
android:id="#+id/et9"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_above="#id/et10"
android:layout_marginBottom="25dp"
android:layout_toLeftOf="#id/et10"
android:text="9" />
<EditText
android:id="#+id/et8"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_below="#id/et10"
android:layout_marginTop="25dp"
android:layout_toLeftOf="#id/et10"
android:text="8" />
<EditText
android:id="#+id/et7"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="40dp"
android:layout_toLeftOf="#id/et9"
android:text="7" />
<LinearLayout
android:id="#+id/et65wrapper"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/et7"
android:orientation="vertical"
android:paddingLeft="10dp" >
<EditText
android:id="#+id/et6"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="6" />
<EditText
android:id="#+id/et5"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="5" />
</LinearLayout>
<LinearLayout
android:id="#+id/et43wrapper"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/et65wrapper"
android:orientation="vertical"
android:paddingLeft="10dp" >
<EditText
android:id="#+id/et4"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="4" />
<EditText
android:id="#+id/et3"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="3" />
</LinearLayout>
<LinearLayout
android:id="#+id/et21wrapper"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/et43wrapper"
android:orientation="vertical"
android:paddingLeft="10dp" >
<EditText
android:id="#+id/et2"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="2" />
<EditText
android:id="#+id/et1"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="1" />
</LinearLayout>
</com.luksprog.ds.views.RelativeLayoutExtension>
Where the RelativeLayoutExtension is a class extending the RelativeLayout class like this:
public class RelativeLayoutExtension extends RelativeLayout {
private LinearLayout mFirstLinear;
private LinearLayout mSecondLinear;
private LinearLayout mLastLinear;
private EditText mUpperEditText;
private EditText mLowerEditText;
private Paint mPaint;
public RelativeLayoutExtension(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(2.0f);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
mFirstLinear = (LinearLayout) findViewById(R.id.et21wrapper);
mSecondLinear = (LinearLayout) findViewById(R.id.et43wrapper);
mLastLinear = (LinearLayout) findViewById(R.id.et65wrapper);
mUpperEditText = (EditText) findViewById(R.id.et9);
mLowerEditText = (EditText) findViewById(R.id.et8);
}
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
final int leftFirst = mFirstLinear.getLeft();
final int topFirst = mFirstLinear.getTop();
final int middleFirst = (mFirstLinear.getBottom() - mFirstLinear
.getTop()) / 2;
final int lastRight = mLastLinear.getRight();
canvas.drawLine(leftFirst, topFirst + middleFirst, lastRight, topFirst
+ middleFirst, mPaint);
final int rightFirst = mFirstLinear.getRight();
final int bottomFirst = mFirstLinear.getBottom();
canvas.drawLine(rightFirst, topFirst, rightFirst, bottomFirst, mPaint);
final int rightSecond = mSecondLinear.getRight();
canvas.drawLine(rightSecond, topFirst, rightSecond, bottomFirst, mPaint);
final int leftUpperEdit = mUpperEditText.getLeft();
final int topUpperEdit = mUpperEditText.getTop();
final int middleUpperEdit = (mUpperEditText.getBottom() - mUpperEditText
.getTop()) / 2;
canvas.drawLine(lastRight, topFirst + middleFirst, leftUpperEdit,
topUpperEdit + middleUpperEdit, mPaint);
final int leftLowerEdit = mLowerEditText.getLeft();
final int topLowerEdit = mLowerEditText.getTop();
final int middleLowerEdit = (mLowerEditText.getBottom() - mLowerEditText
.getTop()) / 2;
canvas.drawLine(lastRight, topFirst + middleFirst, leftLowerEdit, topLowerEdit
+ middleLowerEdit, mPaint);
}
}
The lines aren't quite centered, it was just an example.
If you plan to use this layout on a single device for which you know its dimensions the layout will work as you only need to calculate the dimensions once outside of the code. If you plan this as a general layout things will get pretty ugly because you'll need to make a lot of calculations to properly position the views and draw the lines so you may want to rethink your approach. Also I hope that you want to use this layout on large screen devices, because cramming six EditTexts along with spaces on a portrait smartphone will not work pretty well.
You can create it with standard layouts.
The main layout is a FrameLayout.
The background is a image with some lines (or shapes to display lines).
The active layout is a RelativeLayout to show all rectangles.
I'm writing a program that is supposed to draw a line in a canvas at the bottom of the screen below a button, etc. My layout shows up, but the line doesn't. Anyone know why my canvas doesn't show up?
Here is the code:
public class Vectors extends Activity{
VectorsView vectorsView;
LinearLayout l;
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.vectors);
vectorsView = new VectorsView(this);
l = (LinearLayout) findViewById(R.id.llCanvasV);
l.addView(vectorsView);
.......
}
public class VectorsView extends View{
public VectorsView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawLine(0, 0, 100, 100, paint);
vectorsView.draw(canvas);
vectorsView.setLayoutParams(new LayoutParams(25, 25));
}
}
Here is the xml:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background"
android:orientation="vertical">
<ImageView android:layout_height="wrap_content"
android:src="#drawable/vectors"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:adjustViewBounds="true">
</ImageView>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">
<Button android:text="Choose Program"
android:id="#+id/bChsProgV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="97dp"
android:adjustViewBounds="true">
</Button>
<ImageButton android:layout_height="wrap_content"
android:src="#drawable/help"
android:id="#+id/ibHelpV"
android:layout_width="wrap_content"
android:layout_marginLeft="65dp"
android:background="#null"
android:layout_marginTop="10dp">
</ImageButton>
</LinearLayout>
<LinearLayout android:id="#+id/llCanvasV"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</LinearLayout>
</LinearLayout>
onMeasure method missing in VectorsView class. and also you can add VectorsView from Layout by keeping the complete package <package.VectorsView android:id= android:width= android:height= ></package.VectorsView>