Add child views in RelativeLayout programmatically - android

I have a function that loops over a list and returns the row elements.
I want to add these rows to an empty RelativeLayout one by one, so that all the rows are displayed sequentially vertically.
But the code below is not working.
void setRows(RelativeLayout rowContainer, ViewHolder viewHolder,
List<RowCollection> rowCollection) {
for (int i = 0; i < rowCollection.size(); i++) {
MyRow row = new MyRow(rowCollection.get(i));
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, row.getId());
rowContainer.addView(row, params);
}
}
Only the last row element is displayed.
I guess but am not sure, that the rows are overlapping each other.

You are placing all your Views to the Bottom of the RelativeLayout, so they are always on top of the other. So there is always only the last one visible because the other ones are blow it.
Change your Code to this:
params.addRule(RelativeLayout.BELOW, iDFromPreviousView);

change to:
void setRows(RelativeLayout rowContainer, ViewHolder viewHolder,
List<RowCollection> rowCollection) {
MyRow lat_row=null;
for (int i = 0; i < rowCollection.size(); i++) {
MyRow row = new MyRow(rowCollection.get(i));
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
if (i == 0) {
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}else{
//<---get the id of previous row not sure what RowCollection contains
params.addRule(RelativeLayout.ABOVE,lat_row.getId());
}
lat_row=row;
rowContainer.addView(row, params);
}
}
this will stack all the view from bottom to top.

Related

Adding multiple views to RelativeLayout with loop

I'm trying to add multiple views to RelativeLayout that I declared inside xml. Looping is the only way because I do not know how many elements needed to add there, since the size is dynamic. But I got this error.
java.lang.IllegalStateException: The specified child already has a
parent. You must call removeView() on the child's parent first.
Code:
View inf = getActivity().getLayoutInflater().inflate(R.layout.item_table_edit, null);
RelativeLayout.LayoutParams layoutParamss = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
for (int i = 0; i < putzones.size(); i++) {
inf.setX((float) putzones.get(i).getPosX());
inf.setY((float) putzones.get(i).getPosY());
addMap.addView(inf, layoutParamss);
}
What is wrong here, since when I'm trying to add views by clicking items it works with the same code, without any error. code is same when I am adding by clicking item without loop. Thanks in advance.
You have to create a new instance of item_table_edit at each loop's iteration.
RelativeLayout.LayoutParams layoutParamss = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
for (int i = 0; i < putzones.size(); i++) {
View inf = getActivity().getLayoutInflater().inflate(R.layout.item_table_edit, null);
inf.setX((float) putzones.get(i).getPosX());
inf.setY((float) putzones.get(i).getPosY());
addMap.addView(inf, layoutParamss);
}

Create buttons in sequential order programmatically

I want to parse text, and create for each word - button, but i don't know how to arrange them one after the other
String s = "Alice was beginning to get very tired of sitting";
String[] q = s.split(" ");
for (int i = 0; i < q.length; i++) {
Button myButton = new Button(this);
myButton.setText(q[i]);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1);
layout.addView(myButton, params);
}
See this custom library: FlowLayout
While you're adding views inside FlowLayout, it automatically wraps when there is no space for the next item.
There's not much wrong about your approach, it's only that relative layout as name suggests requires child views to have some parameters to align the views relative to them e.g. above, below etc. As a result you are getting views overlapping each other and hence only the last added view is visible being on top.
Use FlowLayout instead and you'll be fine.
You need to define RelativeLayout parameters as in example below
Heres an example to get you started, fill in the rest as applicable:
TextView tv = new TextView(mContext);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
params.leftMargin = 107
...
mRelativeLayout.addView(tv, params);
The docs for RelativeLayout.LayoutParams and the constructors are
here
From: How to add a view programmattically to RelativeLayout?
Check the link below to get more useful informations.
Hope it will help
In the following code, you should change the upper limits of the for, to a variable.
public class MainActivity
extends Activity
implements View.OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableLayout layout = new TableLayout (this);
layout.setLayoutParams( new TableLayout.LayoutParams(4,5) );
layout.setPadding(1,1,1,1);
for (int f=0; f<=13; f++) {
TableRow tr = new TableRow(this);
for (int c=0; c<=9; c++) {
Button b = new Button (this);
b.setText(""+f+c);
b.setTextSize(10.0f);
b.setTextColor(Color.rgb( 100, 200, 200));
b.setOnClickListener(this);
tr.addView(b, 30,30);
} // for
layout.addView(tr);
} // for
super.setContentView(layout);
} // ()
public void onClick(View view) {
((Button) view).setText("*");
((Button) view).setEnabled(false);
}
} // class

Setting a layout to view.setEnabled(false) does not disable all child views

