My layout structure is like this
LinearLayout
FrameLayout
ImageView
ImageView
FrameLayout
TextView
LinearLayout
I have set margin's for the two ImageView which are inside FrameLayout. But FrameLayout margins are discarded and it always set's the Image to top left corner. If i change from FrameLayout to LinearLayout the margin's work properly. How to handle this ?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/inner1"
>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="24px"
android:layout_height="24px"
android:id="#+id/favicon"
android:layout_marginLeft="50px"
android:layout_marginTop="50px"
android:layout_marginBottom="40px"
android:layout_marginRight="70px"
/>
<ImageView
android:layout_width="52px"
android:layout_height="52px"
android:id="#+id/applefavicon"
android:layout_marginLeft="100px"
android:layout_marginTop="100px"
android:layout_marginBottom="100px"
android:layout_marginRight="100px"
/>
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/title"
android:layout_marginLeft="10px"
android:layout_marginTop="20px"
android:textColor="#FFFFFF"
android:textSize = "15px"
android:singleLine = "true"
/>
</LinearLayout>
I had the same issue myself and noticed that setting the layout_ margins does not work until you also set your ImageView's layout gravity i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP;.
To make it more clear why. The FrameLayout.onLayout() call contains this (in api v2.3.4 at least):
// for each child
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int gravity = lp.gravity;
if (gravity != -1) {
// handle all margin related stuff
So if gravity is -1, there will be no margin calculation. And the thing is, gravity in FrameLayout.LayoutParams is defined by:
gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);
So if gravity is not set, there will be no margin calculation.
add your xml this attribute and re run
android:layout_gravity="top"
everything is Ok!
and you dont set new layout params like this;
FrameLayout.LayoutParams llp = new FrameLayout.LayoutParams(WallpapersActivity.ScreenWidth/2, layH);
use like this:
FrameLayout.LayoutParams llp = (LayoutParams) myFrameLay.getLayoutParams();
llp.height = 100;
llp.width = 100;
myFrameLay.setLayoutParams(llp);
Taken from the FrameLayout docs (link)
The size of the frame layout is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits).
This seems to describe the fact that it'll strip margins out. Like boulder mentioned, you could try switching to padding as it can be used to produce a similar effect if done properly.
Out of curiosity, you mentioned that it does work fine when using a LinearLayout container, why the choice of FrameLayout?
Have you tried android:layout_gravity ? Try using android:padding in you ImageViews instead of android:layout_margin. AFAIK margins doesn't work properly on Frame layout. I even had to write custom layout for that purpose once. BTW, how do you want allign you ImageViews?
try setCropToPadding(true) to ImageView ,this should be helped!
you have to set your ImageView's layout gravity top i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP
Related
I have this layout:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="left" />
<TextView
android:id="#+id/button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="40dp" />
</LinearLayout>
Now, I want to modify gravity of the ImageView to left and gravity of the TextView to right. All other values present in xml (width, height, ...) must be preserved.
I tried:
1) setGravity method. Unfortunately, ImageView doesn't have this method. Why?
2)
LinearLayout.LayoutParams iconLayoutParams = new LinearLayout.LayoutParams(icon.getWidth(), icon.getHeight());
iconLayoutParams.gravity = Gravity.LEFT;
This somehow destroys View's dimensions
3)
android.view.ViewGroup.LayoutParams iconLayoutParams = icon.getLayoutParams();
This doesn't have gravity property.
(how is that even possible that icon.setLayoutParams() accepts layout parameters where gravity can be set and icon.getLayoutParams return some different kind of layout params without gravity property? That is a mess)
Can you please help me with that?
I think the easiest way to sort this out is using the 3rd approach but modify it slightly.
LinearLayout.LayoutParams iconLayoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams();
And then do:
iconLayoutParams.gravity = Gravity.LEFT;
Reason LayoutParams itself does not have Gravity is that not all containers have gravity. LinearLayout does, so you need to cast to LinearLayout.LayoutParams since you surely know that your container is LinearLayout. And the method getLayoutParams is in the View class so it must return the parent of all other LayoutParams, which again, does not have to have Gravity.
I hope I explained properly :)
I have an Android Flow layout hash_tag_layout
<org.apmem.tools.layouts.FlowLayout
android:id="#+id/hash_tag_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/view_padding"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin">
</org.apmem.tools.layouts.FlowLayout>
The problem is I cannot change the margins on dynamically added views.
int pixels = convertDensityPixelsToPixels(5);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(0,0,pixels,pixels); //<---<< This line has no effect
TextView tv1 = new TextView(ctx);
tv1.setPadding(pixels,pixels,pixels,pixels); //int left top right bottom
tv1.setBackground(ctx.getResources().getDrawable(R.drawable.hash_tag_bubble_format));//drawable
tv1.setText("# Asd");
tv1.setLayoutParams(lp);
layout.addView(tv1);
If I change hash_tag_layout layout to a regular linear layout, than I get margins!
<LinearLayout
android:id="#+id/hash_tag_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
So I am lead to conlude that Android Flow layout does not allow me to add margins to views added dynamically!
Any idea how to change the source code or find a way around this? Maybe add a transparent border around the dynamically added views?
Just change your LinearLayout.LayoutParams to FlowLayout.LayoutParams.
Here is an issue discussion on GitHub.
I see that you asked a question 3 years ago, but I have just faced the same problem :)
I'm trying to create a list of clickable image buttons w/ text that fit inside a HorizontalScrollView. The images/content will be set programmatically. The best way to do this seemed to be a LinearLayout, that then contained a series of RelativeLayouts that contained the views to display the relevant content. However, I'm having trouble getting space between each RelativeLayout. Even though I've set margins in xml and programmatically they seem to be ignored and the RelativeLayout objects are squished together.
Some code:
<RelativeLayout
android:id="#+id/details_image_button"
android:layout_width="75dp"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
android:background="#00ff78">
<ImageView
android:id="#+id/loadable_image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:id="#+id/details_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#b083ef"
android:text="PH - Info about title"
android:layout_alignParentBottom="true"
/>
//Code below is looped through several times
RelativeLayout imageButtonLayout = (RelativeLayout) inflater.inflate(R.layout.details_image_button, null);
RelativeLayout.LayoutParams imageButtonLayoutParams = new RelativeLayout.LayoutParams(100, 100);
imageButtonLayoutParams.setMargins(10, 10, 10, 10);
imageButtonLayout.setLayoutParams(imageButtonLayoutParams);
The current result that I am getting is a solid green (background color of the RelativeLayout) rather than the expected result of a group of RelativeLayouts with a space between each. How can I best get a margin or buffer between each RelativeLayout?
If your RelativeLayout is inside a LinearLayout, the LayoutParams you need to use would be LinearLayout.LayoutParams:
RelativeLayout imageButtonLayout = (RelativeLayout)
inflater.inflate(R.layout.details_image_button, null);
LinearLayout.LayoutParams imageButtonLayoutParams = new
LinearLayout.LayoutParams(100, 100);
imageButtonLayoutParams.setMargins(10, 10, 10, 10);
imageButtonLayout.setLayoutParams(imageButtonLayoutParams);
LayoutParams come from the parent, not the child.
Hi i am using following layout structure inside LinearLayout
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tv1"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="10dp"
android:textColor="#000" />
<TextView
android:id="#+id/tv2"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="right"
android:paddingRight="10dp"
android:textColor="#000" />
</TableRow>
</TableLayout>
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="320px"
android:layout_height="320px"
android:gravity="center" >
</RelativeLayout>
and want to set relative layout width and height dynamically from java file instead of setting it to 320px in the xml file but not able to do that , Orientation change is not an issue for as i restricting it to only in Portrait mode. It is possible to set the relative layout on full screen by using match_parent but i have to put another views on the screen so is it possible or i have to achieve it another way...
Android does NOT refresh layout of views with wrap_content once it has been displayed.
Even with invalidate() or requestLayout().
So if you add a child view, or modify the content dynamically, you're screwed.
getLayoutParams().height = x plus requestLayout() are a good solution if you know the "x", and if you need to do it ONLY ONCE.
After that the wrap_content in LayoutParams is lost, since you have overridden it.
To solve that, I've written a static class that recomputes the sizes and forces the update of the layout for the views with wrap_content. The code and instructions to use are available here:
https://github.com/ea167/android-layout-wrap-content-updater
Enjoy!
try using this
getLayoutParams().height= x;
requestLayout(); or invalidate();
give an id to your relative layout in .xml :
android:id="#+id/relativelayout"
now in your java file write this:
RelativeLayout Rl = (RelativeLayout) findViewById(R.id.relativelayout);
RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT or YourUserDefinedwidth,
RelativeLayout.LayoutParams.FILL_PARENT or YourUserDefinedHeight);
Rl.setLayoutParams(layout_description);
From below code u can get device height and width:-
Display display = getWindowManager().getDefaultDisplay();
int width = (display.getWidth() );
int height = (display.getHeight() );
paramsTop ur realative layout:-
Now u can set height or width what you want.
paramsTop = new RelativeLayout.LayoutParams(width, height);
You can set views dimensions dynamically using LayoutParams.
Something like this:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.yourlayout_id);
// Gets the layout params that will allow you to resize the layout
LayoutParams params = layout.getLayoutParams();
params.height = 320;
params.width = 320;
I faced this problem, the best solution for Change Relative layout width and height dynamically like this
RelativeLayout relMain = (RelativeLayout) convertView.findViewById(R.id.relMain);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.width =200;
params.height =200;
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
relMain.setLayoutParams(params);
If you intending to change Height, then this would make a trick.
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.yourId);
relativeLayout.getLayoutParams().height = 100;
relativeLayout.getLayoutParams().width = 100;
I encountered same issue when working with LinearLayout which has wrap_content and one child as TextView which had match_parent.
Remove the TextView programatically and then add it again.
linearLayout.removeView(textView)
linearLayout.addView(textView)
I know it sound stupid but it works.
In my case calling invalidate didn't work, only this worked.
Depending on your implementation you need to take care of view index inside its parent
I'm trying to add a textView to a frameLayout. The TextView has wrap_content properties, so it grows when the text grows. I'm adding it to a FrameLayout with this function:
((FrameLayout) findViewById(R.id.mainLayout)).addView(mEditText);
This is the xml of the frame layout:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</FrameLayout>
The textView always appears in the top left corner of the screen. I'd like to position it in the middle, or top middle. How can this be done?
I looked over the answers in How can I dynamically set the position of view in Android? and they weren't much help :( Mainly caused crashes..
Try this:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER);
((FrameLayout) findViewById(R.id.mainLayout)).addView(mEditText, params);
Change Gravity to suit your need.
BTW, the frame layout should use fill_parent for width and height
Try to gravity or Layout gravity to your Framelayout or the Textview. It makes your Layout to the center of the screen. Use like this,
android:layout_gravity="center"
or
android:gravity="center"
Add android:layout_gravity="center" in your frame layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
</FrameLayout>
you can try it by set the gravity of text use it like-
textview.setGravity(Gravity.center);
othervise by xml set gravity to center so it will display you in center and if you'll use centerinparents so it will always apperas at the center of screen.
Set FrameLayout properties android:layout_width and android:layout_height to fill_parent and also set TextView property LayoutGravity . such as Center, Right or Top.
Thanks
Setting the gravity programatically definitely works
Please set the layout_gravity to right in the xml
TextView.setGravity(Gravity.RIGHT);