Dynamically-generated LinearLayouts overlapping - android

I'm a newbie to Android development, and I'm very much still learning Java too so be gentle!
I am creating an app that can take information about a task (I'm basing it around a sort of homework planner), store that info and then display it in a list. The program must be able to dynamically generate the list from the background files. I have managed all of this so far, but when I create a basic output for each task, containing the "subject" and "details" variables using a LinearLayout they appear on the screen overlapping. They all seem to be creating correctly, but they are all being put in the same place. Are there attributes I can set to make them display in a vertical list???
Here is the piece of code where I generate the viewgroups and display them. This is called from a loop in another part of the program which finds the number of files in internal storage.
TextView subjView;
TextView detailView;
RelativeLayout displayLayout;
LinearLayout taskDisplay = new LinearLayout(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
subjView = new TextView(this);
detailView = new TextView(this);
displayLayout = (RelativeLayout) findViewById(R.id.relative_display_layout);
subjView.setText(subject);
detailView.setText(details);
layoutParams.setMargins(0, 0, 0, 0);
taskDisplay.addView(subjView, layoutParams);
layoutParams.setMargins(10, 0, 0, 0);
taskDisplay.addView(detailView, layoutParams);
displayLayout.addView(taskDisplay);

If I understand correctly, I think your issue is only that you are declaring and then changing the layoutParams margins which sets them both to the same, which is overlapping your TextViews.
Edit
Okay, I am still not 100% sure how you are doing all of this so my example may need to be tweaked. I tried to throw this together quickly so forgive me for any minor mistakes.
New mock up for dynamic layouts:
TextView subjView, detailView;
RelativeLayout displayLayout, rl;
// I am assuming this is your main layout
displayLayout = (RelativeLayout) findViewById(R.id.relative_display_layout);
// Just using a for loop as an example of a loop event, not sure how you are accomplishing this
for(int i = 0; i < data.length(); i++) {
RelativeLayout.LayoutParams rllp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 100);
if (i > 0) {
int rePositionRule = i;
rllp.addRule(RelativeLayout.BELOW, rePositionRule);
}
RelativeLayout taskDisplay = new RelativeLayout(this);
taskDisplay.setLayoutParams(rllp);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, 0);
LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams2.setMargins(10, 0, 0, 0);
subjView = new TextView(this);
detailView = new TextView(this);
subjView.setText(subject);
subjView.setLayoutParams(layoutParams);
detailView.setText(details);
detailView.setLayoutParams(layoutParams2);
taskDisplay.addView(subjView);
taskDisplay.addView(detailView);
displayLayout.addView(taskDisplay);
}

Your displayLayout is a relativeLayout.. A relative layout, as the name implies, places element relative to each other. Normally you'd say "element A should go below element B" etc. Since you aren't providing any of these rules for the items you are creating they are just going to all go to the default position in a relative layout (which is the top of the screen.. hence the overlap)
If you don't want to deal with the hassle of changing your code to place things relatively simply switch your displayLayout to a LinearLayout in your xml and code and set its orientation to vertical. You'll probably want to wrap that in a scroll view if it runs off the screen
However, it sounds like what you really want is a ListView...

Related

Not able to add margins on buttons through code

