Adding Views to another View - java

Is there a possibility to add a view or derivative (button, textview, imageview etc...) to another view without having to go through layouts?
I have a class called ScreenView, it derives from View (e.g. public class ScreenView extends View).
I wanted to display text into it, labels, images etc..
On an iPhone it's trivial, simply create my objects and use addSubview method ; you can embed any UI objects into another. Most UI toolkits work that way too.
Problem with layouts is that I haven't found an easy way to properly position a subview (say a text view) in a given location of the enclosing View. I want one to contain the other...
I was hoping I had missed something in the documentation (which is far from being intuitive that's for sure) and I could do something like myView.addView(subview). But it ain't so :)
As a side question, what is the closest to iPhone's UILabel in the Android world?
A UILabel can contain a text or a graphic. Right now I've been using TextView and ImageView but they aren't anywhere as flexible when it comes to layout as a UILabel
Edit: Making my View inherit from ViewGoup instead, let me add subview..
However, I want to draw in my view. I found that when ScreenView extends ViewGroup, the onDraw function is never called then.
Something like:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
// make the entire canvas yellow
paint.setColor(Color.YELLOW);
canvas.drawPaint(paint);
}
Would paint in yellow my view if ScreenView extends View ; but not if it extends ViewGroup.
How do you draw directly in the view then?
Thanks
JY

Use a ViewGroup, that's what they are for. And then you can call addView() :)

After making my class inherit from RelativeLayout instead, it does draw my subviews.
GroupView doesn't draw anything by default, and onLayout needs to be fully written. With no documentation on this matter it's going to be a hard thing to do.
onDraw isn't called by default, it does get called if you set the background colour or add any drawable item.
Otherwise you need to draw during dispatchDraw instead.

Related

Show google maps polyline only on specific part of device screen

Good day to you all, I am creating a ride app and I was asking for some assistance in the following problem I am facing.
So, On the image below the grey background represents a google map fragment and above it sits two views(black) I wanted to know if it were possible to only show a polyline and markers between the black views only in the red area and have the rest of the map showing in the background as well.
If it helps I have managed to get the LatLng's of the corners of the red box using:
googleMap.getProjection().fromScreenLocation();
Thank you in advance!
Yes, it is possible. Several ways. For example, the red area of your figure can be View (e.g. custom view) with transparent background and you can draw your polylines on it (you need to take into account position of transparent "red" view on map view for correction of fromScreenLocation()/toScreenLocation() methods results). Also, probably, you can use two MapViews one over another and synchronize its scrolling and zooming, but IMHO best way is to to implement custom view component based on MapVew (or MapFragment) an override onDraw() for MapVew-based (or dispatchDraw() for MapFragment-based) method like in this or that answers:
..
#Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
drawPolylinesInRegion(canvas);
canvas.restore();
}
...
In drawPolylinesInRegion(canvas); method you should draw your polylines and markers "manually" converting coordinates of them via method opposite you mentioned: toScreenLocation() and taking into account size of "gray regions" of you example figure.

How to create a large image that one can scroll over

Currently I have a class that draws a bunch of squares dynamically based on the contents of a sqlite file. As the data is quite large the drawing is many times larger than the screen. I've read a lot of proposed methods to do this and am unsure of the best approach. As I will not change the image after I render it (only need to dynamically render it upon restart) the first answer listed here seems to be the best but I'm not fully understanding how to do so.
If I understand correctly I:
create a bitmap,
create my canvas (that is larger than the screen resolution)
grab the cached bitmap and
render the bitmap versus the canvas.
But I'm lacking the knowledge to make this happen within my existing code. My existing code simply creates a very large canvas (I do not define the bounds, I just start drawing). My main class looks like this:
package com.example.drawdemo;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
public class DrawDemo extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
}
And the DrawView class something like this:
public class DrawView extends View {
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
//LOTS OF CODE HERE to figure out how to render rectangles through loops
// similar to lines like this
canvas.drawRect(xStart, rectYPointer, xEnd, rectYPointer+rectSize, paint);
// or this
canvas.drawText(String.valueOf(rectSize), 130, rectYPointer*2, paint);
}
}
Is the approach I am taking the correct approach to allow me to scroll down and see this large image that is bigger than the android screen? If so, how do I migrate my code to conform to the approach listed in the answer I believe is the correct method?
Well I'm affraid you didn't get the point of the linked topic. It's quite different as what you try to achieve.
this topic is about drawing on a bitmap to be used later.
you already have a constructed bitmap do you ? ( or at least you can load it from resources using :
BitmapFactory.decode... (resource or file according to your input, see the documentation here)
Your canvas doesn't have to be huge in order to scroll it inside the screen. The size of the canvas is the size of your view (here, the size of the screen) but you will be drawing the bitmap according to the scroll position you want to apply.
see : canvas.drawBitmap() 's documentation
and canvas.translate can help too.
Basically what you want is : get a reference on a loading bitmap (using bitmapdecode) in your view.
then in the onDraw, draw the bitmap on the view's canvas to show it on screen.
then, to add the scroll effect, try to change the y translation of the canvas when drawing on it.
hope that helps.
For more information (and a good example) about drawing on a canvas I suggest you open the API demo project source code :
API Demos -> Graphics -> TouchPaint

Select Content inside ImageView - Android

I have an Activity containing an ImageView and I'd like to allow the User to select part of it's content with the touch (or mouse click) capabilities.
I'd like to write a procedure able to achieve two things:
Draw a highlighted window over the selected parts of the image
Return an object containing the coordinates of the selected (highlighted) pixels.
For better understanding you can check the little mock up I've created:
The User should touch the screen over some part of the image and it should get highlighted. When pressing the back button I'd like to obtain via Java the coordinates of the pixels that were highlighted.
Can you help me understand how to do?
In particular I'd like to find out the following:
should I access pixel level information of the image?
which classes are needed to implement this functionality?
some idea of pseudo code?
Thks for any kind of help!
I would subclass ImageView then you can capture the touch events by overriding onTouchEvent(...)
When you get to the onDraw(...) method you can call super to draw the image as normal, then add your own code to draw a highlight over the top.
EDIT
Well instead of using ImageView you can extend it and write your own class, all this class has to do is override onTouchEvent(...) so you know when the view is being touched and can save the location on screen of the touch events. Next you edit the drawing methods:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // So the image you want is drawn as normal
myMethodForDrawingAFancyHighlight(Canvas canvas); // add your special effects on top of the image
}

