Place 2+ Textfields side-by-side in a LinearLayout (horizontal) programmatically - android

i know, there are a lot of questions like this. I read a lot on stackoverflow and google about this topic, but nothing help me :(
Ok, here is the problem. I have a small app. In this app i have a fragment. The layout.xml for this fragment includes a placeholder linearlayout like the following
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/placeholderLinLayout">
</LinearLayout>
The fragment has a button. If u click on it a DialogFragmentPopup opens and u can enter some data-stuff. After you enter the data you can click on another button on this dialog and the data will be transfere to the main-fragment. Here i call a method which should generate programmatically a layout to present the data. I use the following code
myRoot = (LinearLayout) view.findViewById(R.id.placeholderLinLayout);
innerLayout = new LinearLayout(view.getContext());
innerLayout.setOrientation(LinearLayout.VERTICAL);
innerLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
LinearLayout productHeaderLayout = new LinearLayout(getContext());
productHeaderLayout.setOrientation(LinearLayout.HORIZONTAL);
productHeaderLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
TextView product_header = new TextView(getContext());
product_header.setText("Produkt");
product_header.setLayoutParams(layoutParams);
TextView amount_header = new TextView(getContext());
amount_header.setText("Menge");
amount_header.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
amount_header.setLayoutParams(layoutParams);
TextView packaging_header = new TextView(getContext());
packaging_header.setText("Verpackung");
packaging_header.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
packaging_header.setLayoutParams(layoutParams);
TextView price_header = new TextView(getContext());
price_header.setText("Preis");
price_header.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
price_header.setLayoutParams(layoutParams);
TextView payment_header = new TextView(getContext());
payment_header.setText("Zahlart");
payment_header.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
payment_header.setLayoutParams(layoutParams);
productHeaderLayout.addView(product_header);
productHeaderLayout.addView(amount_header);
productHeaderLayout.addView(packaging_header);
productHeaderLayout.addView(price_header);
productHeaderLayout.addView(payment_header);
innerLayout.addView(productHeaderLayout);
The problem is, that the first textview push all other textviews out of the visible space, see the screenshot
What i want to do is, that these 5 textviews spread out automatically to the existing width. I googled a lot and the code i post here is the result of which i found many times on the internet.
So i hope someone can help find out the problem in my code :)
Greetings

Set all your TextView layout paramters to this:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f);
And remove .setWidth(ViewGroup.LayoutParams.MATCH_PARENT); from all the TextViews.
This will guarantee that all the views will have same weight set to them, and that weight gives all the views in LinearLayout same Width (or Height if orientation is set to vertical).

The issue is that your setting the TextView to MATCH_PARENT in its width. So one TextView takes the whole screen and the other starts just out of it. To solve this set the layoutparam width to WRAP_CONTENT.
Better yet, if you want to spread it, you can use the LinearLayout's weight property so they take as much space as they can:
textview.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f));
The third parameter 1f is the weight. A weight of one means it'll take all the available space without intruding on the other children, hence they will all spread evenly.

If you want to have your TextViews side by side, you must set the orientation of the LinearLayout to horizontal instead of vertical

Related

android textview set height does not work

I am trying to create a layout with nested linear layouts and textviews which are placed vertically in a linear layout. They are created programatically. While I can set the height of the linear layout using layout Params I am not able to do this for textview. Using Textview setLayoutParams or setHeight function provides no response. The text is always wrapped around the content (though this is no where mentioned by me in the code). Can someone help me fix this?
this code might help you:
LinearLayout.LayoutParams paramsLayoutExpire = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
TextView txtView=new TextView(this);
txtView.setLayoutParams(paramsTextViewExpire);
LayoutParams.MATCH_PARENT: Height
LayoutParams.WRAP_CONTENT: Width
I hope this might help
TextView textView = new TextView(this);
textView.setText("Hellow World");
textView.setHeight(prefered_height_in_pixel);
this.addView(textView)

adding linear layout to current view

I'm sure this has come up often, but I couldn't find an exact solution for my issue. I'm simply trying to programmatically create a linear layout with a textview and 2 buttons and add it to the bottom of my fragment (which is also a linear layout). I.e. I want it to appear below the other views on the screen not the actual bottom. However, when I try to add it, it always appears at the top corner and not the end. Here's my code:
LinearLayout layout = new LinearLayout(getActivity());
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
layout.setBackgroundColor(Color.CYAN);
TextView noteView = new TextView(getActivity());
LayoutParams lparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
noteView.setLayoutParams(lparams);
noteView.setText(noteText);
layout.addView(noteView);
getActivity().addContentView(layout, lparams);
}
Have you tried to add gravity to the LinearLayout?
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
params.gravity = Gravity.BOTTOM;
layout.setLayoutParams(params);
If your main goal is to have your views line up relative to each other, perhaps it would be worth considering using a Relative Layout to accomplish a similar task.
If that's not an option for whatever reason, I think LayoutParams has a gravity option that can be set to bottom which will align views to the bottom of the parent view. I can't guarantee this will work though as I usually do not accomplish tasks like these programmatically.

