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.
Related
I'm creating the above popup, the content of which consists of rows of horizontal LinearLayout views within a main vertical LinearLayout. Each horizontal LinearLayout contains one ImageView and one TextView.
I'm creating this within a PopupWindow, and doing so programmatically so that I can change the ImageView source as required.
As you can see the first icon seems to take up a lot of space, despite having the same code generating it as the other icons.
Below is the code:
LinearLayout verticalLayout = new LinearLayout(context);
verticalLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams mainLayoutParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
verticalLayout.setLayoutParams(mainLayoutParams);
LinearLayout.LayoutParams layoutParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams iconParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams textParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//History row
LinearLayout historyLayout = new LinearLayout(context);
historyLayout.setLayoutParams(layoutParams);
historyLayout.setOrientation(LinearLayout.HORIZONTAL);
ImageView historyIcon = new ImageView(context);
historyIcon.setImageResource(R.drawable.small_book_grey);
historyIcon.setAdjustViewBounds(true);
historyIcon.setLayoutParams(iconParams);
historyLayout.addView(historyIcon);
TextView historyText = new TextView(context);
historyText.setLayoutParams(textParams);
historyText.setText("History");
historyLayout.addView(historyText);
verticalLayout.addView(historyLayout);
//Exam row...
//... (duplicate of history row)
I've tried playing around with the layout parameters, even creating a mock xml layout that displays the content as I'd like, to match the parameters to.
If anyone can give some advice on making that book icon the same size as the others, I'd be grateful.
Add a scaleType to ImageView of fitCenter
Write this code under historyIcon.setAdjustViewBounds(true);
historyIcon.setWidth()`
And put width according to your layout.
Although I didn't figure out why the first image was scaling differently to the other images, I did find another solution: Using compound left drawables.
historyText.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Drawable img = m_context.getResources().getDrawable(
R.drawable.small_book_grey);
img.setBounds(0, 0, img.getIntrinsicWidth() * historyText.getMeasuredHeight() / img.getIntrinsicHeight(), historyText.getMeasuredHeight());
historyText.setCompoundDrawables(img, null, null, null);
historyText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Manually setting the bounds to match the TextView worked. Seems clunky, but it was the only way I could get it to do what I was aiming for.
I have done some research, but the answer i found does not work for me. Here is some part of my code. the R.id.relative is the id of the relativelayout in the xml file
RelativeLayout RL = (RelativeLayout) findViewById(R.id.relative);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView title = new TextView(this);
title.setText(" History ");
title.setId(99099);
title.setTextSize(30);
title.setGravity(Gravity.CENTER);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
title.setLayoutParams(params);
RL.addView(title);
RelativeLayout.LayoutParams test_params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
Button test = new Button(this);
test.setText(" Back ");
test_params.addRule(RelativeLayout.BELOW,99099);
test.setId(199291);
test.setGravity(Gravity.CENTER);
test.setLayoutParams(test_params);
RL.addView(test);
RelativeLayout.LayoutParams test_params2 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
Button test2 = new Button(this);
test2.setText(" Clear ");
test_params2.addRule(RelativeLayout.BELOW,test.getId());
test2.setGravity(Gravity.CENTER);
test.setLayoutParams(test_params2);
RL.addView(test2);
all 3 items did show up, but they stack together. I can't get them below another.
Could anyone help ?
From what I've been able to find out, you have to add the view using LayoutParams. Here's an example:
LinearLayout linearLayout = new LinearLayout(this);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
parentView.addView(linearLayout, relativeParams);
And to relatively position your items programmatically you have to assign ids to them, this stops them from 'overlapping'.
TextView tv1 = new TextView(this);
tv1.setId(1);
TextView tv2 = new TextView(this);
tv2.setId(2);
Then addRule(RelativeLayout.RIGHT_OF, tv1.getId());
Change test.setLayoutParams(test_params2); to test2.setLayoutParams(test_params2);
Explanation: You have inadvertently set the layout params of test a second time, with params that instruct it to be below itself, which I guess just puts it top-left (default placement in a RelativeLayout). Since you never give test2 any layout params, it also gets default placement. So everything is at the top and thus appear atop each other.
Incidentally, if you just want them arranged linearly, why not use a vertical LinearLayout?
The rule you have added is causing your view to be stacked together.If you need to add it should be used by the following rule.
test_params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1);
Next, add the view to your RelativeLayout with your LayoutParams:
RL.addView(yourAdView, rLParams);
same goes for the each cases.try to run.It will solve your problem
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.
I want to create a relative Layout dynamically through code with 2 Textviews one below the other.How to implement android:layout_below property through code in Android.
can anyone help me in sorting out this issue.
Thanks in Advance,
final TextView upperTxt = (...)
upperTxt.setId(12345);
final TextView lowerTxt = (...);
final RelativeLayout.LayoutParams params = RelativeLayout.LayoutParams(this, null);
params.addRule(RelativeLayout.BELOW, 12345);
lowerTxt.setLayoutParams(params);
Here is my solution for my special Problem.
In case the username wouldn't be found in the db i had to create a RelativeLayout that looks like the xml-generated one.
// text view appears on top of the edit text
enterNameRequest = new TextView(mainActivity.getApplicationContext());
// fill the view with a string from strings.xml
enterNameRequest.setText(mainActivity.getResources().getString(R.string.enterNameRequest));
// edit text appears below text view and above button
enterName = new EditText(mainActivity.getApplicationContext());
enterName.setId(667);
// button appears at the bottom of the relative layout
saveUserName = new Button(mainActivity.getApplicationContext());
saveUserName.setText(mainActivity.getResources().getString(R.string.useUserName));
saveUserName.setId(666);
// generate the relative layout
RelativeLayout layout = new RelativeLayout(mainActivity.getApplicationContext());
layout.setId(668);
// set a background graphic by its id
layout.setBackgroundDrawable(mainActivity.getApplicationContext().getResources().getDrawable(R.drawable.background_head_neutral));
// runtime told me that i MUST use width and height parameters!
LayoutParams params2 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ABOVE, 666);
enterName.setLayoutParams(params2);
LayoutParams params3 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params3.addRule(RelativeLayout.ABOVE, 667);
enterNameRequest.setLayoutParams(params3);
LayoutParams params4 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params4.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 668);
saveUserName.setLayoutParams(params4);
// add views
layout.addView(enterNameRequest);
layout.addView(enterName);
layout.addView(saveUserName);
/* todo: set button action */
mainActivity.setContentView(layout);
What i found out additionally:
It is not so good to manipulate the layout manually from within java!
You should better use a new Activity and set a new layout in it.
This way, the application-code is readable a lot better!
I even tried to set several layouts (not manually, but wit setContentView) in one activity, and it turned out that i didn't know where what was accessing what else... Also, i had a great problem in adding onClickListeners... so you better use -- android:onClick="myButtonMethod" -- in your button tag in the xml and have a method in your according activity, which uses the layout, like this:
public void myButtonMethod(View v){
// do stuff
}
This improves performance because you are not using additional Listeners - but you use the already available Listener that is bound to your activity in every case.
u can try this
LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);``
leftMarginParams.leftMargin = 50;
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams)