How do I get space between consecutive RelativeLayouts inside a LinearLayout? - android

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.

Related

Adding a few TextViews on RelativeLayout

I'm trying to programmatically add many TextView to a RelativeLayout but I am unable to do that when TextView reach the end of the display right next TextView inflate in a new line.
RelativeLayout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/tag_cloud"
android:padding="10dp">
</RelativeLayout>
Code:
if (categoriesCursor.moveToFirst()){
do {
TextView tagElement = (TextView) getLayoutInflater().inflate(R.layout.tag, null);
tagElement.setText(categoriesCursor.getString(2));
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
llp.setMargins(0, 0, pixels, pixels); // llp.setMargins(left, top, right, bottom);
tagElement.setLayoutParams(llp);
tagCloudLayout.addView(tagElement);
} while (categoriesCursor.moveToNext());
}
tag.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"
android:textColor="#ff000000"
android:textStyle="bold"
android:paddingLeft="5dp"
android:paddingRight="5dp"/>
Thanks
It´s not really clear what You are asking, but If I understand You the right way, You want to have only one line with textViews, or? Also, You are using wrong Layout Params, if You want to add some views to a relativeLayout side by side, I think You will get it with:
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 1.0f);
Where the last parameter stands for the layout weight attribute. With LayoutWeight and MATCH_PARENT, all views will be drawn with equal size.
Consider using a ListView which contains TextView, and that way you'll be able to take advantage of cell re-use etc. Here's a good tutorial
Finally I put one LinearLayout vertical oriented and inside LinearLayouts horizontal oriented with three TextView inside. Isn't the best solution but it works for me.

Programmatically set TextView gravity right in a TableRow

I know this has been asked several times over, but can't seem to get it to work correctly in my situation. I am trying to get the last column to align right in a table that is generated programatically. I know I need to apply the LayoutParams to the row and all the inner children, and I know that I need to set the Gravity to the TextView, not the row, but I have tried all the permutations I can think of and can't seem to get the last column to align right.
Here is my XML layout:
<!--Open Hours-->
<LinearLayout
android:id="#+id/llOpenHourDetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/llWebsiteDetail"
android:paddingBottom="10dp"
android:visibility="gone"
android:weightSum="4">
<TextView
android:id="#+id/tvOpenHourDetailIcon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="#string/fa_clock"
android:textColor="#color/cp_blue" />
<TableLayout
android:id="#+id/tlOpenHoursDetail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3" />
</LinearLayout>
And then in my activity I have the following code in a loop
String currentPeriod = formattedOpen.format(open.getTime()) + " - " +
formattedClose.format(close.getTime());
TableRow.LayoutParams params = new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT );
TableRow tableRow = new TableRow(getBaseContext());
tableRow.setLayoutParams(params);
TextView tvDayOfWeek = new TextView(getBaseContext());
tvDayOfWeek.setText(open.getDisplayName(
Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault()));
tvDayOfWeek.setTextColor(getResources().getColor(R.color.black));
tvDayOfWeek.setLayoutParams(params);
tableRow.addView(tvDayOfWeek);
TextView tvPeriodHours = new TextView(getBaseContext());
tvPeriodHours.setText(currentPeriod);
tvPeriodHours.setTextColor(getResources().getColor(R.color.black));
tvPeriodHours.setGravity(Gravity.RIGHT);
tvPeriodHours.setLayoutParams(params);
tableRow.addView(tvPeriodHours);
tlOpenHoursDetail.addView(tableRow);
In order for setGravity() to work you must first modify the width field of yourTextView as follows in your layout:
android:layout_width="fill_parent"
Now you should be able to call:
tvPeriodHours.setGravity(Gravity.RIGHT)
I think there are two ways of doing this.
If your TableLayout has a width not based on it's contents (such as if the columns widths are set using android:stretchColumns) you can set the TextView width to match_parent and then assign the gravity on the TextView using textView.setGravity(Gravity.END).
If your TextView width is smaller than the bounds of the TableLayout cell you can call the gravity on the TableRow instead using tableRow.setGravity(Gravity.END).
I have a TableLayout where my TextViews fill the width of the cell but not the height so I'm using:
textView.setGravity(Gravity.CENTER);
tableRow.setGravity(Gravity.CENTER_VERTICAL);
To get my text in the very centre of the cell.
In case it helps anyone, I have spent ages trying to get the TextView aligned to the bottom of the cell but nothing seems to work, including tableRow.setGravity(Gravity.CENTER_VERTICAL), no idea why but I have given up and in the centre is fine.

Android layouts not displaying as intended

