I'm trying to create a TableLayout programatically. It just won't work. The same layout in an xml file works though. This is what I have:
public class MyTable extends TableLayout
{
public MyTable(Context context) {
super(context);
setLayoutParams(new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
TableRow row = new TableRow(context);
row.setLayoutParams(new TableRow.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
Button b = new Button(getContext());
b.setText("hello");
b.setLayoutParams(new LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
row.addView(b);
addView(row)
}
}
...
// In main activity:
MyTable table = new MyTable(this);
mainLayout.addView(table);
When I run this, I don't get a crash, but nothing appears. If I get rid of the TableRow instance, at least the button does appear as a direct child of the TableLayout. What am I doing wrong?
Just to make the answer more clear:
TableLayout.LayoutParams tableParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT);
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
TableLayout tableLayout = new TableLayout(context);
tableLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));// assuming the parent view is a LinearLayout
TableRow tableRow = new TableRow(context);
tableRow.setLayoutParams(tableParams);// TableLayout is the parent view
TextView textView = new TextView(context);
textView.setLayoutParams(rowParams);// TableRow is the parent view
tableRow.addView(textView);
Explanation
When you call setLayoutParams, you are supposed to pass the LayoutParams of the parent view
It turns out I needed to specify TableRowLayout, TableLayout etc for the layout params, otherwise the table just won't show!
For me, to get mine I had to call addContentView().
A good solution is to inflate layout files for each instance of row you want to create. See this post : How to duplicate Views to populate lists and tables?
Your problem is at this line:
b.setLayoutParams(new LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
You need to change LayoutParams to TableRow.LayoutParams:
b.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
Related
In the code snippet below there's one commented line. When I uncomment that line, then the contents of LinearLayout are not displayed in a TableRow. Without setting the LayoutParams, the row displays both texts. I don't understand this behavior. I know that I can include complex views via xml files, but I'd rather understand what's wrong with this code:
TableLayout tableLayout = (TableLayout) findViewById(R.id.table);
TableRow tableRow = new TableRow(this );
tableRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
// when I comment out this line, the row only shows the second text.
// linearLayout.setLayoutParams(layoutParams);
TextView textLabel = new TextView(this);
textLabel.setText("inside linear layout");
linearLayout.addView(textLabel);
TextView message = new TextView(this);
message.setText( "inside tablerow");
tableRow.addView(linearLayout);
tableRow.addView(message);
tableLayout.addView(tableRow);
Assuming the question is something like "What's the issue of this? How to resolve this?", here's my answer:
When you are setting LayoutParams to a View, those params would be used by the parent of this View to layout that View appropriately. So in your case what you have done is following:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(...);
linearLayout.setLayoutParams(layoutParams);
tableRow.addView(linearLayout);
Now, the tableRow is confused, because it expects TableRow.LayoutParams in order to layout the view appropriately, but it suddenly finds out some other layout params. Whereas, had you not explicitly specified params (i.e. when linearLayout.setLayoutParams() is commented out), the default layout params would be generated.
#Override
protected LinearLayout.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(); // this is TableRow.LayoutParams
}
So, instead of creating LinearLayout.LayoutParams, create TableRow.LayoutParams:
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(...);
linearLayout.setLayoutParams(layoutParams);
tableRow.addView(linearLayout);
I have created a fragment which should display table of buttons. I used table layout to create a table. But the button table doesn't display in the fragment. What is the problem related to this code and how can I overcome this???
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
ArrayList buttons = new ArrayList();
ScrollView sv = new ScrollView(this.getActivity());
//Set a TableLayout to add buttons
TableLayout tl= new TableLayout(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
tl.setLayoutParams(params);
tl.setOrientation(TableLayout.HORIZONTAL);
for(int i=0;i<5;i++){
TableRow row=new TableRow(this.getActivity());
LayoutParams paramrow = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
row.setLayoutParams(paramrow);
for(int j=0;j<2;j++){
Button button = new Button(getActivity());
button.setText("testing");
button.setPadding(5, 5, 5, 5);
LayoutParams parab = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
button.setLayoutParams(parab);
row.addView(button);
buttons.add(button);
}
tl.addView(row);
}
sv.addView(tl);
}
You're using the wrong type of LayoutParams in at least two places. Views need to use the type of LayoutParams that correspond to their container. Therefore Views contained directly in a TableLayout - i.e., the TableRows - should use TableLayout.LayoutParams. The Views contained in TableRows - the Buttons, in this case - should use TableRow.LayoutParams. And finally, the TableLayout is in a ScrollView, so it should use ScrollView.LayoutParams, which is actually FrameLayout.LayoutParams, since ScrollView extends FrameLayout.
It also appears that you're not adding the ScrollView to the Fragment's View anywhere. I would mention, too, that it might be preferable to define the ScrollView and the TableLayout in layout xml, inflate this layout in onCreateView(), and dynamically create only what needs to be - i.e., the TableRows and Buttons.
For creating a structure like the image in android, I tried the following code.
But showing this error. Please help
My code looks like
public void setValues(){
LinearLayout table=(LinearLayout)findViewById(R.id.mainWrap);
LinearLayout row=new LinearLayout(this);;
for(int i=0;i<5;i++){
if(i%2==0){
row= new LinearLayout(this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(lp);
}
FrameLayout layout = new FrameLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((width/2)-10,(height/2)-10);
params.setMargins(5, 5, 5, 5);
layout.setLayoutParams(params);
if(i%2==0){
layout.setBackgroundColor(Color.parseColor("#CACACA"));
}
else {
layout.setBackgroundColor(Color.parseColor("#333333"));
}
ProgressBar pr=new ProgressBar(this);
FrameLayout.LayoutParams params_p = new FrameLayout.LayoutParams((width/6),(width/6));
params_p.gravity=Gravity.CENTER;
pr.setLayoutParams(params_p);
layout.addView(pr);
ImageView im=new ImageView(this);
FrameLayout.LayoutParams params_im = new FrameLayout.LayoutParams((width/2),(width/2));
im.setImageResource(R.drawable.man);
im.setLayoutParams(params_im);
layout.addView(im);
row.addView(layout);
table.addView(row);
}
Error is
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Thanks in advance
I have a feeling the problem is here:
LinearLayout row=new LinearLayout(this);;
for(int i=0;i<5;i++){
The first time it loops row will be replaced by your second assignment of it and held in the variable OUTSIDE of the loop, the second time it is not replaced and because it is outside of the loop, it is the same row you're trying to add to the table again. Just swap the order of the lines above.
i want to add spinner dynamically inside table like this image and how to specify its width and height also :
Any help will be appreciated.
Take a TableLayout form xml and inflate the xml to your code.
Now you can add new TableRows to the tableLayout using
addView(new TableRow())...
And again u can addView(View v) to each table Row.
U can addWeight to each TableRow you add to TableLayout..In your case
TableRow weight will be 2
addView(new TextView())
addView(new Spinner())
you can add as many table rows as you want:
"TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayoutFromXML);"
"TableRow tableRow = new TableRow(this);"
"tableRow.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));"
"tableRow.addView(WhatEver view that you want);"
"tableLayout.addView(tableRow);"
view that you want add to tablerow, you can also set their attributes like "width" or "height".
I know i am bit late, but you can try this.....
final TableLayout dynamicTable = (TableLayout) findViewById(R.id.hotelTableLayout);
/* Create a new row to be added. */
final TableRow row = new TableRow(Hotels.this);
row.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT));
/* Create a component to be the row-content. */
SpnAdult = new Spinner(Hotels.this);
SpnAdult.setLayoutParams(new TableRow.LayoutParams(0,
TableRow.LayoutParams.WRAP_CONTENT, 1));
SpnAdult.setAdapter(adapter);
/* Add Spinner to row. */
row.addView(SpnAdult);
/* Add row to TableLayout. */
dynamicTable.addView(row, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
Hope this helps....
I want to add linearlayout in table row and that linear layout will hold some buttons and textview.How I can achieve that.I am using this but it does not display anything
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
final CheckBox checkbox = new CheckBox(this);
checkbox.setPadding(10, 5, 0, 0);
checkbox.setTextSize(TypedValue.COMPLEX_UNIT_PX, 15);
checkbox.setOnClickListener(new View.OnClickListener() {
TextView tv = new TextView(this);
tv.setText("Hello");
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, 14);
tv.setPadding(0, 0, 0, 0);
tv.setOnClickListener(new View.OnClickListener() {
checkbox.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
tv.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
LinearLayout linearLayout = new LinearLayout(tr.getContext());
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.addView(checkbox, new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
linearLayout.addView(tv, new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
tr.addView(linearLayout);
table.addView(tr, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Please Help me.
Try adding row params like this
TableRow row = new TableRow(this);
row.addView(linearLayout, new TableRow.LayoutParams(1));
Add relativeLayout instead of linearlayout and set params like this for textview
RelativeLayout.LayoutParams rel_lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rel_lp.addRule(RelativeLayout.BELOW);
tv.setLayoutParams(rel_lp);
For a start you need to close your curly braces at right place. While Setting onClickListener, you are not closing the curly brace and not even putting a semicolon there. So it seems you are making a textView in the listener. The following line
checkbox.setOnClickListener(new View.OnClickListener() {
should be like this
checkbox.setOnClickListener(new View.OnClickListener() {
protected void onClick(View v){
//your listener code here.
}
});
And when the layout is so complex, you should use XML files instead of Dynamically coding, unless you have to.