I have a layout with several nested relative layouts. Within the nested layouts I have form elements, such as TextViews, EditTexts and Buttons. The code is abbreviated just for this example:
Context con;
LinearLayout survey = new LinearLayout();
RelativeLayout question = new RelativeLayout();
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button btnAnswer = new Button(con);
btnAnswer.setId(GlobalVars.getLatestId());
btnAnswer.addParams(params);
question.addView(btnAnswer);
TextView tvBtnLabel = new TextView(con);
btnAnswer.setId(GlobalVars.getLatestId());
tvBtnLabel.setText("Some Label");
tvBtnLabel.addParams(params);
question.addView(tvBtnLabel);
survey.addView(question);
question.setEnabled(false);
//^^^^does not set child views to disabled state
When I set the entire nested Relative Layout to false, the Button and the TextView are not disabled. I have to go in and set each child view to disabled individually. Bug in android? Is there a maximum nesting limit for disabling views? I've checked the state and the relative layouts are indeed set to disabled.
Try this:
Context con;
LinearLayout survey = new LinearLayout(con);
survey.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
RelativeLayout question = new RelativeLayout(con);
question.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button btnAnswer = new Button(con);
btnAnswer.setId(GlobalVars.getLatestId());
btnAnswer.addParams(params);
question.addView(btnAnswer);
TextView tvBtnLabel = new TextView(con);
btnAnswer.setId(GlobalVars.getLatestId());
tvBtnLabel.setText("Some Label");
tvBtnLabel.addParams(params);
question.addView(tvBtnLabel);
survey.addView(question);
[UPDATE]
for (int i = 0; i < question.getChildCount(); i++) {
View child = question.getChildAt(i);
child.setEnabled(false);
}
Hope this help!

Adding Buttons dynamically in RelativeLayout to LinearLayout

When the user inputs a word, he creates a number of Buttons equal to the length of the word. For example: if user inputs "aaaa" he will create 4 Buttons, side by side, in the first row. Then if the user enters "bb" he will create 2 Buttons, side by side, in the second row. And "ccc" he creates 3 Buttons...
Image to demonstrate:
I dynamically create a RelativeLayout, then dynamically add Buttons to that layout. And finally I add the RelativeLayout to my existing LinearLayout. But the problem is, only one Button is added per row. And my program currently looks like this:
Can someone please me fix this problem?
CODE:
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_bttn_words);
final LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
button_test.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
RelativeLayout relativeLayout = new RelativeLayout(view.getContext());
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
int size = enter_txt.getText().toString().length(); //the user input number of buttons
int id = 1;
for (int i=0; i<size; i++)
{
Button myButton = new Button(view.getContext());
myButton.setBackgroundResource(R.drawable.button);
myButton.setId(id);
rlp.addRule(RelativeLayout.RIGHT_OF, myButton.getId());
relativeLayout.addView(myButton, rlp);
id++;
}
linearLayout.addView(relativeLayout, llp);
rlp.addRule(RelativeLayout.RIGHT_OF, myButton.getId());
This line says that myButton should be added to right of myButton, which doesn't make any sense.
simple way to resolve this is to use the following line instead
rlp.addRule(RelativeLayout.RIGHT_OF, myButton.getId()-1);
But this isn't the best way to do this, you should use LinearLayout with horizontal orientation instead.
The structure should be simple
Just need to add your buttons in 3 different linear layout with orientation horizontal.
Like
<Relative layout>{
<LinearLayout global container with vertical orientation >{
<LinearLayout for 'a' type buttons container with horizontal orientation>
<LinearLayout for 'b' type buttons container with horizontal orientation>
<LinearLayout for 'c' type buttons container with horizontal orientation>
}
}
You guys are right. It is much easier using a LinearLayout. For those interested
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_bttn_words);
final LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
button_test.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
LinearLayout linearLayout2 = new LinearLayout(view.getContext());
linearLayout2.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams rlp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
int size = enter_txt.getText().toString().length();
for (int i=0; i<size; i++)
{
Button myButton = new Button(view.getContext());
myButton.setBackgroundResource(R.drawable.button);
linearLayout2.addView(myButton, rlp);
}
linearLayout.addView(linearLayout2, llp);

Dynamically creating views

I want to create a function that takes in an array of text and creates buttons and adds them to the view.
This is my code.
It is working and creating the buttons but when i call the function twice it doesn't create two linear layouts it just shows the last one called as if it is deleting the first one.
How can i make it to create a new linear layout and add it to the View?
// Create a view
protected boolean CreateTheButtons(String[] names)
{
try
{
LinearLayout linLayout = new LinearLayout(this);
linLayout.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams linLayoutParam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// set LinearLayout as a root element of the screen
linLayout.setWeightSum(names.length);
setContentView(linLayout, linLayoutParam);
LayoutParams lpView = new LayoutParams(0, LayoutParams.WRAP_CONTENT);
lpView.weight = 1;
for (int i = 0; i < names.length; i++) {
Button btn = new Button(this);
btn.setText(names[i]);
linLayout.addView(btn, lpView);
}
return true;
}
catch(Exception ex)
{
return false;
}
}
It is working and creating the buttons but when i call the function
twice it doesn't create two linear layouts it just shows the last one
called as if it is deleting the first one.
Your code removes the first LinearLayout resulted from calling the method because you use setContentView()(which will replace the current view of the activity(if any is found) with the view that you pass as a parameter). Instead you should remove the call to setContentView() and insert a holder ViewGroup for the LinearLayouts that you plan to add through that method.
<!-- This will be the content view of the activity -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/parent" />
Set the layout above as the content view for the activity, in the onCreate() method:
setContentView(R.layout.the_layout_above);
In the method you'll then have:
protected boolean CreateTheButtons(String[] names) {
try {
LinearLayout linLayout = new LinearLayout(this);
linLayout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams linLayoutParam = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
linLayout.setWeightSum(names.length);
// assuming this method is in an Activity
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
parent.addView(linLayout, linLayoutParam);
LayoutParams lpView = new LayoutParams(0, LayoutParams.WRAP_CONTENT);
lpView.weight = 1;
for (int i = 0; i < names.length; i++) {
Button btn = new Button(this);
btn.setText(names[i]);
linLayout.addView(btn, lpView);
}
return true;
} catch(Exception ex) {
return false;
}
}

Categories

Resources