I want to create a layout that contains an image on top of which I want to place many images and TextViews. I know how to place images on top of one another using RelativeLayout, but how to align them in a desired way? Eg I want an image to be exactly in a place where my “background” image has a specific black circle. Playing with values like android:layout_marginTop etc does not seem to do the effect in every screen.
So which is the proper way to handle these issues?
EDIT:
I cannot upload the images, but I uploaded a very simple sketch of what I want here:
http://imageshack.us/photo/my-images/715/buttonlayout.png/
all the buttons have also Icons and text (which must be a textview so that I can change it programmatically if need be)
You have to create a custom layout that places the image specifically where you want them relative to the size of the parent view. If you choose, you can override the LayoutParams and apply custom attributes to them for your custom view to read.
Anyway, to specifically place an item, say 30% down from the top and 20% from the left, you would overwrite onLayout().
#Override
public void onLayout(boolean c, int left, int top, int right, int bottom) {
super.onLayout(c, left, top, right, bottom);
int width = right - left;
int height = bottom - top;
View v = getTheChildView();
int viewL = left + (int)(width * .2f); // The left pixel is 20% down the total width of the parent view
int viewR = viewL + v.getWidth(); // The right pixel is the left pixel plus the measured width of the child view itself
int viewT = top + (int)(height * .3f); // The top pixel is 30% down the total height of the parent view
int viewB = top + v.getHeight(); // The bottom pixel is the top pixel plus the measured height of the child view itself
v.layout(viewL, viewT, viewR, viewB);
}
Related
I trying to get the usable screen space for my app. This would be the space between the Action/Tool bar and the Navigation bar.
Reason I'm needing it. I have six buttons in a constraint layout chained together vertically. At run time I need to resize the buttons. The app has a fixed landscape orientation.
Ultimately I want to constrain the the bottom button of the chain to the bottom parent or nav bar (if it exists) and the top button to the action/tool bar.
I've found that there's an attribute resource for the action bar/tool bar that I'm constraining the top of the chain to.
For the bottom, my thought is to constrain the bottom button with a constraint guide. I just not sure how to find the screen position to position it at.
There is one more way of doing this, if the previous answer doesnt work for whatever reason. In your layout editor, put buttons on the constraint layout and constrain them one to the other. Set constraints to be fixed, for example 8dp. The first button is constrained to the top of root layout, the last to the bottom. Lastly set the height of buttons to "match constraint". Am on mobile so I cant copy any xml, but this should force the height to be ruled by the dimension of root layout and lenght of constraint
Steps:
Get window height
resize images proportional to that height
add this code somewhere after setContentView or after inflation:
// root layout is the constraint layout which holds the buttons
rootLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
int rootHeight = v.getHeight();
int btnHeight = rootHeight/6;
btn1.getLayoutParams().height = btnHeight;
btn1.requestLayout();
btn2.getLayoutParams().height = btnHeight;
btn2.requestLayout();
// and same for the rest of your views
}
});
My relative layout is named "highlight".
public static void selectText(float left, float right, float top, float bottom) {
highlight.getLayoutParams().width =(int) (right-left);
highlight.getLayoutParams().height=(int) (bottom - top);
highlight.setX(left);
highlight.setY(top);
}
This works great for highlighting text as far as setting the top left corner of the highlight box. But, the box expands all the way to the bottom right corner of the screen, no matter how small I make the .width and .height values.
You set your width and height as wrap_content. Your layout will have the size of it's content.
Instead of:
highlight.getLayoutParams().width =(int) (right-left);
highlight.getLayoutParams().height=(int) (bottom - top);
Try:
highlight.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Check this link:
http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html
I don't know why, but the simple 'get layout params' wasn't working. I needed to make a new layout params entirely.
int width = (int) (right-left);
int height = (int) (bottom - top);
RelativeLayout.LayoutParams rlMainlayoutParams = new RelativeLayout.LayoutParams((int) (right-left), (int) (bottom - top));
highlight.setLayoutParams(rlMainlayoutParams);
highlight.setX(left);
highlight.setY(top);
The above answer doesn't answer my question, perhaps because I was not clear that this relative layout doesn't hold any text, it only highlights certain text already present on the screen (in a PDF document, where I cannot necessarily just extract the text to a PDF document).
After you've modified a view's layout params, call requestLayout() on the view for the changes to take effect.
(Calling setLayoutParams() also implicity calls requestLayout().)
Is there a way to dynamically change the position(like a manually translation animation) on a child view thats been defined and places inside onLayout?
i have this onLayout defined here:
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//place topview at the top of the layout by removing the ySpace value defined fro the height
// of this view and dividing the height so that the topView takes nearly half the space
// height of this view container
topView.layout(0, 0, getWidth(), (getHeight() - ySpace) / 2);
}
i want to manually change the y axis position of topView Dynamically .
i was thinking ofabout onDraw but onDraw doesnt that childViews and draws them. Instead it just gives you a blank canvas to manually draw items in it.
Currently implementing a custom ViewGroup that takes x amount of child views and dynamically moves them around. My question is how do i move them around?
In GestureOverlayView is there any way to limit paintable area. ie in the whole View i want some margin that is not paintable, with the view(GestureOverlayView) covering all the available area
you can try to apply padding in your view. probably in your layout xml, or via code View.setPadding(int left, int top, int right, int bottom)
I have a layout where the Gallery height is WRAP_CONTENT (width is FILL_PARENT) with bottom margin of 80dp. This would leave 80dp at bottom of screen for something else.
The problem is how can I find out exactly how many pixels do I have in the height of this Gallery? I need this in order to set the size of the bitmap in Gallery's getView (as I want each image to take up a full Gallery screen) Various devices should give me different height pixels...
Apparently when I query Gallery.getHeight, it returns zero.
Also, if the image itself is smaller than the Gallery view port, I want to scale it up. However setScaleType(FIT_CENTER) seems to only scale down (if image is larger than viewport) yet does not scale up? Am I missing something?
Thanks in advance for your help.
Gallery is just another View, so any method defined for View will work. Use myGalery.getHeight();
From the View API reference page: http://developer.android.com/reference/android/view/View.html
Size, padding and margins
The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.
The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().
The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().
To measure its dimensions, a view takes into account its padding. The padding is expressed in pixels for the left, top, right and bottom parts of the view. Padding can be used to offset the content of the view by a specific amount of pixels. For instance, a left padding of 2 will push the view's content by 2 pixels to the right of the left edge. Padding can be set using the setPadding(int, int, int, int) method and queried by calling getPaddingLeft(), getPaddingTop(), getPaddingRight() and getPaddingBottom().
Update
Be careful when are you measuring it. If you use it on the constructor, the it will return zero since it was not drawn yet. Unless you are absolutely sure that the GridView will be visible by the time you measure it, you can measure by adding an View.OnLayoutChangeListener and implementing
public abstract void onLayoutChange (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
http://developer.android.com/reference/android/view/View.OnLayoutChangeListener.html
or overriding protected void onSizeChanged (int w, int h, int oldw, int oldh)
u can get the total height & delete 80px from it ie(your Gallery height)
get total height by this code
Display display;
display = activity.getWindowManager().getDefaultDisplay();
display.getHeight()