Added Views appear at top of screen

I've been trying to add multiple textviews and buttons when onClick, and this is the best code I have found that actually works:
RelativeLayout relative = (RelativeLayout) findViewById(R.id.RelativeLayout01);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
(LayoutParams.WRAP_CONTENT), (LayoutParams.WRAP_CONTENT));
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(lp);
tv.setText("Shift" + mShiftCount);
EditText edittv = new EditText(getApplicationContext());
edittv.setLayoutParams(lp);
relative.addView(tv);
relative.addView(edittv);
This seems to be the best code to add additional items that are alike to that of what I already have in my main.XML file.
My issue is that when these are added, they appear at the top of the screen and I am unsure how to add further parameters to the objects.
How would I go about placing the textview and edittext below my other elements specified in the XML?
What you need to do is create a RelativeLayout.LayoutParams (refer here) when you add the views like tv and edittv to the RelativeLayout. In your RelativeLayout.LayoutParams, you need to define the same parameters you would give to your other RelativeLayout objects. Here is an example:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, R.id.idOfWhatYouWantToBeBelowOf);
addView(tv, params);
First off there are definitely some static components to your view and some dynamic components. can you please specify what is your layout file so that i can give you a much more detail in your application.

Android FrameLayout and TextView - why does LayoutParams work where setGravity() does not?

I'm using a FrameLayout to display (on demand) some text on the screen. I want the text to be in a certain place, so I thought setGravity() would do the job... but no, it seems to have no effect whatsoever on where the text goes (and other objects like ImageView don't even have this method).
So first, what exactly is TextView.setGravity() used for? (Edit: I understand this much better now, thanks! Still not clear on the following part of the question though.)
Second, it seems the only way to update a FrameLayout in this way is to create a new FrameLayout.LayoutParams object with the settings you want, and then use the setLayoutParams() method to apply it. (This seems to automatically update the view so is a requestLayout() call necessary?) And is there a simpler / more straightforward way to achieve this for a FrameLayout... say, without creating a new LayoutParams object as I'm doing now?
Thanks! For reference, below is a (working) code snippet showing how I'm setting up this FrameLayout and TextView.
FrameLayout fl1 = new FrameLayout(this);
FrameLayout.LayoutParams flp1 = new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
fl1.setId(9001);
fl1.setLayoutParams(flp1);
.....
tv1 = new TextView(this);
FrameLayout.LayoutParams tvp1 = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
tv1.setId(9006);
tv1.setLayoutParams(tvp1); // This works
tv1.setBackgroundColor(Color.GRAY);
tv1.setTextColor(Color.BLACK);
tv1.setText("Dynamic layouts ftw!");
tv1.setGravity(Gravity.CENTER); // This does NOT work
.....
fl1.addView(tv1);
1) view.setGravity means hows the view should positions if children.
In the case of the textview it refers to the positioning of the text.
When in linearlayouts or viewgroups it refers to its child views.
2) I checked your code. You are already using textview.setGravity method. In that case you dont need to specify gravity parameters in the FrameLayout.LayoutParams constructor.
Other thing I noticed is that you gave the textview the width and height as wrap content which will only take the size of the text. So there is no meaning in giving gravity as the textview has no extra area to position the text to the center. You need to give the width of the textview as fill_parent. That should make your gravity property work.
Btw this is a very good article about Gravities. It explains both about gravity and the layout_gravity attribute.
If you want your textview to wrap the content then you should add your textview to a linearlayout and setgravity to the linear layout.
This should give what your are trying to do
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
FrameLayout fr = new FrameLayout(this);
fr.setLayoutParams(lp);
fr.setBackgroundColor(Color.RED);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
LinearLayout l = new LinearLayout(this);
l.setLayoutParams(lp2);
l.setGravity(Gravity.CENTER);
l.setBackgroundColor(Color.BLUE);
ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
TextView t = new TextView(this);
t.setLayoutParams(vp);
t.setText("Blessan Mathew");
t.setBackgroundColor(Color.CYAN);
l.addView(t);
fr.addView(l);
tv1.setGravity(Gravity.CENTER);
belongs to the gravity of the TEXT inside the TextView.
As documentation states:
Sets the horizontal alignment of the text and the vertical gravity
that will be used when there is extra space in the TextView beyond
what is required for the text itself.

How to Change Margin of TextView