Android: Is it possible to draw a view on top of the mapview as an overlay

Actually, the subject is a question.
I want to draw on top of the map a view as overlay, simply my view consist of linear layout with 9patch background and two textview inside. I need to draw those layouts in runtime and they will be linked to geo location
There is no problems to define such view, but it is problematic to create an overlay that will handle such draw...
Yes - this is what a FrameLayout is for! Children in a FrameLayout appear on top of each other, with the last item displayed on top and the first item displayed on the bottom.
Put your MapView as the first child of a FrameLayout and your LinearLayout as the second.
Actually there is no way to do what I want, I've found a way to convert any layout to bitmap, but firstly you need to invoke layout on the root view and define it boundaries, so in my case it is the same to simple drawing on canvas which I've used for my solution. Converting layouts to bitmap is a good thing when your layout is already drawen on the screen, but when you need to draw layout on the canvas from scratch there is no benefits due to simple drawing on canvas.
You could create a drawable out of your view by converting it to a bitmap.
Or you can try to use this. Has the same effect: https://github.com/jgilfelt/android-mapviewballoons#readme
And you can modify it like you want to show whatever view you like

Layered SurfaceViews in a FrameLayout in Android

I am attempting to build an augmented reality application for Android and have come across the problem of layering surface views. I need a surface view to display the camera preview onto which I will overlay graphics, and I need a surface view to draw my graphics on. This second surface also needs to be drawn above the camera preview but have a transparent background. In my current implementation, I have both surface views working and appearing as they are supposed to, but the background is not transparent and therefore there is no appearance of the second surface view with the graphics drawn being superimposed on the camera preview surface view. How could this be achieved? Upon searching numerous stack overflow questions as well as other forums I've come across many conflicting opinions pertaining to this matter. Some say that layering surface views in Android is impossible whilst others say that it is a matter of using a different layout (FrameLayout vs. LinearLayout?) Specifically, my implementation includes two views: a class, CustomCameraView, that extends SurfaceView, and a class, CustomDrawView, that also extends SurfaceView contained in a FrameLayout with the CustomDrawView appearing after the CustomCameraView. How can these be layered so that CustomDrawView seems superimposed on CustomCameraView?
I think a lot of people have tried this. A Google Enginee stated (here) clearly, that you should avoid stacking Surface Views. Even if somebody has found some trick to do it, it is probably incompatible and will lead to problems.
I think this gives three options, depending on your requirements:
View(s) on Top of Surface View
Use a Surface View for the Camera preview and stack Views on top of it. The disadvantage of this approach is that drawing on "normal" Views a) is slower and b) takes place in the UI thread. You can get around b) if you implement the threads yourself. But generally, that is probably the way to go if your overlays contain something like UI elements or a few Drawables that don't need to be updated too often.
Do everything in a SurfaceView
This will give yo better performance and less overhead during runtime. You have just one SurfaceView. Composite the overlays on your SurfaceView and and draw everything there. Of course, you can combine both approaches.
Do everything in a GLSurfaceView
This is probably the way to go for real performance. Like above, but with the camera view rendering to a OpenGL texture in a GLSurfaceView.
I got this working having 2 transparent views above the camera's SurfaceView using the following approach:
My activity sets up all its views in the onCreate() method, I make no use of any layout file for that. It looks as follows:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null); //savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
cameraPreview = new CameraPreview(this);
addContentView(cameraPreview, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
animationView = new AnimationView(this);
addContentView(animationView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
crosslinesView = new CrosslinesView(this);
addContentView(crosslinesView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
cameraPreview is of type SurfaceView, animationView and crosslinesViews are of type View. The onDraw() of the 2 latter views looks as follows:
protected void onDraw(Canvas canvas) {
// Have the view being transparent
canvas.drawARGB(0, 0, 0, 0);
// Your drawing code goes here
// ...
}
Good luck!

Categories

Resources