I want to create vertical LinearLayout with couple of Button children, where each child has width of widest of them.
However depending on using MATCH_PARENT or WRAP_CONTENT for children width, I get either LinearLayout taking whole screen's width, or Buttons not filling LinearLayout. Screenshots below (fill/wrap):
Example Activity code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout mainView = new RelativeLayout(this);
mainView.setBackgroundColor(Colors.WHITE);
String[] buttonsNames = new String[] { "Short", "Looooooong", "Medium" };
View buttonsView = getButtonsView(buttonsNames);
mainView.addView(buttonsView, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
setContentView(mainView);
}
private View getButtonsView(String[] buttonNames) {
LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
buttonsView.setBackgroundColor(Colors.BLACK);
for (int i = 0; i < buttonNames.length; i++) {
Button button = new Button(this);
button.setText(buttonNames[i]);
///////////// HERE LAYS THE PROBLEM //////////
buttonsView.addView(button, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
//LinearLayout.LayoutParams.WRAP_CONTENT, // neither of them works
LinearLayout.LayoutParams.WRAP_CONTENT));
View redLineDivider = new View(this);
redLineDivider.setBackgroundColor(Colors.RED);
buttonsView.addView(redLineDivider, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 2));
}
return buttonsView;
}
As you can see on second screenshot, red lines actually take whole width without stretching LinearLayout - it is because at least one view has set width.
Potential fix I have came up with is to find widest button (with longest text) and make it use WRAP_CONTENT, while all the rest use MATCH_PARENT, which gives me expected result:
Code:
buttonsView.addView(button, new LinearLayout.LayoutParams(
isLongestText(i) ? LinearLayout.LayoutParams.WRAP_CONTENT
: LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
It doesn't feel like elegant solution though - is there any intended mechanism for situation like this, that I am missing out?
Following is the trick:
Mention the width of the LinearLayout containing the buttons (buttonsView in your code) as WRAP_CONTENT.
Mention the width of each button as MATCH_PARENT
Your program should give you the expected result if you do not include the redLineDivider View. There seems to be some issue with setting the width of redLineDivider. As an alternative you can declare it as a LinearLayout to make your code work perfectly.
// View redLineDivider = new View(this);
// Instead declare it as a LinearLayout
LinearLayout redLineDivider = new LinearLayout(this);
Hope this will be useful.
I am getting stucked on the following problem:
For a questions app I want to implement a nice output for a survey showing the possible answers and the percentage of people answered the specific question. Therefore, I want to add a "bar" to my app that displays the percentage. I try to solve this by using views and weighting them in a linear layout.
I want to add the different answers programmatically, this is the code I've got so far.
My problems are, that I am not getting closer to weighting the views and resizing them.
/* Add all questions */
RelativeLayout my_root = (RelativeLayout) findViewById(R.id.ownerRL);
/* Add a new Linearlayout as a container for the question */
LinearLayout A = new LinearLayout(this);
A.setOrientation(LinearLayout.HORIZONTAL);
my_root.addView(A);
/* Create a new View in this container, for the status bar */
View new_view = new View(getBaseContext());
new_view.setBackgroundColor(Color.YELLOW);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(50, 20, 3);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) A.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.question1);
A.addView(new_view);
View new_view2 = new View(getBaseContext());
new_view.setBackgroundColor(Color.GREEN);
ViewGroup.LayoutParams lp2 = new ViewGroup.LayoutParams(50, 20);
RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) A.getLayoutParams();
params2.addRule(RelativeLayout.BELOW, R.id.question1);
params2.addRule(RelativeLayout.LEFT_OF, new_view.getId());
A.addView(new_view2);
The Green view should actually be right of the yellow one (which is not visible).
How do get it managed such that it creates a red/white bar that has a height of 4px and the red and weight parts are weighted?
Thanks for your help!
check this link, Set Linear Layout weight it like this
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT, 1.0f);
The last parameter is weight.Hope this help.
I'm trying to programmatically add an ImageView then add another one that is relative to this one. My code:
RelativeLayout mLayout = (RelativeLayout) findViewById(R.id.myLayout);
ImageView anchor = new ImageView(getApplicationContext());
anchor.setImageDrawable(getResources().getDrawable(R.drawable.anchor));
anchor.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams anchorParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
anchorParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
anchorParams.addRule(RelativeLayout.CENTER_VERTICAL);
mLayout.addView(anchor,anchorParams);
ImageView spinner = new ImageView(getApplicationContext());
spinner.setImageDrawable(getResources().getDrawable(R.drawable.image1));
spinner.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams spinnerParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
spinnerParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
spinnerParams.addRule(RelativeLayout.BELOW,anchor.getId());
mLayout.addView(spinner,spinnerParams);
The first image is just where I want it - centralized - but the second one doesn't appear below the anchor, instead it appears at the top of the screen, just below the status bar.
Did I miss anything?
i think, you get null for anchor.getId(). Set a Id for your anchor view, before addRule()
I believe you need to programmatically give anchor an id before you can use anchor.getId() using anchor.setId(int).
It is difficult to say what is wrong, try to make XML and add it
LinearLayout myLayout = (LinearLayout) findViewById(R.id.LogoView);
View hiddenInfo = getLayoutInflater().inflate(R.layout.search,
myLayout, false);
myLayout.removeAllViews();
myLayout.addView(hiddenInfo);
My question is simple,
How to set my buttons layout_gravity programmatically?
I found this on internet, but it simply throws me a Nullpointer exception:
Button MyButton = new Button(this);
LinearLayout.LayoutParams lllp=(LinearLayout.LayoutParams)MyButton.getLayoutParams();
lllp.gravity=Gravity.RIGHT;
MyButton.setLayoutParams(lllp);
MyLinearLayout.addView(MyButton);
Any solution?
Java
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
params.gravity = Gravity.TOP;
button.setLayoutParams(params);
Kotlin
val params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply {
weight = 1.0f
gravity = Gravity.TOP
}
For gravity values and how to set gravity check Gravity.
Basically, you should choose the LayoutParams depending on the parent. It can be RelativeLayout, LinearLayout etc...
I'd hate to be resurrecting old threads but this is a problem that is not answered correctly and moreover I've ran into this problem myself.
Here's the long bit, if you're only interested in the answer please scroll all the way down to the code:
android:gravity and android:layout_gravity works differently. Here's an article I've read that helped me.
GIST of article: gravity affects view after height/width is assigned. So gravity centre will not affect a view that is done FILL_PARENT (think of it as auto margin). layout_gravity centre WILL affect view that is FILL_PARENT (think of it as auto pad).
Basically, android:layout_gravity CANNOT be access programmatically, only android:gravity.
In the OP's case and my case, the accepted answer does not place the button vertically centre.
To improve on Karthi's answer:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
button.setLayoutParams(params);
Link to LinearLayout.LayoutParams.
android:layout_gravity shows "No related methods" meaning cannot be access programatically.
Whereas gravity is a field in the class.
I had a similar problem with programmatically setting layout_gravity on buttons in a GridLayout.
The trick was to set gravity on the button layoutParams AFTER the button was added to a parent (GridLayout), otherwise the gravity would be ignored.
grid.addView(button)
((GridLayout.LayoutParams)button.getLayoutParams()).setGravity(int)
MyButton.setGravity(Gravity.RIGHT);
For layout_gravity use the answer stated by "karthi". This method sets gravity to place the children inside the view.
layoutParams2.gravity = Gravity.RIGHT|Gravity.BOTTOM;
use this to add mor than one gravity
If you want to change the layou_gravity of an existing view do this:
((FrameLayout.LayoutParams) view.getLayoutParams()).gravity = Gravity.BOTTOM;
Remember to use the right LayoutParams based on the Layout type your view is in. Ex:
LinearLayout.LayoutParams
KOTLIN setting more than one gravity on FrameLayout without changing size:
// assign more than one gravity,Using the operator "or"
var gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
// update gravity
(pagerContainer.layoutParams as FrameLayout.LayoutParams).gravity = gravity
// refresh layout
pagerContainer.requestLayout()
This question is old but I just had the same problem and solved it like this
LayoutParams lay = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)
lay.gravity = Gravity.CENTER;
I use someting like that: (Xamarin and C# code)
LinearLayout linLayout= new LinearLayout(this);
linLayout.SetGravity(GravityFlags.Center);
TextView txtView= new TextView(this);
linLayout.AddView(txtView);
the SetGravity puts my textView in the center of the layout.
So SetGravity layout property refer to layout content
In case you need to set Gravity for a View use the following
Button b=new Button(Context);
b.setGravity(Gravity.CENTER);
For setting layout_gravity for the Button
use gravity field for the layoutparams as
LayoutParams lp=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.gravity=Gravity.CENTER;
try this
hope this clears
thanks
If you want to put a view in the center of parent, you can do with following code..
public class myLayout extends LinearLayout {
public myLayout(Context context) {
super(context);
RelativeLayout vi = (RelativeLayout) ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.activity_main, null);
LinearLayout.LayoutParams cc = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
cc.gravity = Gravity.CENTER;
this.setGravity(Gravity.CENTER);
this.addView(vi);
}
}
these code section make LinearLayout put the first view elements in the center of parent.
So, we system don't consider the initial width and high to arrange view in the center .
I do the code section well.
The rest of the answers are right, I want to add more explaination. The layout_gravity is about how to position the view in parent view.
You must set gravity **after method parentView.addView() ** was called. We can see the code:
public void setLayoutParams(ViewGroup.LayoutParams params) {
if (params == null) {
throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;
resolveLayoutParams();
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onSetLayoutParams(this, params);
}
requestLayout();
}
And the problem of null pointer is because it's not calling addView before getLayoutParams().
The annotation was already said "This method may return null if this View is not attached to a parent ViewGroup or {#link#setLayoutParams(android.view.ViewGroup.LayoutParams)} was not invoked successfully. When a View is attached to a parent ViewGroup, this method must not return null."
to RelativeLayout, try this code , it works for me:
yourLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
Perfectly Working!!! None of the above answer works for me. In Xml file setting gravity and setting layout_gravity is different. Check out the below code
// here messageLL is the linear layout in the xml file
// Before adding any view just remove all views
messageLL.removeAllViews();
// FrameLayout is the parent for LinearLayout
FrameLayout.LayoutParams params = new
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.CENTER|Gravity.CENTER_VERTICAL;
messageLL.setLayoutParams(params);
messageText.setVisibility(View.GONE);
messageNoText.setVisibility(View.VISIBLE);
messageLL.addView(messageNoText);
Also check This,where you can find clear explanation about gravity and layout_gravity .
Most of above answer are right, so written a helper methods, so you can use it
directly in you project .
set layout_gravity programmtically
// gravity types : Gravity.BOTTOM, Gravity.START etc.
// view : can be any view example : button, textview, linearlayout, image etc.
// for single view
public static void setLayoutGravity(int gravity, View view){
((LinearLayout.LayoutParams) view.getLayoutParams()).gravity = gravity;
}
// for mulitple views
public static void setLayoutGravity(int gravity, View ...view){
for(View item : view)
((LinearLayout.LayoutParams) item.getLayoutParams()).gravity = gravity;
}
Modify the existing layout params and set layout params again
//Get the current layout params and update the Gravity
(iv.layoutParams as FrameLayout.LayoutParams).gravity = Gravity.START
//Set layout params again (this updates the view)
iv.layoutParams = layoutParams
I switched from LinearLayout.LayoutParams to RelativeLayout.LayoutParams to finally get the result I was desiring on a custom circleview I created.
But instead of gravity you use addRule
RelativeLayout.LayoutParams mCircleParams = new RelativeLayout.LayoutParams(circleheight,circleheight);
mCircleParams.addRule(RelativeLayout.CENTER_IN_PARENT);
int width=getResources().getDisplayMetrics().widthPixels;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
(width, width);
params.gravity = Gravity.CENTER;
iv_main_text = new HTextView(getContext());
iv_main_text.setLayoutParams(params);
iv_main_text.setBackgroundColor(Color.BLUE);
iv_main_text.setTextSize(60);
iv_main_text.setGravity(Gravity.CENTER);
iv_main_text.setTextColor(Color.BLACK);
FloatingActionButton sendFab = new FloatingActionButton(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(32, 32, 32, 32);
layoutParams.gravity = Gravity.END|Gravity.BOTTOM;
sendFab.setLayoutParams(layoutParams);
sendFab.setImageResource(android.R.drawable.ic_menu_send);
Try this code
Button btn = new Button(YourActivity.this);
btn.setGravity(Gravity.CENTER | Gravity.TOP);
btn.setText("some text");
or
btn.setGravity(Gravity.TOP);
I created a custom view. In it, theres a line, a textview, another line. beneath the bottom line, i wanted to put a new horizontally oriented linearlayout. when i run it, this nested linearlayout doesnt seem to show up at all. Instead, i can see the test button right underneath the bottom line. what am i doing wrong?
public class MyView extends LinearLayout {
public MyView(Context context, Question question) {
super(context);
// this.setLayoutParams(params);
this.setOrientation(VERTICAL);
this.setBackgroundColor(Color.WHITE);
LinearLayout.LayoutParams lineParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 2);
View topLine = new View(context);
lineParams.setMargins(0, 15, 0, 0);
topLine.setBackgroundColor(Color.argb(255, 0, 159, 218));
topLine.setLayoutParams(lineParams);
this.addView(topLine);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
//Challenge Question
TextView questionText = new TextView(context);
questionText.setTextColor(Color.BLACK);
questionText.setTextSize(14);
questionText.setLayoutParams(params);
questionText.setGravity(Gravity.CENTER_HORIZONTAL);
questionText.setText(question.getQuestion());
this.addView(questionText);
View bottomLine = new View(context);
bottomLine.setBackgroundColor(Color.argb(255, 0, 159, 218));
bottomLine.setLayoutParams(lineParams);
this.addView(bottomLine);
LinearLayout innerLayout = new LinearLayout(context);
LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(300, LayoutParams.WRAP_CONTENT);
innerLayout.setLayoutParams(innerLayoutParams);
innerLayout.setBackgroundColor(Color.RED);
innerLayout.setOrientation(HORIZONTAL);
//TableLayout for the multiple choices
TableLayout tableLayout = new TableLayout(context);
LayoutParams tableLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// tableLayoutParams.weight = .8f;
tableLayout.setBackgroundColor(Color.RED);
tableLayout.setLayoutParams(tableLayoutParams);
innerLayout.addView(tableLayout);
this.addView(innerLayout);
Button button = new Button(context);
button.setLayoutParams(params);
button.setText("testing 123");
this.addView(button);
}
Note that I pasted the code without all the stuff that I added to the tablelayout. I probably should have pasted that too. But it didn't work when I did that either. but either way, if i set the nested linearlayout to 300 width and set a background color of red to it, i should at least see it, no?
Think about what the height of the inner layout should be. Right now it is wrap_content and contains a TableLayout (with no rows) with its height also set to wrap_content. There doesn't seem to be anything in that inner layout giving it a height dimension, so that may be why it is not being displayed.
Trying the following will make your layout visible:
LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(300, 300);
More usefully, you can try adding something with a real width/height to the TableLayout.
Also consider writing your layout in XML to better separate your application logic and the presentation.