Using ViewGroup and View on Android draw and make buttons using canvas - android

I'm trying to make my own custom view, currently all it does is draw an image on a specific x and y coordinate and then draws the similar images repeatedly on different locations.
I want to be able to create a button on each instance of the image that is drawn. if one image is clicked it will have cause something different to happen depending on which image is chosen.
How can I implement this?
would I have to create a different view for each image/button combination and then set an onClick event?
Let me try to be a little more clear
I'm trying to make a map using hexagon (different types of terrains for different players)
I've figured out how to get them to draw (see here - they will have a border to show what terrain is owned by whom)
I just made a custom view class and had the hexagons drawn using a Canvas; however, I'm not sure how to be able to make the hexagons into buttons so that I can differentiate between which hexagon was chosen and how it should react to the opponents spot.
I was thinking of making a ViewGroup called Terrain to contain the Nodes(hexagons) that belong to the player and have a group of Node Views that only draw the hexagon where it should be located.
the question is can i make each node or the entire viewGroup into a button (or do an onTouch ) if a certain hexagon is pressed?

If I understood well, you should do :
One template my_pictures.xml which is a simple button.
Then you create a custom adapter which as a function for each kind of image you wanna create. By this, I mean that you will have to change the background value of your button depending on what you need it to be. Then you do a notifyDataSetChanged(); to refresh the container with the new button.
For the Listener, you just have to add it either in your activity or your adapter when you create your buttonImages, I don't know what's better.

Thanks for your help!
I figured out what I needed to do.
I have a NodeView class and in my GameActivity class, I'm using a relative layout and setting the layout parameters of where I wanted things positioned
RelativeLayout rl = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(95,95);
params.leftMargin = 10;
params.topMargin = 10;
params = new RelativeLayout.LayoutParams(95,95);
params.leftMargin = 10+95*x;
params.topMargin = 81+(71*y);
rl.addView(new NodeView (this,0,0,1,1), params);
This helped me add things where I needed them and now all I'm trying to figure out how to scroll around the territories on both the x and y axis (I tried ScrollView but that only allows me to scroll on the y-axis, I'm looking into it though)

Related

Redrawing clipped content in Android View after moving into bounds