Here is my code, I am trying to add few buttons in a row. Its working fine, But these buttons appear too close to each other, I want to apply horizontal margins to buttons. But not able to add. To achieve this I tried to keep button inside a Linearlayout and applied margins to it. But it somehow don't show any buttons, And when I comment out this line- ll.setLayoutParams(lp); Buttons can be seen again, But without any margin. Please let me know how can I make buttons at some distance from each other.
maintable = (TableLayout) findViewById(R.id.maintable);
TableRow tr = new TableRow(this);
for (int z = 0; z < 3; z++) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(5, 5, 5, 5);
LinearLayout ll = new LinearLayout(this);
//ll.setLayoutParams(lp);
Button b = new Button(savedLists.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(150, 150);
params.setMargins(0, 20, 0, 20);
b.setBackgroundResource(R.drawable.circular);
b.setText(Integer.toString(c));
b.setPadding(10,10,10,10);
ll.addView(b,params);
tr.addView(ll);
c++;
}
maintable.addView(tr);
R.drawable.circular is just creating a simple circular button. Please let me know, if I should post that too.
You haven't set any margin for the button here. You are setting it's padding! Here is how you can set the margin for a button!
Button b = new Button(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
params.setMargins(top, left, bottom, right);
yourLinearLayout.addView(b,params);

Insert layout with different values

I want to insert a few LinearLayouts, but it doesn't work like it should. It inserts just one, but it should insert more.
LinearLayout commentsContainer = (LinearLayout) findViewById(R.id.view_comment_container);
commentsContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
commentsContainer.setOrientation(LinearLayout.HORIZONTAL);
for (int i = 0; i < postView.commentLenght(); i++) {
Log.e("LENGTH", postView.commentLenght()+"x"+i);
LinearLayout commentContainer = new LinearLayout(PostViewActivity.this);
commentContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
LinearLayout userContainer = new LinearLayout(PostViewActivity.this);
userContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
userContainer.setOrientation(LinearLayout.VERTICAL);
commentContainer.setOrientation(LinearLayout.HORIZONTAL);
commentContainer.setPadding(25,0,0,0);
ImageView commentImage = new ImageView(PostViewActivity.this);
commentImage.setLayoutParams(new LinearLayout.LayoutParams((int) ((float) width / 6), (int) ((float) width / 6)));
commentImage.setImageBitmap(postView.getComment(i).getImage());
TextView commentText = new TextView(PostViewActivity.this);
commentText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
commentText.setText(postView.getComment(i).getText());
TextView displayUserText = new TextView(PostViewActivity.this);
displayUserText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
displayUserText.setText(postView.getComment(i).getDisplayName());
Log.d("TEXT", postView.getComment(i).getText());
Log.e("TEXT", displayUserText.getText()+"");
displayUserText.setTag(postView.getComment(i).getUsername());
displayUserText.setTextSize(12);
displayUserText.setTextColor(getResources().getColor(R.color.colorAccent));
userContainer.addView(commentImage);
userContainer.addView(displayUserText);
commentContainer.addView(userContainer);
commentContainer.addView(commentText);
commentsContainer.addView(commentContainer);
}
Another strange thing: the first Log.d is always the correct one, but the second one is always the same. What's the mistake?
This code can be greatly cleaned up by using XML resource files. As each of the comments takes the same form, the same layout can be used for each. You can fill different values into the layout as you desire. These can all be added to a ViewGroup within another layout.
Programmatically generating layouts is much more error prone and complex than using an XML layout.
Doing some reading into the Android official documentation is absolutely worth it! https://developer.android.com/guide/topics/ui/declaring-layout.html

How to set dynamic size for Android's view?

I am trying to set the minimum sizes, but still one view is taking over completely. My normal view looks like this:
These two values are coming from the server. But if the size of the "hello" changes to something longer then the number string disappears.
My code looks like this:
if (jsonDataViewType.get(i).toString().equals("editBox")) {
editText = new EditText(context);
editText.setMinLines(1);
editText.setMinimumWidth(10);
linearLayoutHorizontal.addView(editText);
editText.setText(jsonDataValue.get(i));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
// RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.weight = 1.0f;
editText.setGravity(Gravity.CENTER_HORIZONTAL);
editText.setLayoutParams(params);
}
else if(jsonDataViewType.get(i).toString().equals("button")) {
helloButton = new Button(context);
// helloButton.setMinLines(1);
linearLayoutHorizontal.addView(helloButton);
helloButton.setText(jsonDataValue.get(i));
// testing
// helloButton.setText("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeelllllllllllllllllllllllllllooooooooooo");
}
I am setting both the minLines and minWidth, but as you can see its still not working.
Try to set layout_width=0 for both EditView andButton`. Then set layout_weight to 0.8 and 0.2
So theese two view will fill parents width. Now your EditView is out of the screen left side.
So your problem is that setting setMinLines(1) is a lower bound setting meaning that at minimum make this one line long. If you want to control how much is being shown you need to setMaxLines(1); and then the same for width setting setMinWidth(10) means at least let this be 10 wide so do setMaxWidth(10)
Then you may want to consider adding ellipsize to the buttons text if you want it to show that there is more text but its cut off.
Update
If you want them to sit next to each other:
// Linear Layout has weight sum of 3
linearLayoutHorizontal.setWeightSum(3.0f);
// Lets EditText take up 2/3 of view
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 2.0f);
editText.setLayoutParams(params);
// Button gets the other 1/3
LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1.0f);
helloButton.setLayoutParams(params2);

android position TextViews programmatically

how do I position two programmatically created TextViews in a LinearLayout BESIDE each other? I tried the code below, but that way the "number" TextView is placed one line deeper compared to the "value" TextView, so the height of nlap LinearLayout changes. I need both TextViews to be at the same height, the "number" TextView should be on the left side an centered vertically. Any help is appreciated.
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 1, 10, 1);
LinearLayout nlap = new LinearLayout(this);
nlap.setOrientation(LinearLayout.VERTICAL);
nlap.setLayoutParams(layoutParams);
TextView value = new TextView(this);
value.setText("Test");
value.setTextColor(Color.parseColor("#A60101"));
value.setTextSize(23);
value.setGravity(Gravity.CENTER);
value.setTypeface(font);
TextView number = new TextView(this);
number.setTextColor(Color.parseColor("#FFFFFF"));
number.setText("01");
nlap.addView(value);
nlap.addView(number);
You should use nlap.setOrientation(LinearLayout.HORIZONTAL); to achieve having textViews beside each other, if you use VERTICAL as you do, second one will always be below the first.

Programmatically aligning items in RelativeLayout?

I'm trying to position items inside my RelativeLayout so that the image appears first, the title to the right of it, and the content below the image area. Those three content items appear on top of each other. I understand that my LayoutParams probably aren't being set, but I'm not sure why or how to fix it. Any help? Thanks.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.contentTable);
for(int i=0;i<itemIndexes.size();i++)
{
RelativeLayout item = new RelativeLayout(this);
item.setId(i);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(320, RelativeLayout.LayoutParams.WRAP_CONTENT);
if(i>0)
{
lp.addRule(RelativeLayout.RIGHT_OF,i-1);
}
item.setLayoutParams(lp);
ImageView iv = new ImageView(this);
if(globals.myHitetItems.get(itemIndexes.get(i)).image!=-1)
{
iv.setImageResource(globals.myHitetItems.get(itemIndexes.get(i)).image);
item.addView(iv);
}
else
{
iv.setImageResource(R.drawable.noimage);
item.addView(iv);
}
RelativeLayout.LayoutParams text1lp =new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text1lp.addRule(RelativeLayout.RIGHT_OF,iv.getId());
TextView tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).name);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(text1lp);
item.addView(tv);
RelativeLayout.LayoutParams text2lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text2lp.addRule(RelativeLayout.BELOW,iv.getId());
tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).content);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(lp);
item.addView(tv);
rl.addView(item);
}
That looks painful to debug. It sounds like maybe the relative rules aren't being set or accepted. I suggest simplifying to a static test set to verify that one row of views can be set relative to each other (and ensure that one of them is anchored to the layout itself).

Categories

Resources