I need to create one full screen android activity programatically as shown in the image below:
The two buttons should remain at the bottom of the screen.
Dummy content will consist of different components (textviews, radio buttons, checkboxes...) and will be populated dynamically.
This is the code I have so far:
//Main Layout
FrameLayout lLayout = new FrameLayout(this);
lLayout.setBackgroundColor(Color.parseColor("#0099cc"));
lLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
//Navigation layout
LinearLayout l = new LinearLayout(this, null, R.style.ButtonBar);
LayoutParams bottomLayout = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
l.setLayoutParams(bottomLayout);
l.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
l.setBackgroundColor(Color.parseColor("#66000000"));
l.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams buttLayout = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//previous section button
previousButton = new Button(this);
previousButton.setLayoutParams(buttLayout);
previousButton.setText("Previous section");
previousButton.setOnClickListener(this);
l.addView(previousButton);
//next section button
Button nextButton = new Button(this);
nextButton.setLayoutParams(buttLayout);
nextButton.setText("Next section");
nextButton.setOnClickListener(this);
l.addView(nextButton);
//add components
TextView tView = new TextView(this);
tView.setText("Dummy text");
tView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
lLayout.addView(tView);
lLayout.addView(l);
setContentView(lLayout);
Here is what the code produces:
Tthere are several points that do not work as intended:
1. Buttons are at the top and not the bottom.
2. Buttons do not spread out nicely
3. TextView I added as a test is shown behind the buttons. I will have many different widgets on the screen and expect them to be larger than one screen. I would like to have a scroll option but with all those widgets not to be seen behind the two buttons that are supposed to be at the bottom of the screen.
The following xml is exactly what you would need:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/dynamiclayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/navigationlayout"
android:orientation="vertical" >
</LinearLayout>
<RelativeLayout
android:id="#+id/navigationlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Previous Section" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Next Section" />
</RelativeLayout>
</RelativeLayout>
Now programatically inflate dynamiclayout and add all your dynamic views into it.
Your root view is a FrameLayout, which is intended for only one child View. It is also frequently used to create overlapping Views, as all of a FrameLayout's children will be drawn in the same place on screen.
Replace your FrameLayout with a RelativeLayout. Make sure you update your LayoutParams references to use RelativeLayout.LayoutParams. You will also need to set the navigation LinearLayout to align with the parent View's bottom like so:
RelativeLayout.LayoutParams lps = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lps.addRule(RelativeLayout.LayoutParams.ALIGN_PARENT_BOTTOM, true);
Though I really would suggest using XML. It will make your life far simpler.

View overlapping another view in LinearLayout

I have a wierd problem.
I define a LinearLayout with vertical orientation.
I define an ImageView and another custom View.
if I add the custom one and then the image, all is fine and I see both of them.
if I add the image one first, I see only the image.
I try any variation of LayoutParams and nothing worked.
what I'm doing wrong here?
Edit - I even tried some default button to check its not my custom view that causing this
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = new LinearLayout(getApplicationContext());
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
ImageView image = new ImageView(getApplicationContext());
image.setImageDrawable(getResources().getDrawable(R.drawable.image_strip));
Button button = new Button(getApplicationContext());
button.setText("test");
layout.addView(image, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
layout.addView(button, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setContentView(layout);
}
I found a way, but its still has an issue.
I used RelativeLayout, and aligned the button to the bottom of the parent (the layout) and I set the image to be above the button.
now I see both of them, but the problem now is that the image width also shrinks
How big is your image? If its bigger than the view area, its going to push the button off screen. If the button is first, you'll see it. If the button is after the image, you won't. That would be my first guess. You could wrap the whole thing (the parent LinearLayout) in a ScrollView to see if its doing that. If so, you'll need to clip the image somehow.
If the image is bigger than the screen size, try the following. Create the parent LL as you have it, then create a ScrollView and add the image inside that. Set the layout_weight of the ScrollView to 1 (or whatever), and DON'T set the layout_weight of the button. This should force the ScrollView to take up as much space as possible, but leave room for the button, and allow you to scroll to see the image.
I don't have good code off hand for doing this in code. I do most layout in XML (and not to pontificate, but I'd suggest the same for you ;)
<ProgressBar
android:layout_height="50dp"
android:layout_width="50dp"
android:id="#+id/myprogress"
android:layout_gravity="center_horizontal"
android:visibility="gone"
style="#android:style/Widget.Holo.Light.ProgressBar.Small"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title" />
<ImageView
android:layout_height="165dp"
android:id="#+id/imageView1"
android:layout_width="125dp"
android:scaleType="fitXY"
android:visibility="invisible"
android:layout_marginTop="-30dp"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
Check for the above layout of progressbar and imageview. What I wanted was to overlap the imageview over progressbar and I achieved the same by setting android:layout_marginTop="-30dp" to imageview

FrameLayout margin not working

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

Categories

Resources