I have an Open GL ES 2.0 app and am displaying an Android TextView over the top of my GLSurfaceView.
I have the actual textviews displaying OK but now I need to try to centre them.
This is what I have so far:
text1 = new TextView(this);
text1.setText("This is some sample text");
text1.setTextColor(Color.WHITE);
text1.setTextSize(textSize);
text2= new TextView(this);
text2.setText("And this is some more sample text");
text2.setTextColor(Color.WHITE);
text2.setTextSize(textSize);
RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
textLayout = new RelativeLayout(this);
textLayout.setLayoutParams(textParams);
textLayout.addView(text1);
textLayout.addView(text2);
mainLayout.addView(textLayout);
However, when I run this, only text1 is centered. Text 2 isn't, and starts at the left side of the first (correctly centered) textView. Try as I might, I can't seem to get both of them centered. The following graphic describes what I mean:
(Please note re vertical placement - in my actual results, both TextViews are at the same vertical/'y' position and therefore overlapping - obviously this is expected as I haven't changed the vertical position of the 2nd TextView, but to make things clearer to illustrate, I've moved the 2nd one down manually.......)
The idea I was going with was creating a 'textLayout' to which I could add all of my textViews, then just add that textLayout to my main layout. Thus facilitating the addition and removal of all of the textViews with a single line of code.
Please note that I am not using, and do not wish to use, XML for this - I would like to know how to do this programmatically.
What am I missing?
Edit Here is how I am creating my Main Layout to which I am adding the textView.....
layout = new RelativeLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
When you are adding "RelativeLayout.CENTER_HORIZONTAL" as a rule to your layout params, what you are actually doing is telling textLayout that it should be centered horizontally in your mainLayout (see http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html#attr_android:layout_centerHorizontal). In code you should actually do text1.setGravity(Gravity.CENTER) and text2.setGravity(Gravity.CENTER).
Related
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
I've been making all of my views dynamically, and now I've come to the point where I want to add an EditText for people to write in.
I've been able to accomplish this for the most part, but it doesn't look right. I have a linear layout that I'm adding a relative layout to. I'm making the relative layout have a white background, then adding the EditText. Problem is, it always adds it to the direct center of the relative layout, and options to align it vertically to the top have so far failed.
I also need to be able to pull the text from it later when a separate button was pressed (I know how to make the button work, it's the pulling text from it part I'm a bit iffy on). Here's my code so far:
public void addEditText(LinearLayout L){
EditText myEditText = new EditText(c);
myEditText.setSingleLine(false);
RelativeLayout l1 = new RelativeLayout(c);
LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(scWidth1, 300);
lp.gravity=Gravity.CENTER;
l1.setLayoutParams(lp);
l1.setBackgroundColor(Color.WHITE);
l1.setGravity(Gravity.CENTER_VERTICAL);
l1.addView(myEditText);
L.addView(l1);
}
l1.setGravity(Gravity.CENTER_VERTICAL); places the EditText in center vertical of the parent container i.e RelativeLayout, remove that line.
I have the following problem:
The code below successfully adds my TextView to my custom RelativeLayout:
RectF rectRecord = getItemRect(trCurrent);
TextView tv = new TextView(this.getContext());
tv.setLeft((int)rectRecord.left);
tv.setRight((int)rectRecord.right);
tv.setTop((int)rectRecord.top);
tv.setBottom((int)rect.bottom);
addView(tv);
Unfortunately the methods ("setLeft,setRight,setTop,setBottom") aren't available on Android older than 3.0.
So I tried to add my TextView the alternative way:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.setMargins((int)rectRecord.left, (int)rectRecord.top, (int)rectRecord.right, (int)rectRecord.bottom);
//tv.setLayoutParams(tv);
addView(tv, params);
Doing it that way does not show a child control ...
I already tried to change the class my host control derives from ViewGroup to LinearLayout, RelativeLayout and the deprecated AbsoluteLayout but always the same.
Also removed my custom onDraw and onMeasure and "setWillNotDraw(false);" but that didn't solved my problem.
Snippet 1 is displaying my child views.
Snippet 2 does not show a child.
Can anyone point to the solution for this problem?
Your margins are set to 1234 - that's 1234 dip (density independent PIXELS) and that is huge. Your control doesn't show up on the screen because margins are too big, and your control has no place to show on the screen.
I am having a little bit of trouble making the table look like I intend to.
These are a few questions, but since they all refer to the picture below and the details I provide I thought they should all be in a single post.
Here is what I achieved so far:
The header row contains one element of type Button.
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
Button bt = new Button(getContext());
bt.setText("Column1");
mHeader.addView(bt, params);
mHeader.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
addView(mHeader);
The rest of the table is poulated like this:
(Messagerow extends TableRow and has a TextView member)
for(int i = 0; i < 100; i++) {
MessageRow mr = new MessageRow(getContext());
// stuff to set the TexView text and color
mr.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
this.addView(mr);
}
1. How can I make the header row height be more like the rows?
2. How can I make the button occupy the full width of the row?
If the table is empty, no text rows just header, then the button matches the row width. As soon as I add a row of text, the column width is adapted but the button width is not.
3. How can I make the row fill the screen width? (MATCH_PARENT does not do it)
4. How can I draw a thin line between the table rows?
I tried to override the onDraw() function on MessageRow, but it never gets called, not even once.
Don't get me wrong. I am not asking that you do my work for me. These are issues I tried to solve by myself and googled them and read similar posts, but did not find an answer.Note: I find that UI design in Javascript for Android lacks clear control and clear documentation over all these little details.
Edit
This is how I create the table:
TableLayout mTable = new TableLayout(this);
HorizontalScrollView hview = (HorizontalScrollView) findViewById(R.id.hscroll);
populate(mTable);
mTable.setLayoutParams(new TableLayout.LayoutParams( TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
mTable.setBackgroundColor(Color.WHITE);
hview.addView(mTable);
How can I make the header row height be more like the rows?
Using the default Button there isn't much to do. The Button uses a nine-patch image that has some space between the button's text and the borders that you see. You could use a smaller font but that you'll probably look ugly. Another thing to try is using your own background for the Button and get rid of the default extra space(of the default nine-patch image) so the final height is near the height of the text from the TextViews. Or try to enforce a standard height for all rows using a fixed value.
How can I make the button occupy the full width of the row?
I think that you have more then one TextView in MessageRow so when you add the Button it moves to the first column(corresponding to the first TextView). If this is the case, make your Button span across the number of columns representing the number of TextViews in MessageRow:
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
params.span = 3; // if you have 3 `TextView` in the MessageRow
Button bt = new Button(getContext());
bt.setText("Column1");
mHeader.addView(bt, params);
If this is not the case add more details.
How can I make the row fill the screen width? (MATCH_PARENT does not do it)
As I said on one of your previous questions, I don't know why that happens(but I gave you some solutions there to overcome this issue). Also:
mHeader and the other MessageRow are children of a Tablelayout and the correct LayoutParams to use on them is the LayoutParams of the parent: TableLayout.LayoutParams and not TableRow.LayoutParams.
You add some TextView in the MessageRow(from what I seen in your previous questions), add those child views with TableRow.LayoutParams to MessageRow.
You use only WRAP_CONTENT for your LayoutParams everywhere in your code, you might want to set the width(the first parameter in the constructor) to FILL_PARENT/MATCH_PARENT
How can I draw a thin line between the table rows?
You could use a simple View that will act as a separator:
for(int i = 0; i < 100; i++) {
MessageRow mr = new MessageRow(getContext());
// stuff to set the TexView text and color
mr.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
this.addView(mr);
View separator = new View(getContext());
separator.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, 3)));
separator.setBackgroundColor(Color.RED);
this.addView(separator);
}
Because you have 100 rows you could try to set a drawable with a separator line as the background for theTableRow(header and MessageRow) instead of the above method that adds another 100 Views to the layout.
Extra Note:
You have a lot of views to add to a single activity layout, you are talking about 100 rows, and if your MessageRow is more complex than a simple TextView(and I think it is) you could get in some performances problems. I suggest you take a look at the wonderful ListView widget.
Don't have a programming environment here, but I'll try and answer some of your questions.
The reason your header row (button) is taller than your test based rows is because the button requires more space and the row accomodates it. The default button has padding on both the top/bottom of the text. I think your best option is to create your own button, which gives you the additional benefit of being able to control the look and feel. It seems like other people have had this issue before: Can't get rid of bottom padding on button
Your button is set to wrap_content which means it won't be any bigger than it needs to be (It will grow/shrink so it can fit the text "Column1" or whatever you put there). Instead of making the Button WRAP, I suspect you'll need to make it FILL_PARENT.
It's not your Table Row that needs to fill the screen width, it's your table that needs to fill the screen. Wherever you define your table, it's probably set to WRAP_CONTENT for the Horizontal dimension. Set it to FILL_PARENT and your table should expand to the full width of whatever it's container is (In this case, it should expand the full width of the screen)
There are probably several different ways you can do this. One method I used somewhat recently is to utilize the View tag which essentially looks like a horizontal bar across the screen. Below is a link to how to implement it.
http://sonnygill.net/android/horizontal-rule/
I'm trying to build an android application that features a graphical display drawn within a RelativeLayout. I want to place "+" and "-" buttons next to several of the parameters, which are drawn at various points on the canvas. The positions are free-form don't seem to conform to any of the standard XML layouts.
I know how to create the buttons programmatically, but I don't know how to place them over the canvas where I need them to be. I'm assuming that this would be done in the view thread's doDraw() method, after all the graphics have been drawn, but how?
I struggled with the same problem, and found out great solution.
RelativeLayout rules like "leftOf" or "rightOf" can be implemented programmatically like this:
RelativeLayout container = new RelativeLayout(getApplicationContext());
Button weight = new Button(getApplicationContext());
final int WEIGHT_ID = 0;
weight.setId(WEIGHT_ID);
weight.setText("0.0");
LayoutParams wrapBoth =
new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
container.addView(weight, wrapBoth);
Button increaseWeight = new Button(getApplicationContext());
increaseWeight.setText("+");
// Note the difference: RelativeLayout.LayoutParams in spite of LayoutParams
RelativeLayout.LayoutParams toBeRightOfWeight =
new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
container.addView(parameter,wrapBoth);
// Sweet part
clearAirParams.addRule(RelativeLayout.RIGHT_OF, WEIGHT_ID);
container.addView(increaseWeight, toBeRightOfWeight);
So, in code you can create a 'container' RelativeLayout, then add several Views with unique ID's and, finally, create RelativeLayout.LayoutParams object to achieve sweet-like-sugar methods for alignment, like in XML.