Good Afternoon,
I am having trouble getting a RelativeLayout to work within a ListView. If I change the layout to linear etc. I see it behave as I would expect but the RelativeLayout is scrunching everything up into overlapping space. Now my uneducated guess is that it is trying to cram everything into on row. I thought it would expand that row but perhaps not or that is not the problem.
Note my code has been abbreviated for space.
Anyway in my Parent XML:
<LinearLayout ..._width="fill_parent" ..._height="fill_parent" ...orientation="vertical" >
<ListView ...layout_width="fill_parent" ...layout_height="fill_parent" />
</LinearLayout>
So my thought was that this would fill the device screen and in the GraphicalLayout view in Eclipse it appears that it does.
My "row" definition for the ListView is this:
<RelativeLayout width="fill_parent" height="fill_parent" >
<ImageView
android:layout_width="60dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_marginTop="15dp"
android:layout_marginLeft="5dp" />
.....
</RelativeLayout>
As mentioned I thought this would fill all available space but it seems to only fill some sort of "default" row height?
Not sure what I am missing but any help would be greatly appreciated.
use the layout attributes layout-above, layout-below, layout-toRightOf, layout-toLeftOf in your xml. that way the items will be put next to where you want them to go. right now you are setting everything according to the parent so they are all going to overlap
RelativeLayout by default adds it's children anchored to the top left corner of the layout.
By using the very handy attributes of RelativeLayout, you can arrange the children both
relatively to each other, and
relatively to the parent view.
layout_alignParentLeft, ..Right, ..Top, ..Bottom, layout_centerInParent, layout_centerHorizontal, layout_centerVertical, layout_toLeftOf, ..toRightOf, ..above, ..below
These attributes will help you get the desired display in a very efficient (flat) way, so I'd suggest keep reading it up and consider using it instead of other layout containers for complex views.
I ended up overriding the getView of the ArrayAdapter and then setting the height and width to the dynamically determined screen size
...snip....
int[] iarry_ScrnDim = new int[2];
DisplayMetrics metrics = new DisplayMetrics();
metrics = ctx_Currnt.getResources().getDisplayMetrics();
iarry_ScrnDim[0] = metrics.heightPixels;
iarry_ScrnDim[1] = metrics.widthPixels;
return iarry_ScrnDim;
....snip....
if (vw_BigRow == null)
{
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vw_BigRow = inflater.inflate(R.layout.liftdatalayout, null);
}
vw_BigRow.setMinimumHeight(mHeight);
vw_BigRow.setMinimumWidth(mWidth);
Related
I am developing an Android app. In my app, I need to inflate list of views dynamically. I added them and working. The problem is with setting the width and height of layout. Now I will demonstrate my problem with a simple project. Actually, my project is much more complicated than this simple project.
I am inflating views to this layout.
<LinearLayout
android:orientation="horizontal"
android:id="#+id/cm_photos_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
I am looping through a list of bitmap and adding view dynamically as follow
for(Bitmap bmp : bitmaps)
{
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
ImageView previewImageView = (ImageView)preview.findViewById(R.id.item_cm_preview_image);
previewImageView.setImageBitmap(bmp);
container.addView(preview);
}
Please note, in the above code, container is a LinearLayout added dynamically to the parent XML in the above.
container = new LinearLayout(this);
container.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
container.setLayoutParams(params);
parentLinearLayout.addView(container);
This is my item_cm_preview_image.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_weight="1"
android:layout_height="400dp"
android:layout_width="0dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:scaleType="centerCrop"
android:id="#+id/item_cm_preview_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
As you can see, I set the layout height to 400dp, width 0 and layout_weight to 1 in the XML. So all image height must be same and width must be equal because of layout_weight. But the result is not as expected. You can see screenshot below.
As you can see in the screenshot, both layout_weight and height are not working for all inflated views. But if I add extra ViewGroup dynamically and inflate the view to that layout, it is working. Below is my code
//This happening in for loop
LinearLayout wrapper = new LinearLayout(this);
wrapper.setLayoutParams(new LinearLayout.LayoutParams(0,500,1));
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
ImageView previewImageView = (ImageView)preview.findViewById(R.id.item_cm_preview_image);
previewImageView.setImageBitmap(bmp);
wrapper.addView(preview);
container.addView(wrapper);
This is the result:
As you can see both layout_weight and height working when I use an extra dynamic linear layout. Why is setting layout weight and height in XML not working? Why second way is working? How can I set weight and height in XML layout file? Is it possible?
If you inflate layout using method
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
it skip its width and height parameters..., but if you will use:
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,parent,false);
it should work correct, for example if you inflate view in activity as parent you can provide (ViewGroup) getView():
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,(ViewGroup) getView(), false);
I'm trying to implement a horizontal ListView using a HorizontalScrollView and adding 'items' to it within the code. Adding the items works fine. Now I want each item to be 1/7 of the ScrollView's width so I can display exactly 7 items without scrolling. I cannot figure out a way to get the width of the HorizontalScrollView.
My XML looks like this:
<HorizontalScrollView
android:id="#+id/information_popup_dialog_listScrollView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="7" >
<LinearLayout
android:id="#+id/information_popup_dialog_listParent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
I add an item like this:
LinearLayout listContainer = (LinearLayout) view
.findViewById(R.id.information_popup_dialog_listParent);
LinearLayout listItem = (LinearLayout) inflater.inflate(
R.layout.information_popup_dialog_list_item, listContainer,
false);
listItem.setLayoutParams(new LinearLayout.LayoutParams(
width, LayoutParams.MATCH_PARENT));
listContainer.addView(listItem);
When I use measure() to get the width of the ScrollView I get the total width, not the visible width. So it keeps growing with every item I add.
HorizontalScrollView scrollView = (HorizontalScrollView) view
.findViewById(R.id.information_popup_dialog_listScrollView);
scrollView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
System.out.println("Width: " + scrollView.getMeasuredWidth());
I tried different ways using .getLayoutParams().width / getWidth(), both return 0.
Is there anyway to do this?
I'm doing all of this in the onCreateView() method of a DialogFragment.
You can get device's screen width, and then divide it by 7. Now, set this number you get after dividing screen width, as the width of your each view in HorizontalScrollView. This way you can have exactly 7 items visible on your screen.
I haven't tried this, but it should work and it is pretty easy to do.
Use view.getWidth() in onViewCreated(). LayoutParameters.width will return the value you put in the XML.
If it's still not working , then you'll need to getWidth inside the view.post() method. This makes sure the view has been laid out.
I have a custom view which I add child views to dynamically.
When each child is added, I need to recalculate the size of the views so they can fit the parent's width
For example:
If I have a TextView:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:padding="8dp"
android:clickable="true"
android:textColor="#666666"
android:visibility="visible"/>
If I add three of these to a horizontal LinearLayout within the xml it correctly sizes the three views so the total widths match the parent.
But I want to inflate them one at a time and add them so can reuse elsewhere in the code if we want a different number of TextViews in a layout.
When I do this, the total width is less than its parent, and I can't get the views to resize when a new one is added.
Here's where I inflate the view:
layout = (LinearLayout) inflater.inflate(R.layout.segmented_control, this);
TextView item = (TextView) inflater.inflate(R.layout.segmented_control_item, null);
Change the width to match_parent, i think you need to keep the weight. Pass the parent layout to the inflater.
layout = (LinearLayout) inflater.inflate(R.layout.segmented_control, this);
TextView item = (TextView) inflater.inflate(R.layout.segmented_control_item, layout, false);
layout.addChild(item);
I'm not sure if that works right away, you might need to experiment a little with the layout paramters.
Change your TextView layout width to fill_parent and remove the weight. I think that it should work.
I there a way to wrap_content on a specific element inside of a parent element? For instance, I have something like the following layout:
<RelativeLayout width:match height:wrap>
<ImageView width:match height:wrap scale:fitXY />
<LinearLayout width:wrap height:wrap>
</RelativeLayout>
The parent wrap constraint is very loose, but I want it to specifically use the matching width, but always match the height of the image view.
The problem here arises when I place this view in another RelativeLayout where each view is aligned above or below another in order to fill a potentially changing superview. LinearLayout didn't really seem to stretch things to fill, so I switched to Relative, but when I did, the view described above stretched vertically when I want it to still match the height of the image view.
Is there a good solution to this problem?
You could try putting the following (pseudocode) in the onResume() method:
if(myRelativeLayout.height > myImageView.height)
myRelativeLayout.setHeight(myImageView.height);
You need to make sure to call myRelativeLayout.measure() before you do this, so the system knows what the size of the Views will be.
Just an idea for you to try, let me know if it works :)
I have a small project where I want to reuse a certain UI component a few time so I created a widget by expanding a ViewGroup. In that ViewGroup I inflated a view that contained a TextView inside a LinearLayout and added that inflated view to the ViewGroup trough addView.
The outer LinearLayout expands itself perfectly but the inner TextView have getHeight() = 0 and getWith() = 0 when I view it through Hierarchy Viewer. The strange thing is that layout_height and layout_width is the values I gave them in my xml.
I don't have the code here but it looked something like this:
xml:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="random text.."
android:layout_with="200px"
android:layout_height="50px" />
</LinearLayout>
Java:
class MyWidget extends ViewGroup {
...
//In constructor
myView = View.inflate(context, R.layout.xml, null);
addView(myView);
//In layout
myView.layout(l, t, r, b);
I have tried to give my text view fill_parent values for size but it didn't help.
Remember:getHeight() and getWidth()return 0 if components are not drawn yet.
To find the width And height of a View before it being drawn:
First call measure
view.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)
Now you can get width using getMeasuredWidth and height using getMeasuredHeight
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
I have posted some more ideas here: How to get width/height of a View
1) Here is some links to use Hierarchy Viewer on your dev phone.
http://developer.android.com/guide/developing/debugging/debugging-ui.html
and the class you'll need:
http://github.com/romainguy/ViewServer
2) You can also reuse layout like a component with the include tag:
<include android:id="#+id/your_id" layout="#layout/layout_name" />
So, I put a bounty on this one, and here is what I've found.
Inflating with a null reference is A Bad Idea(TM). Essentially, that View won't get the proper layout parameters it needs (its parent sets a whole bunch of them, with a whole bunch of magic/logic involved). So inflating into null means no parents, and no inherited layout parameters. One can manually set a number of these parameters, but due to the magic involved it might not solve your problem.
The "solution(s)" that I've come up with involve; using include (when you know how many you need) and pulling them into code, or inflating to a parent (when you need true dynamic, N things). And of course, the XML you inflate will have ID collisions, so I go about it by grabbing the last child (e.g. getChildAt(getChildCount()-1) ) of whatever I'm looking for, etc.
Did you try passing yourself as the root:
View.inflate(context, R.layout.xml, this);
Since you will be the parent of this View that complies with the javadoc spec.