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.
Related
I have a strange problem I'm creating a canvas drawing app in Android that has lots of buttons in xml file. The problems is when I draw a circle with all those buttons included in the file it's never a smooth circle it's full of corners like hexagon shape but when I exclude buttons may be leaving in one or two, it draws a perfect smooth circle. I have tried to split the file into three so I've included them using but still same result. Can someone please enlighten me what am I do wrong.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--First Draw -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/nav_one"
android:layout_width="30dp"
android:layout_height="60dp"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"
android:background="#drawable/ic_tab_res_bkg"/>
<ImageButton
android:id="#+id/nav_two"
android:layout_width="30dp"
android:layout_height="60dp"
android:layout_marginTop="200dp"
android:background="#drawable/ic_tab_tools_bkg"/>
</LinearLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/resource_bank"
android:layout_width="350dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/background_light"
android:dividerHeight="0dp"
android:background="#f4f1f1"
/>
<ListView android:id="#+id/tools"
android:layout_width="350dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:choiceMode="singleChoice"
android:divider="#android:color/background_light"
android:dividerHeight="0dp"
android:background="#dedada"/>
</android.support.v4.widget.DrawerLayout>
<RelativeLayout
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" >
<xxxxx.xxxxxx.xxxx.xxxxxx.DrawView
android:id="#+id/canvas_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/canvas_view">
<!-- Pen icons -->
<include layout="#layout/activity_pen_color" android:id="#+id/pen_color" />
<include layout="#layout/activity_pen_style" android:id="#+id/pen_style" />
<!-- Navigation bar icons -->
<ImageView
android:id="#+id/icon_bar"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_gravity="bottom"
android:background="#drawable/icon_bar_bkg"
/>
<Button
android:id="#+id/ic_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="150dp"
android:layout_marginTop="60dp"
android:elevation="1dp"
android:background="#drawable/ic_select_bkg"/>
<TextView
android:id="#+id/text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:layout_marginTop="90dp"
android:text="Select"
android:textColor="#color/colorAccent"
/>
<Button
android:id="#+id/ic_pens"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="200dp"
android:layout_marginTop="60dp"
android:elevation="1dp"
android:background="#drawable/ic_pen_bkg"/>
<TextView
android:id="#+id/text_pens"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="200dp"
android:layout_marginTop="90dp"
android:text="Pen"
android:textColor="#color/colorAccent"
/>
</FrameLayout>
</RelativeLayout>
My DrawView
public class DrawView extends View {
private Paint drawPaint, canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private SparseArray<Path> paths;
public DrawView(Context context) {
super(context);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupDrawing();
}
private void setupDrawing() {
paths = new SparseArray<>();
drawPaint = new Paint();
drawPaint.setColor(Color.BLACK);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(9);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
for (int i=0; i<paths.size(); i++) {
canvas.drawPath(paths.valueAt(i), drawPaint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int id = event.getPointerId(index);
Path path;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
path = new Path();
path.moveTo(event.getX(index), event.getY(index));
paths.put(id, path);
break;
case MotionEvent.ACTION_MOVE:
for (int i=0; i<event.getPointerCount(); i++) {
id = event.getPointerId(i);
path = paths.get(id);
if (path != null) path.lineTo(event.getX(i), event.getY(i));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
path = paths.get(id);
if (path != null) {
drawCanvas.drawPath(path, drawPaint);
paths.remove(id);
}
break;
default:
return false;
}
invalidate();
return true;
}
/**
* change path color here
*/
public void setPathColor(int color) {
drawPaint.setColor(color);
}
}
Answer
I take it that you are drawing this circle with your finger, and that when a lot of extra buttons are present, you notice that the lines you draw with your finger become "less smooth".
This is related to the app's screen refresh rate. When your app has to spend lots of time drawing all those extra buttons, it has fewer opportunities to get MotionEvents. With fewer MotionEvents, there are fewer points in your shape, and it takes longer line segments to connect them.
Suggested fix
The recommended approach is to stop those button views from being invalidated (an assumption on my part) every time onTouchEvent() gets called. From your code, I can't immediately see why they would be invalidated, but it may be that your DrawView underlies the buttons you are adding, thus whenever the DrawView is invalidate()-ed, the system must re-compose it with the buttons. You could move the DrawView so that it's by itself. Adding an opaque background to your button container(s) may help as well, b/c the system would have to do fewer alpha calculations.
You must have a lot of buttons... you may want to do some performance profiling to determine exactly what's taking so long.
I am making a simple LED colour control app which sends data over bluetooth to an arduino which then controls an LED strip.
I am trying to implement a colour wheel, then use getPixel to pick a colour to send to the arduino. I am having lots of issues getting the bitmap to draw correctly and work. I am testing using the Android Studio preview and using my phone (HTC U11) to test on hardware.
I cannot get this image to draw correctly. Here is my canvas.
package com.example.buledin.ledstripcontrolapp;
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.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
//we must extend View for simplicity
public class DrawableCanvas extends View {
static Canvas c;
private Paint BlueEdgePaint = new Paint();
private Paint BlackEdgePaint = new Paint();
ColourPoint point;
private Bitmap colourWheelB;
Rect rect;
public DrawableCanvas(Context context) {
super(context);
init(null, null, 0);
this.setWillNotDraw(false);
}
public DrawableCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public DrawableCanvas(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, 0);
}
// This is the initialisation routine.
private void init(Context context, AttributeSet attrs, int defStyle) {
BlueEdgePaint.setColor(Color.BLUE);
BlueEdgePaint.setStrokeWidth(4);
BlueEdgePaint.setStyle(Paint.Style.STROKE);
BlueEdgePaint.setAntiAlias(true);
BlackEdgePaint.setColor(Color.BLACK);
BlackEdgePaint.setStrokeWidth(2);
BlackEdgePaint.setStyle(Paint.Style.STROKE);
BlackEdgePaint.setAntiAlias(true);
// colourWheel = getResources().getDrawable(R.drawable.color_wheel_730_no_outline);
colourWheelB = BitmapFactory.decodeResource(context.getResources(), R.drawable.color_wheel_730_no_outline);
point = new ColourPoint(0, 0);
invalidate();
}
// Here is our DRAW LOOP.
#Override
public void onDraw(Canvas c) {
//draw
DrawableCanvas.c = c;
super.onDraw(c);
//draw wheel
rect = new Rect(0, 0, c.getWidth(), c.getHeight());
c.drawBitmap(colourWheelB, 0, 0, null);
//selection circle
c.drawCircle(point.getX(), point.getY(), 20, BlueEdgePaint);
c.drawCircle(c.getWidth() / 2, c.getHeight() / 2, c.getHeight() / 2, BlackEdgePaint);
}
public void updatePoint(int x, int y) {
point.setNewCoords(x, y);
invalidate();
}
public static double distanceFromCentre(double x, double y) {
double A = Math.abs(x - (c.getWidth() / 2));
double B = Math.abs(y - (c.getHeight() / 2));
double distance = Math.sqrt(A * A + B * B);
return distance;
}
public int[] getRGBfromPoint(double x, double y ) {
int pixel = colourWheelB.getPixel((int) x ,(int) y);
int Red = Color.red(pixel);
int Green = Color.green(pixel);
int Blue = Color.blue(pixel);
int[] ret = {Red, Green, Blue};
Log.v("Coords: ", ""+point.getX() + " " + point.getY());
Log.v("Color:", "Red = " + Red + " " + "Green = " + Green + "Blue = " + Blue);
return ret;
}
}
And here is my Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.buledin.ledstripcontrolapp.MainActivity"
tools:showIn="#layout/activity_main">
<SeekBar
android:id="#+id/seekBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="22dp"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingTop="10dp"
android:progress="100" />
<Button
android:id="#+id/strobebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="73dp"
android:text="Strobe" />
<Button
android:id="#+id/rainbowbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/strobebutton"
android:layout_centerHorizontal="true"
android:text="RAINBOW" />
<Button
android:id="#+id/offbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignTop="#+id/rainbowbutton"
android:text="Off" />
<TextView
android:id="#+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:text="Null" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/seekBar"
android:layout_alignParentStart="true"
android:gravity="center"
android:text="Brightness"
android:textColor="#color/colorPrimaryDark"
android:textSize="20sp" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/rainbowbutton"
android:text="Status:" />
<TextView
android:id="#+id/brightness"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="100" />
<com.example.buledin.ledstripcontrolapp.DrawableCanvas
android:id="#+id/canvas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView2"
android:layout_below="#+id/strobebutton"
android:color="#66000000" />
</RelativeLayout>
Here is what it looks like on the phone
And here is what it looks like in the Android studio preview
Note the scaling is all wrong for both the colourwheel and the "outline circle" which I draw over the top for aesthetic reasons. I don't know why the scaling is all wrong, but when I use the app on my phone in hardware testing I can essentially only set colours shown in the first screenshot so I lose out on 3/4 of the wheel.
Here's the real kicker though and the real head-scratcher : Despite what the image looks like on screen ( I have got it to successfully draw on my phone as a full circle) I can still only Select colours as if only that top left 1/4 of the wheel was there.
I have a LinearLayout with vertical seekbars in it. For vertical seek bar I am using custom class. While using android:layout_weight="1" seekbar thumb alignment is not proper.
verticalseekbar.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar1"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1"
android:progress="50" />
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar2"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1"
android:progress="30" />
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar3"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1"
android:progress="10" />
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar4"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1" />
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar5"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1"
android:progress="80" />
</LinearLayout>
VerticalSeekBar.java
public class VerticalSeekBar extends SeekBar{
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
#Override
public synchronized void setProgress(int progress) // it is necessary for
// calling setProgress
// on click of a button
{
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
setProgress(getMax()
- (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
Did anyone encounter this kind of issue.
Thanks.
I had the same issue. The only way to solve it, was putting each seekbar into a FrameLayout, like this:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<com.example.verticalseekbardemo.VerticalSeekBar
android:id="#+id/seekBar1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:progress="50" />
</FrameLayout>
I hope help you.
Here is an example
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center"
android:background="#ffffff">
<com.example.yourpackgename_where_VerticalSeekbar_is_define.VerticalSeekBar
android:id="#+id/first_seekbar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:progress="50" />
</LinearLayout>
To add the 5 seek bar i would suggest make a LinearLayout with horizontal orientation with weight sum of 5 and then inside the layout copy the above code 5 time with different ids
Instead of using vertical seekbar add android:rotation="90" in your normal seekbar code.
Ex:-
<SeekBar
android:layout_width="200dp"
android:layout_height="wrap_content"
android:max="50"
android:id="#+id/rightturn"
android:layout_marginTop="80dp"
**android:rotation="90"**
/>
If you'd like to use your custom VerticalSeekBar, I think the issue is that the Canvas needs to be rotated in the center to get the desired effect, although I could be wrong.
int centerX;
int centerY;
protected void onDraw(Canvas c) {
c.translate(centerY, centerX);
c.rotate(-90);
super.onDraw(c);
}
#Override
protected void onSizeChanged(int width, int height, int oldw, int oldh) {
super.onSizeChanged(width, height, oldw, oldh);
centerX = width / 2;
centerY = height / 2;
}
i have same issue and i solve this by adding
android:maxHeight="300dp"
to seekbar in layout file.
Hope this help you.
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 have an issue with a CustomView. I have a layout where I have EditText fields on top of screen. At the bottom there are two buttons. The remaining space in the middle of the screen is occupied with an ImageView. On the ImageView I should be able to draw a rectangle. I have kept a CustomView in my layout which also occupied the same width and height as that of ImageView. But my issue is the canvas occupies the whole width and height of a screen. So when user draws a rectangle on my image it hides below my EditText fields. I want to limit my canvas size same as that of the ImageSize and not to hide.
I have checked some sources but it did not help me.
<?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:background="#color/white" >
<RelativeLayout
android:id="#+id/headerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:background="#color/header_red" >
<TextView
android:id="#+id/tvAddName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:text="Enter Name"
android:textColor="#color/white"
android:textSize="16sp" />
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tvAddDimens"
android:layout_marginTop="5dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:text="Name:"
android:textColor="#color/white"
android:textSize="16sp" />
<EditText
android:id="#+id/etNameValue"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginLeft="10dp"
android:layout_below="#id/tvAddDimens"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/tvWidth"
android:paddingLeft="5dp"
android:paddingTop="2dp"
android:singleLine="true"
android:paddingBottom="2dp"
android:background="#FFFFFF"
android:maxLength="8"
android:textColor="#color/black"
android:textSize="16sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/bottomLayout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#color/dark_gray" >
<ImageView
android:id="#+id/ivDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:src="#drawable/delete" />
<ImageView
android:id="#+id/ivOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="50dp"
android:src="#drawable/tick" />
</RelativeLayout>
<RelativeLayout android:id="#+id/imgLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottomLayout"
android:layout_below="#id/headerLayout"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp" >
<ImageView
android:id="#+id/ivCapturedImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY" />
<com.ibee.macromedia.utils.DrawingView
android:id="#+id/drawRect"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
</RelativeLayout>
</RelativeLayout>
My DrawingView class is:
public class DrawingView extends View {
/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float STROKE_WIDTH = 5f;
public Paint paint;
/**
* Optimizes painting by invalidating the smallest possible area.
*/
private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private boolean isDraw=false;
private Context mContext;
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext=context;
init();
}
public void init(){
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(mContext.getResources().getColor(R.color.fluor));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
}
/**
* Erases the signature.
*/
public void clear() {
isDraw=true;
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
Log.e("MACROMEDIA", " DRAWING VIEW CANVAS WIDTH " + canvas.getWidth() + " HEIGTH " + canvas.getHeight());
if(isDraw==true){
paint = new Paint();
paint.setColor(Color.TRANSPARENT);
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), paint);
} else{
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(mContext.getResources().getColor(R.color.fluor));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
isDraw=false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartX = (int) event.getX();
mStartY = (int) event.getY();
return true;
case MotionEvent.ACTION_MOVE:
final int x = (int) event.getX();
final int y = (int) event.getY();
if (Math.abs(x - mEndX) > 5 || Math.abs(y - mEndY) > 5) {
mEndX = x;
mEndY = y;
invalidate();
}
break;
case MotionEvent.ACTION_UP:
break;
default:
return false;
}
invalidate();
return true;
}
}
Please help me. Thanks
Try in your xml:
<com.ibee.macromedia.utils.DrawingView
android:id="#+id/drawRect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/ivCapturedImg"
android:layout_alignBottom="#+id/ivCapturedImg"
android:layout_alignLeft="#+id/ivCapturedImg"
android:layout_alignRight="#+id/ivCapturedImg" />
This should align all the borders of your custom view to the borders of the ImageView.