Within Android, I'm trying to move a TextView from outside the parents bounds into view, but the contents never shows up, or remains clipped if it was partially within the bounds already.
Initial situation at start
Situation after animation
(Below this is another view, that was completely out of bounds and isn't drawn either)
I have 4 TextViews below each other in a custom Object extending RelativeLayout. Based on a percentage the top 2 should move outside it's bounds and the bottom 2 should move in (from the bottom).
I use the following code to update the properties of each TextView. In this class each variable **positionY* is filled with their initial position from the layout-xml. effect is percentage between 0 & 1. The animation works, but the views aren't drawn again.
public class ActionBarTitleView extends RelativeLayout {
public void updateTransition(float effect) {
float height = getHeight();
titleView1.setY(title1positionY - height*effect);
detailView1.setY(detail1positionY - height*effect);
titleView2.setY(title2positionY - height*effect);
detailView2.setY(detail2positionY - height*effect);
invalidate();
}
}
What I tried
After some researching I found a few hints what the issue might be, but so far none of the tried options had any effect. Below is a list of things I've found on SO and tried.
Calling invalidate() on the RelativeLayout - No effect.
Invalditing the TextViews - No effect.
clipChildren = false for the RelativeLayout - No effect.
setWillNotDraw = false for the RelativeLayout - No effect. (onDraw is being called)
I haven't tried to solve this with a ScrollView, but I don't want to really, cause that adds another layer in the hierachy for something pretty small.
I thought I understood the drawing logic, but perhaps I'm missing something, so I hope someone might be able to point me in the right direction.
What I ended up doing (September 3rd)
Since no real solution was offered, I tried again and came to the following "fix". I set both second labels to Visibility.GONE, but within the original bounds of the container view. Then when I start the animation, I set their correct values, then move them outside the bounds and finally setting Visiblity.VISIBLE. When the animation progresses the labels roll into view as supposed to. So a fix to the issue, but no real explanation why the TextViews aren't drawn again...

which layout displays multiple image buttons?

Hi I'm trying to add an activity that displays 4 images (imagine a square cut to quarters) where each image shows a different one when clicked, I have tried a few layouts using image buttons to no avail but then read here my answer is a grid view using image pager but when implementing this I get small images spaced quite far apart in grid view is there a better way please?
if it's always 2x2 images you can simply use a vertical linear layout and two horizontal layouts in it and then put your images as ImageButton or ImageView inside the horizontal layouts...
if it needs to be dynamic a gridlayout would probably be a good idea...
however, you need to provide more detailed information on what the issue is, if you need a more detailed answer...
(edit: I meant gridview, gridlayout is only available since api level 14)
You can use a RelativeLayout in order to add your ImageButtons and have all the control to your hands for location of buttons, size etc.
A different point of view, is to break your screen into 4 Rectangles (Rects).
Something like this :
Rect upLeftRect = new Rect(0,0,screenWidth/2 , screenHeight/2);
Rect upRightRect = new Rect(screenWidth/2,0,screenWidth,screenHeight/2);
Rect downLeftRect = new Rect(0,screenHeight/2, screenWidth/2 , screenHeight);
Rect downRightRect = new Rect(screenWidth/2, screenHeight/2, screenWidth,screenHeight);
The, attach an onTouchListener on your relativeLayout, something like this in your constructor:
yourRelativeLayout.setOnTouchListener(this);
And finally , inside the onTouch method you will have something like this :
#Override
public boolean onTouch(View v, MotionEvent e){
if(upLeftRect.contains( ( int ) e.getX(), (int) e.getY){
// do whatever you want, i guess that you want some alpha animation or something like this
}else if(upRightRect.contains( (int) e.getX(), (int) e.getY(){
// bla bla.. :)
} // do the rest conditions your self!!
Hope that helped!

How do I get a view position relative to another view in Android?

I'm making a app for Android that shows a camera image (after going through some manipulation) on screen using an ImageView and I want to allow to move other ImageViews on the screen - but only inside the the parent ImageView.
Also, I need to get the coordinates of the child views relative to the coordinates of the parent ImageView. i.e - So that (0,0) will not be the whole screen, but the ImageView that shows the camera.
Is that possible at all? If so - How?
Help is much appreciated! Thanks
If you want to move the views by drag here's a lot of info around, e.g Moving image with touch events .
What about getting the top and left side of minorView relative to majorView it's also straightforward with some plain substraction minorViewRelativeTop = minorViewTop - majorViewTop. Use View.getLocationInWindow() for getting these absolute positions.
N.B. That View.getLocationInWindow() will usually not work just inside Activity.onCreate() so better call it after some delay. For testing it could be sth like:
majorView.postDelayed(new Runnable() {
#Override
public void run() {
int[] location = new int[2];
majorView.getLocationInWindow(location);
int majorViewLeft = location[0];
int majorViewTop = location[1];
}
}, 1000);

Drawing custom view using Android

I am drawing a custom view in my application which basically takes arguments(XML) as the text to display and then keeps on rotating it infinitely.
While I was making this control I had a few doubts which I want to ask:
I have made 2 of my stylable attributes which I have declared in the attrs.xml file. These attributes are to set the width and the width of the circle used in my control. These values I would use in the ondraw method and the onmeasure method. I ran my program by declaring just these but there was an error which asked me to put android:width and android:height attributes. My question is why would I need those if I am already using my custom attributes to define the height and the width of my view
I am coding on a mac. Now when I was making my attrs.xml file, to get the autocomplete list which we usually get by ctrl+space was not showing up. Why is that. For e.g., i wanted to know what values can I give the format attribute of my custom attribute that like I am demostrating in the following:
<attr name ="somename" format="value I wanted to find out through autocomplete"> . Why is the autocomplete not popping up? It does pop up when I am making a.java file.
In my ondraw() method I wanted to draw a circle. Now for this I would require the co-ordinates of the center of the circle. So what I do is put 0, 0. But this is not correct. I want the circle to be at the center of the parent view it is in. So if my view is in a hierarchy I want it to respect that. I want to give the co-ordinates relative to the parent view. What is happeining right now is that it is being drawn at the top left corner of my screen. This is what I don't want. What do I do to achieve this?
why would I need those if I am already using my custom attributes to define the height and the width of my view?
This is because Android needs to know how and where to put your view in the layout. You can implement your view to make use of your custom height/width requirements by overriding View.onMeasure() to return your own size parameters. You can then just set android:layout_width="wrap_content" android:layout_height="wrap_content" in your layout file.
Why is the autocomplete not popping up? It does pop up when I am making a.java file.
Autocomplete and autodoc implementation for Android xml files is shaky at best, so it's not really surprising that it doesn't work. I'm not aware of a fix and AFAIK it's an IDE bug.
In my ondraw() method I wanted to draw
a circle. Now for this I would require
the co-ordinates of the center of the
circle. So what I do is put 0, 0. But
this is not correct. I want the circle
to be at the center of the parent view
it is in. So if my view is in a
hierarchy I want it to respect that. I
want to give the co-ordinates relative
to the parent view. What is happeining
right now is that it is being drawn at
the top left corner of my screen. This
is what I don't want. What do I do to
achieve this?
If you implemented onMeasure() correctly, the coordinates relative to parent should be taken care of already. To get the center of your view use the following code:
void onDraw(Canvas canvas)
{
int centerX = this.getWidth() / 2;
int centerY = this.getHeight()) / 2;
//..draw code here
}
Edit
Here's an example with source code that should help: http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/

Android - How to draw a letter at a specific point?

I want to fill the screen with a 100 different letters in random positions. On the iPhone I just created a bunch of UILabels set their x and y positions and then used animations to move them about.
On Android it doesn't look like I can add a TextView to my view and specify its X and Y. Is there a way to do this?
View gameView = findViewById(R.id.gameboard);
tv = new TextView(gameView.getContext());
tv.setText("A");
tv.setWidth(w); tv.setHeight(h);
// How to set the X and Y?
EDIT: The solution was to use AbsoluteLayout:
AbsoluteLayout al = (AbsoluteLayout)findViewById(R.id.gb_layout);
tv = new TextView(this);
AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,10,10);
params.x = 50;
params.y = 50;
al.addView(tv, params);
and to move it base on MotionEvent me:
AbsoluteLayout.LayoutParams p = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,(int)me.getX(), (int)me.getY());
mTV.setLayoutParams (p);
I think you are making a game and for this you should look into SurfaceView here is an good example then
1...if you look into code there is onDraw method where you will get the width of screen and height
2...Now taking this width and height as seed for random generator get x and y position.
3...Iterate through point 2 100 times and you will get the desired result
You can use a FrameLayout for this. Set each TextView's background to transparent and add it to the FrameLayout. Make each TextView, and the FrameLayout, fill their parent. The FrameLayout places all its child views at (0,0). To move letters around, just change the top and left padding of the corresponding TextView.
In android positioning child views is the responsibility of the layout class.
You need to create a custom.layout and overide the onLayout method. In this method you can iterate through all the child views calling View.layout(left,top,right,bottom) on each child.
i found this example code whilst trawling the net :
https://gist.github.com/882650
You should also check out view.setTranslationX (and Y) which might be exactly what you need
I'm not entirely sure how you'd go about doing this in code, but you need to use an absolute layout as your root element. (edit: Do not use absolute layout, as it was pointed out that it is deprecated. The closest alternative seems to be RelativeLayout.)
The properties in the XML format for the absolute layout coordinates are layout_x and layout_y.
edit: A little research is saying you need to be using setLayoutParams, but my Eclipse IDE is not working properly, so unfortunately I can't test exactly what you're looking for.

Categories

Resources