How to add a view to a specifc point on mapView - java

an When an onTouch event occurs on my MapView, i want layout i have specified to be drawn above the where the user has touched
The below is where i have started, i do not know how to actually place the popup view on the x and y values retrieved from the event. Do you guys have any ideas?
#Override
public boolean onTouchEvent(MotionEvent ev, MapView mapView) {
int X = (int)ev.getX();
int Y = (int)ev.getY();
ViewGroup parent=(ViewGroup)map.getParent();
View popup=getLayoutInflater().inflate(R.id.popup, parent, false);
((ViewGroup)map.getParent()).addView(popup);

You can set the MapView.LayoutParams() with the values of x and y and then call the MapView's addView with the LayoutParams.
MapView.LayoutParams params = new MapView.LayoutParams(width, height, x, y, alignment);
mapView.addView(popup, params);

At first, your need one global Point with your X,Y coordinates
#Override
public boolean onTouchEvent(MotionEvent ev, MapView mapView) {
int X = (int)ev.getX();
int Y = (int)ev.getY();
selectedPoint = new Point(X,Y);
return true;
}
Now, you should override the onDraw() method to draw you popup view. There are many solutions to do that, I've tried this one with StaticLayout:
#Override
public void draw (Canvas canvas, MapView mapView, boolean shadow){
super.draw(canvas, mapView, false);
if ( selectedPoint != null) {
// here you should define PopupText, textPaint and width variables
StaticLayout sl = new StaticLayout(popupText, textPaint, width,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
// here you can draw a rectangle — border for your popup text.
// You can use sl.getWidth() and sl.getWidth() methods to get the popup dimensions
canvas.save();
canvas.translate(selectedPoint.x, selectedPoint.y);
sl.draw(canvas);
canvas.restore()
}
}

Related

Drawing rectangles that fill up with gradient depending on the value

I want to have three separate rectangles that would fill up with gradient. Depending on the value X the gradient would be placed differently. For example if value X = 75 the gradient would be 75% green and 25% red. I wanted to know if there is any library or a method that would allow me to do this in java (android studio).
To implement this, you could use LinearGradient for the gradient and then create a custom view with methods allowing you to change the layout of the gradient.
public class GradientView extends View {
Paint paint;
LinearGradient gradient;
int[] colors = [Color.RED, Color.GREEN];
public GradientView(Context context, int gradientHeight) {
super(context);
paint = new Paint();
setGradientHeight(gradientHeight);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setShader(colorGradient);
canvas.drawPaint(paint);
}
public void setGradientHeight(int height){
colorGradient = new LinearGradient(0, 0, 0, height * 0.01 * super.getHeight(), colors, null, Shader.TileMode.MIRROR);
paint.setShader(colorGradient);
invalidate();
}
}
Haven't tested the code, but it should certainly work something like this.

Custom viewgroup is not showing its child custom views

The draggablepointviews in pathview arent showing up. I did addView in PathView but the pointviews are still not being rendered. Am I missing something? I thought addView was enough and would make the childs render.
PathView.kt
class PathView(context: Context) : ViewGroup(context)
{
private val pointA = DraggablePointView(context)
private val pointB = DraggablePointView(context)
private val paint = Paint().apply {
strokeWidth = 15f
color = Color.WHITE
}
init
{
pointA.x = 50f
pointA.y = 50f
pointB.x = 330f
pointB.y = 330f
addView(pointA, 100, 100)
addView(pointB, 100, 100)
setWillNotDraw(false)
}
override fun onDraw(canvas: Canvas?)
{
if (canvas == null)
return
// Draw a line between pointA and pointB
canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, paint)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int)
{
}
}
DraggablePointView.kt
class DraggablePointView(context: Context) : ImageView(context)
{
init
{
setImageResource(R.drawable.point)
setWillNotDraw(false)
}
override fun onDragEvent(event: DragEvent?): Boolean
{
println("DRAG EVENT")
if (event == null)
return false
x = event.x
y = event.y
return true
}
}
Then:
val pathView = PathView(context)
frameLayout.addView(pathView)
1) Draw the line
To force a view to draw, call invalidate().
void invalidate()
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future.
void invalidate (int l, int t, int r, int b)
Mark the area defined by the rect (l, t, r, b) as needing to be drawn. The coordinates of the dirty rect are relative to the view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future.
2) Draw the points
Since you extend ViewGroup you're responsible for measuring and laying out the child views.
Perhaps you should extend AbsoluteLayout instead, which already has the measurement and layout logic programmed. Then you can set the coordinates like so:
val lp = layoutParams as AbsoluteLayout.LayoutParams
lp.x = event.x
lp.y = event.y
requestLayout()
Or perhaps you should extend View and draw the points in the same fashion as the line. That should be most efficient. You don't need child views to draw, you need just canvas.
Override onTouchEvent to listen for and react to touch.
Draw the drawable to canvas by calling setBounds (tell it where to draw) and draw.

Canvas; How to remove shapes retroactively