I have TextView added Programmatically in to LinearLayout and on some external events I want to decrease bottom margin of that TextView to -10, for that I tried following.
LinearLayout.LayoutParams lastTxtParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lastTxtParams.setMargins(0, 0, 0, -10);
mOldTextView.setLayoutParams(lastTxtParams);
mOldTextView.invalidate();
Is the right way of modifying Margin of widget that has been added to View?
Some how it is not working.
TextView forgot_pswrd = (TextView) findViewById(R.id.ForgotPasswordText);
forgot_pswrd.setOnTouchListener(this);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(50, 0, 0, 0); // llp.setMargins(left, top, right, bottom);
forgot_pswrd.setLayoutParams(llp);
I did this and it worked perfectly.
Maybe as you are giving the value in -ve, that's why your code is not working.
You just put this code where you are creating the reference of the view.
Your layout in xml probably already has a layout_margin(Left|Right|etc) attribute in it, which means you need to access the object generated by that xml and modify it.
I found this solution to be very simple:
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mTextView
.getLayoutParams();
mlp.setMargins(adjustmentPxs, 0, 0, 0);
break;
Get the LayoutParams instance of your textview, downcast it to MarginLayoutParams, and use the setMargins method to set the margins.
This one is tricky problem, i set margin to textview in a row of a table layout.
see the below:
TableLayout tl = new TableLayout(this);
tl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
TableRow tr = new TableRow(this);
tr.setBackgroundResource(R.color.rowColor);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(4, 4, 4, 4);
TextView tv = new TextView(this);
tv.setBackgroundResource(R.color.textviewColor);
tv.setText("hello");
tr.addView(tv, params);
TextView tv2 = new TextView(this);
tv2.setBackgroundResource(R.color.textviewColor);
tv2.setText("hi");
tr.addView(tv2, params);
tl.addView(tr);
setContentView(tl);
the class needed to import for LayoutParams for use in a table row is :
import android.widget.**TableRow**.LayoutParams;
important to note that i added the class for table row. similarly many other classes are available to use LayoutParams like:
import android.widget.**RelativeLayout**.LayoutParams;
import android.widget.LinearLayout.LayoutParams;
so use accordingly.
setMargins() sets the INNER margins of the TextView, not the layout-margins. Is that what you want to do? This two different margins can be quite complicated.
If you want to set the layout margins, change the LayoutParams of the TextView (textview.getLayoutParams(), then change the parameters on the returned LayoutParams object).
You don't need to change anything on your LinearLayout.
Regards,
Oliver
TextView does not support setMargins. Android docs say:
Even though a view can define a padding, it does not provide any support for margins. However, view groups provide such a support. Refer to ViewGroup and ViewGroup.MarginLayoutParams for further information.
Here is another approach...
When I've got to the same problem, I didn't like the suggested solutions here.
So, I've come up with another way:
I've inserted a TextView in the XML file between the two fields I wanted to separate with two important fields:
visibility set to "GONE" (doesn't occupy any space..)
height is set to whatever I needed the separation to be.
XML:
...//some view up here
<TextView
android:id="#+id/dialogSeparator"
android:layout_width="match_parent"
android:layout_height="30dp"
android:visibility="gone"/>
...//some view down here
Now, I the code, all I needed to do it simple change the visibility to invisible (i.e. it's there, and taking the needed space, but it's unseen)
JAVA:
TextView tvSeparator = (TextView)activity.findViewById(R.id.dialogSeparator);
tvSeparator.setVisibility(View.INVISIBLE);
//Inside an activity extended class I can use 'this' instead of 'activity'.
Viola...I got the needed margin.
BTW, This solution is for LinearLayout with vertical orientation, but you can do it with different layouts.
Hope this helps.
You were probably changing the layout margin after it has been drawn. mOldTextView.invalidate() is useless. you needed to call requestLayout() on the parent to relayout the new configuration. When you moved the layout changing code before the drawing took place, everything worked fine.
TextView tv = (TextView)findViewById(R.id.item_title));
RelativeLayout.LayoutParams mRelativelp = (RelativeLayout.LayoutParams) tv
.getLayoutParams();
mRelativelp.setMargins(DptoPxConvertion(15), 0, DptoPxConvertion (15), 0);
tv.setLayoutParams(mRelativelp);
private int DptoPxConvertion(int dpValue)
{
return (int)((dpValue * mContext.getResources().getDisplayMetrics().density) + 0.5);
}
getLayoutParams() of textview should be casted to the corresponding Params based on the Parent of the textview in xml.
<RelativeLayout>
<TextView
android:id="#+id/item_title">
</RelativeLayout>
To render the same real size on different devices use DptoPxConvertion() method which I have used above. setMargin(left,top,right,bottom) params will take values in pixel not in dp. For further reference see this Link Answer

Categories

Resources