I have a custom component where I know the width and height is always as follows:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
I would like to avoid having to specify the width and height in XML since any other settings are wrong.
I've tried a lot of things, but nothing works. For example, this code doesn't work:
public class MyLayout extends ViewGroup {...
LayoutParams layoutParams =
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
setLayoutParams(layoutParams);
but no matter what I do, I get the exception message "You must supply a layout_width attribute." which goes away if I put back the XML layout_width, layout_height.
I've also tried to Override onFinishInflate(), but that never gets called. I tried inheriting from View, ViewGroup and TableLayout. I've tried calling getLayoutParams(), but it returns null.
How do I get my custom component to not need these specified in XML?
Please no snark.
Thanks.
You have the answer,
LayoutParams layoutParams = new LayoutParams(width, height);
setLayoutParams(layoutParams);
height and width are specified in px, dip, sp
Alternatively, some of them provide with setHeight and setWidth methods, you can use them.
Related
I read often something like this:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
What exactly LayoutParams do?
I've read the Documentary but I wasn't smarter after reading!
Hope someone can explain me what LayoutParams do or pass!
Kind Regards!
LayoutParams are the Java Object representation of all the params you give to your View in the .xml layout file, like layout_width, layout_height and so on. Getting this object from a View allows you to look up those params on runtime, but also to change them in your Java code, when you need to move the View, change it's size etc.
LayoutParams are used by views to tell their parents how they want to be laid out.
The base LayoutParams class just describes how big the view wants to be for both width and height. For each dimension, it can specify one of:
FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which means that the view wants to be as big as its parent (minus padding)
WRAP_CONTENT, which means that the view wants to be just big enough to enclose its content.
That's all folks.
LayoutParams is use for the dynamically change the layout width and height. and also use the create custom view without the xml by using the directly by use of the LayoutParams for Relative or Linear type layout.
Basically when you set an xml with 'match_parent' or anything like layout_something
the android inflator will set the layout param for the child with the appropriate Layout params with the type matching the parent control, you could also do this in code and if you forget or set the wrong type you will get an exception in runtime.
the parent control needs this information to layout the child control correctly and to his liking.
Please see the following: Android Developer site - Layout Params
I think this picture says it all
How can i get the dynamic width of LinearLayout at runtime?
I mean, i want to get the width of LinearLayout at runtime , when LinearLayout visibility is "GONE" and LinearLayout width is "match_parent" in xml layout file.
I can get width using onGlobalLayoutChangeListener and onPreDrawListener but only if our view(LinearLayout) is already "VISIBLE" state, not at "GONE" state.
Is here any solution for this problem?
Thank you so much for your time.
Simply fetch a reference to your linearlayout lets call it "ll" and a call to "ll.getWidth()" gives you thewidth in pixels...
You can use getMeasuredWidth() method:
int width = yourView.getMeasuredWidth();
PS: Be careful, you need to call it after onMeasure() gets executed, otherwise the view size is not yet measured.
I must be missing something really stupid.
I have a LinearLayout in my view:
_editTextViews = (LinearLayout)findViewById(R.id.editDesAndLocViews);
I am trying to dynamically change the height of that view by setting the LayoutParams
I have two LinearLayout.LayoutParams
LinearLayout.LayoutParams collapsedParams;
LinearLayout.LayoutParams openParams;
that are set in the constructor like so:
collapsedParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,0);
openParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
But as soon as i try to apply one of those params to my LinearLayout, like so:
_editTextViews.setLayoutParams(collapsedParams);
I get the following FATAL EXCEPTION:
At first i thought my project needed to be cleaned as it seems to think i am trying to force a relative layout to use linear layout params, but everything is LinearLayout. The LinearLayout in question does contain a couple RelativeLayouts. I don't know if / why that would be the problem.
please help
Change your LayoutParamss' type to either ViewGroup.LayoutParams or RelativeLayout.LayoutParams.
The LayoutParams you apply have to match the parent layout of the view. LayoutParams define how a View is layed out in its parent view (layout). Because each layout type takes different parametres for laying out a view (e.g. only LinearLayout has weight, only RelativeLayout can use anchors), they all have their own LayoutParams.
I have an XML definition for a view that I am adding to a larger container view with addChild. It's based on a LinearLayout and looks basically like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="52dip"
android:background="#drawable/box_bg"
android:clickable="true"
android:onClick="onTreeBoxClick"
android:orientation="horizontal" >
<ImageView android:id="#+id/box_photo"
android:layout_width="45dip"
android:layout_height="45dip"
...
/>
<RelativeLayout
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
>
(Remainder omitted -- probably not relevant since it's basically working as designed)
When I create these views, I have found the following behaviors that seem odd to me:
Right after I inflate the view, getLayoutParameters() returns null.
After I call addChild() to add it to its parent, getLayoutParameters() returns a valid object.
Examining the LayoutParameters, I find both width and height set to -2 (WRAP_CONTENT), which is clearly not what I specified in the XML file.
When I look at the layout parameters of the enclosed ImageView, it reads out at the specified values.
Can anyone explain what is going on here? Why isn't my specified height being noticed?
This isn't really affecting me since the parent view is a custom view wherein I force the final dimensions of the children with MeasureSpec etc., but I'd like to understand this anyway!
You didn't provide some details which are important.
1) Right after I inflate the view, getLayoutParameters() returns null.
I would assume that you used this:
inflater.inflate(R.layout.content, null);
in this case the LayoutInflater can't make(at all) proper LayoutParams for the root Linearlayout because it doesn't know who is going to be its parent(so it can create the right type of LayoutParams). If you would use this:
inflater.inflate(R.layout.content, someOtherLayout, false/true);
then the root LinearLayout will have proper LayoutParams because it will see the type of someOtherLayout and create the LayoutParams from this information. You may want to provide a snippet of code to get a better answer if this is not what you currently do.
2) After I call addChild() to add it to its parent,
getLayoutParameters() returns a valid object.
I assume that you speak about the addView() method. The addView() method will check the LayoutParams of the view which is trying to add and if those LayoutParams are null then it will automatically assign that view a LayoutParams object returned by its generateDefaultLayoutParams() method.
3) Examining the LayoutParameters, I find both width and height set to
-2 (WRAP_CONTENT), which is clearly not what I specified in the XML file.
As I said at 2, the generated LayoutParams are coming from the generateDefaultLayoutParams() method which will return a LayoutParams instance as the parent was designed to do. For example, a LinearLayout with orientation HORIZONTAL(the default one) will return a LayoutParams instance with width/height set to WRAP_CONTENT.
4) When I look at the layout parameters of the enclosed ImageView, it
reads out at the specified values.
Because the LayoutInflater took care of this, as the ImageView it's in the interior of the layout and has a known parent from which the LayoutInflater can make the proper LayoutParams.
I have a custom view which will be jar'ed up and added into another project. In the view I want to give an option of a button.
Here is what I have in the CustomView class.
final CustomView currentView = (CustomView) findViewById(this.getId());
RelativeLayout.LayoutParams params = (new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT ));
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
closeButton.setLayoutParams(params);
currentView.addView(closeButton);
This is all wrapped in a RelativeLayout Tag as well as the other objects of the application
Everything compiles however in the CustomView the Button is aligning left instead of right.Any Ideas???
I would guess the problem is your CustomView. It probably doesn't take the entire width of the window, and is just wide enough to fill its children (which, in your case, is the close button). Make sure your CustomView has a fill_parent horizontal layout.
Since your CustomView extends WebView, which, in turn, extends AbsoluteLayout, you can't expect it to handle RelativeLayout's parameters. Instead, it's best you put your customview and your close button inside a RelativeLayout and position them properly.
When adding your closeButton to your currentView you need to supply the LayoutParams as an argument as well in order for them to take effect.
Basically, switch
currentView.addView(closeButton);
with
currentView.addView(closeButton, params);
Since the width of your button is set to wrap_content, you could also try setting its layout_gravity to right.
params.gravity = Gravity.RIGHT;