So I am using onDraw in a custom View class to draw shapes on a RelativeLayout + TableLayout all that works fine, and I have another class that I use to draw lines from Point A to Point B etc. example below:
My Goal:
If I drag my finger from Point A (objectA) to Point B(objectB), how can I delete those 2 View Objects from the canvas? I added a method:
objectA.delete();
objectB.delete();
that should delete both A and B when I drag my finger through MotionEvent, but it only deletes one and not the other, so i am thinking it's not retroactive?
Codes below:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
/// get the child that corresponds to the first touch
DotView objectA = getChildForTouch((TableLayout) v, x, y);
return true;
case MotionEvent.ACTION_MOVE:
///used the x - y to get the object for every other shape the user`S finger passes over.
DotView objectB = getChildForTouch((TableLayout) v, x, y);
/// just update positions
line.setCoords(mStartX, mStartY, (int) x, (int) y);
objectA.delete(); ///Delete first shape
objectB.delete(); ///Delete second shape
break;
case MotionEvent.ACTION_UP:
///Gets the last shape where the user released their fingers
endView = getChildForTouch((TableLayout) v, x, y);
break;
Delete method inside the: DotView extends View class:
private static class DotView extends View {
private static final int DEFAULT_SIZE = 100;
private Paint mPaint = new Paint();
private Rect mBorderRect = new Rect();
private Paint mCirclePaint = new Paint();
private int mRadius = DEFAULT_SIZE / 4;
public DotView(Context context) {
super(context);
mPaint.setStrokeWidth(2.0f);
mPaint.setStyle(Style.STROKE);
mPaint.setColor(Color.RED);
mCirclePaint.setColor(Color.CYAN);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.parseColor("#0099cc"));
mBorderRect.left = 0;
mBorderRect.top = 0;
mBorderRect.right = getMeasuredWidth();
mBorderRect.bottom = getMeasuredHeight();
canvas.drawRect(mBorderRect, mPaint);
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2,
mRadius, mCirclePaint);
}
public void delete(){
mPaint.setColor(Color.TRANSPARENT);
}
}
Just something simple to fake delete the circles
Thanks in advance guys.. more codes can be provided if need be.
Edit: If I can accomplish this in any other way please feel free to share. (Draw circles on a Grid and delete the ones I used my finger to draw my line over)
First of all try changing your delete() method to this:
public void delete(){
mPaint.setColor(Color.TRANSPARENT);
invalidate();
}
You need to let your View know that you want it to redraw itself (that's why the invalidate() call).

How to get (x,y) cordinates of image in android?

I have drawn a image on ONTOUCH with (X,Y)cordinates while moving the image it's cordinates should move along with the image when it reaches it end point the image should be drawn there or else the image should go back to it's starting position.
For eg:(in our mobile if kepad lock we will drag it to open if it reaches it end point the lock will open or else the image will reaches it's starting position).
Reffered link:http://www.vogella.com/tutorials/AndroidTouch/article.html
Here is my code:
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mLocked) {
return false;
}
final int action = event.getAction();
float x = event.getX();
float y = event.getY();
if (mOnDrawerScrollListener != null) {
mOnDrawerScrollListener.onScrollStarted();
}
final int pt = getSide();
mTouchDelta = (int)(y - pt);
prepareTracking(pt);
mVelocityTracker.addMovement(event);
final Rect frame = mFrame;
final View handle = mHandle;
If anyone have idea about this please help me friends.
If you want to get(x, y) cordinates of view (ImageView), just use view.getX(), view.getY(). But when you get it in onCreate(), the results will be (0, 0), because it is not created yet. You should use view.getX(), view.getY() in onGlobalLayoutListener(). For e.g:
rlRoot.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
rlRoot.getViewTreeObserver().removeGlobalOnLayoutListener(this);
Log.d("X", view.getX()+"");
Log.d("Y", view.getY()+"");
}
});
With rlRoot is the layout includes your view and view may be ImageView or any View.
Try it, hope it help.

How to make Circle color light in the Android google map

Below is my code where I am drawing circle on the Google Map in Android. It is working fine for me.
Problem Statement:-
Currently the circle that is getting drawn on the google map is very dark. I need to make that circle little bit light with the same color that I am having currently. Is that possible to make that circle little bit light by tweaking few parameters in the paint or color? It is more darker in the center part, don't know why. I just need to make it light in all the four circles that I have currently.
class MapOverlay extends Overlay {
private GeoPoint pointToDraw;
int[] imageNames=new int[6];
private Point mScreenPoints;
private Bitmap mBitmap;
private Paint mCirclePaint;
public MapOverlay(GPSLocationListener gpsLocationListener, int currentUser) {
imageNames[0]=currentUser;
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setColor(0x30000000);
mCirclePaint.setStyle(Style.FILL_AND_STROKE);
mBitmap = BitmapFactory.decodeResource(getResources(),imageNames[0]);
mScreenPoints = new Point();
}
public void setPointToDraw(GeoPoint point) {
pointToDraw = point;
}
public GeoPoint getPointToDraw() {
return pointToDraw;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
if (pointToDraw == null) {
return true;
}
mScreenPoints = mapView.getProjection().toPixels(pointToDraw, mScreenPoints);
int totalCircle=5;
int radius=40;
int centerimagesize=35;
for (int i = 1; i <= totalCircle; i ++) {
canvas.drawCircle(mScreenPoints.x,mScreenPoints.y, i*radius, mCirclePaint);
}
canvas.drawBitmap(mBitmap, (mScreenPoints.x-(centerimagesize/2)),(mScreenPoints.y-(centerimagesize/2)), null);
super.draw(canvas,mapView,shadow);
return true;
}
}
Snapshot of my Circle currently-
Any suggestion will be of great help.
Problem
The reason why it gets darker in the center, is because you are drawing four circles, one over the other. When you draw the second circle, the part that is commoun to both, is painted twice, so it becomes darker. When you draw the tird circle, it becomes even darker ...
Solution
If you want all circles with same color, you should use Style.STROKE for all the circles, except the larger one, which shoud use Style.FILL_AND_STROKE. With that you only draw the lines for the small circles and fill all area when drawing the big one.
Code
mCirclePaint.setStyle(Style.STROKE);
for (int i = 1; i <= totalCircle-1; i ++) {
canvas.drawCircle(mScreenPoints.x,mScreenPoints.y, i*radius, mCirclePaint);
}
mCirclePaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawCircle(mScreenPoints.x,mScreenPoints.y, totalCircle*radius, mCirclePaint);
Regards

Categories