Create a dynamic grid like view in android - android

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.

Related

Applying LayoutParams hides the View

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);

method returning Layout or View

The app I am trying to make, has got a lot of similar LinearLayouts and textViews that need to be created programmatically and placed on the screen in a specific order.
So I decided to define a method which returns one element, and for the furthur uses,I will put the method in some loop to produce the others. but when I create a view or layout this way, nothing shows up or sometimes the app crashes, as if it's been sent null to addView(). It only works when I create the View/Layout in onCreate() and then I use it right there afterwards.So , any ideas that I can use the method to creat my Layout/View? Because they are too many and it's not possible to create them one by one in onCreate()
Here's the method:
public LinearLayout createLinearLayout(){
TextView tv_day = new TextView(this);
tv_day.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
tv_day.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
tv_day.setGravity(Gravity.END);
tv_day.setText("27");
LinearLayout ll_horizontal = new LinearLayout(getBaseContext());
LinearLayout.LayoutParams ll_horizontal_params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
ll_horizontal.setLayoutParams(ll_horizontal_params);
ll_horizontal.setOrientation(LinearLayout.HORIZONTAL);
ll_horizontal.addView(tv_day);
return ll_horizontal;
}
and this is onCreate() which doesn't add any linear layouts with a textView in it :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_month_view);
LinearLayout ll= createLinearLayout();
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_month_view);
mainLayout.addView(ll);
}
I think this should help
- add an empty linear layout in XML with some id.
- reference that layout in code
- add elements to that layout dynamically
Hey was just checking your code. Its working perfectly now just try this method.
public LinearLayout createLinearLayout(){
TextView tv_day = new TextView(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tv_day.setLayoutParams(layoutParams);
tv_day.setGravity(Gravity.CENTER);
tv_day.setText("27");
LinearLayout ll_horizontal = new LinearLayout(getBaseContext());
LinearLayout.LayoutParams ll_horizontal_params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
ll_horizontal.setLayoutParams(ll_horizontal_params);
ll_horizontal.setOrientation(LinearLayout.HORIZONTAL);
ll_horizontal.addView(tv_day);
return ll_horizontal;
}

Defining a Linear Layout progmatically

I am trying to dynamically create a linear layout with a dynamic number of buttons based on certain parameters. So far I have some code that compiles but when it runs it does not display anything.
public void displayMenu()
{
LinearLayout lin = new LinearLayout(CategoryMenu.this);
lin.setOrientation(LinearLayout.VERTICAL);
lin.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
ArrayList<Button> btnList= new ArrayList<Button>();
//Test Button
Button btn1= new Button(this);
btn1.setText("Dylan");
lin.addView(btn1);
for (int i =0 ; i < 5; i++){
btnList.add(new Button(this));
btnList.get(i).setText("Hello:"+i);
lin.addView(btnList.get(i));
Log.i("CategoryMenu","Adding btn to view");
}
}
What am i doing incorrectly? I'm sure that i'm missing some thing silly here.
you have to add lin to the current hierarchy of view, or creating a new one calling setContentView(lin);
It seems that you're not adding that linear layout to a viewgroup parent.
After all your code you should add something like
myParentViewGroup.add(lin);
Before lin.addView(btn1);
You should define layoutparams for Button like:
// Defining the layout parameters of the Button
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
// Setting the parameters on the Button
tv.setLayoutParams(lp);
You have to add lin too the layout.
At present you have just created a Linearlayout, but you have not attached it to any layout.
LinearLayout lin = new LinearLayout(CategoryMenu.this);
lin.setOrientation(LinearLayout.VERTICAL);
lin.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
ArrayList<Button> btnList= new ArrayList<Button>();

Put Items in RelativeLayout dynamically

I have done some research, but the answer i found does not work for me. Here is some part of my code. the R.id.relative is the id of the relativelayout in the xml file
RelativeLayout RL = (RelativeLayout) findViewById(R.id.relative);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView title = new TextView(this);
title.setText(" History ");
title.setId(99099);
title.setTextSize(30);
title.setGravity(Gravity.CENTER);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
title.setLayoutParams(params);
RL.addView(title);
RelativeLayout.LayoutParams test_params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
Button test = new Button(this);
test.setText(" Back ");
test_params.addRule(RelativeLayout.BELOW,99099);
test.setId(199291);
test.setGravity(Gravity.CENTER);
test.setLayoutParams(test_params);
RL.addView(test);
RelativeLayout.LayoutParams test_params2 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
Button test2 = new Button(this);
test2.setText(" Clear ");
test_params2.addRule(RelativeLayout.BELOW,test.getId());
test2.setGravity(Gravity.CENTER);
test.setLayoutParams(test_params2);
RL.addView(test2);
all 3 items did show up, but they stack together. I can't get them below another.
Could anyone help ?
From what I've been able to find out, you have to add the view using LayoutParams. Here's an example:
LinearLayout linearLayout = new LinearLayout(this);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
parentView.addView(linearLayout, relativeParams);
And to relatively position your items programmatically you have to assign ids to them, this stops them from 'overlapping'.
TextView tv1 = new TextView(this);
tv1.setId(1);
TextView tv2 = new TextView(this);
tv2.setId(2);
Then addRule(RelativeLayout.RIGHT_OF, tv1.getId());
Change test.setLayoutParams(test_params2); to test2.setLayoutParams(test_params2);
Explanation: You have inadvertently set the layout params of test a second time, with params that instruct it to be below itself, which I guess just puts it top-left (default placement in a RelativeLayout). Since you never give test2 any layout params, it also gets default placement. So everything is at the top and thus appear atop each other.
Incidentally, if you just want them arranged linearly, why not use a vertical LinearLayout?
The rule you have added is causing your view to be stacked together.If you need to add it should be used by the following rule.
test_params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1);
Next, add the view to your RelativeLayout with your LayoutParams:
RL.addView(yourAdView, rLParams);
same goes for the each cases.try to run.It will solve your problem

Create TableLayout programmatically

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));

Categories

Resources