I have an issue with ViewGroup.addView() method. I use this code to add new view to my layout:
TalbeLayout parent = (TableLayout)findViewById(R.id.this_does_not_matter);
parent.removeAllViews(); //this view group contains something at start
TextView tv = new TextView(this);
tv.setText("some text");
TableLayout.LayoutParams lp = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lp);
parent.addView(tv);
And after that I cant see my TextView. More than that, parent.getChildCount() returns correct values (1 if I try to add one child). In onClick() method of parent view I try to get width and height of TextView and all of this equals to 0. Calling requestLayout(), invalidate() and measure(500, 50) for TableView and parent has no effect. I even try to add new view with the help of view.post(Runnable), although this code is executed in UI thread.
I confused. I really don't understand what happens. Can someone explain me what I doing wrong?
One interesting moment:
setLayoutParams() has no effect. If I set params with width=500 and height=50, in onClick method I get params with width=-1 and height=-1.
Code after TableRow added:
TableLayout parent = (TalleLayout)findViewById(R.id.this_does_not_matter);
parent.removeAllViews(); //this view group contains something at start
TextView tv = new TextView(this);
tv.setText("some text");
TableLayout.LayoutParams lp = new TableLayout.LayoutParams(500, 50);
TableRow.LayoutParams tlp = new TableRow.LayoutParams(500, 50);
TableRow tr = new TableRow(this);
tr.addView(tv, tlp);
parent.addView(tr, lp);
parent.invalidate();
parent.requestLayout();
I found one more interesting thing. This Activity runs from TabHost. And "addView bug" appears only if the Activity is first selected in this TabHost. If at the first time I start Activity from another tab, all works fine.
I found solution. If switch off layout animation with android:animateLayoutChanges="false" all works fine. But I still have no idea why this happens. If anyone know reason of this behavior, it interesting for me.
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 want to add some ui elements to my android app, a Button for example!
But I can't find a complete tutorial! I found this code after a lot of searches:
LinearLayout ll = (LinearLayout)findViewById(R.id.layout);
Button btn = new Button(this);
btn.setText("Manual Add");
btn.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
ll.addView(btn);
My first problem is first line! Can you explain it for me please? What is R.id.layout? I know R is an object for resources but I don't know what is layout!
Second problem is line 3, What is LayoutParams?
Thank you all!
You can create views using default constructors for example
Button button = new Button(context);
After that you should determine to which type of parent view you are going to attach it, and create corresponding layot params. Every parent view LayoutParams type has uniqe customize methods, for example rules of RelativeLayout.LayoutParams.
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height)
//customize params here
button.setLayoutParams(params)
Attach view to your parent view
frameLayout.addView(button)
That is it.
LinearLayout ll = (LinearLayout)findViewById(R.id.layout);// you are getting a refrence to your layout
Button btn = new Button(this); // creating a new object of button type
btn.setText("Manual Add"); //setting the button text
btn.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT)); //setting the width and height of the element
ll.addView(btn);//adding the button to your layout
R.id.layout is the name of your activity layout
It is the parent view which you are going to add your views. In your example it is a LinearLayout called layout.
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
I'm trying to create a View dynamically (on click). Any person have any idea why this does not work. It just opens a blank (BLACK) screen. When i click back it moves to previous screen as well. And i need to know the way i'm trying to set the team is correct.
public class Details extends Activity {
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//setTheme(android.R.style.Theme_Dialog);
TextView label = new TextView(this);
label.setText("Hello This text");
label.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
label.setTextSize(20);
label.setGravity(Gravity.CENTER);
TableRow tr = new TableRow(this);
tr.addView(label);
TableLayout tl = new TableLayout(this);
tl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tl.setGravity(Gravity.CENTER);
tl.addView(tr);
ScrollView sv = new ScrollView(this);
sv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
sv.addView(tl);
setContentView(sv);
}
}
There is an msg in LogCat as following
couldn't save which view has focus because the focused view ##### has no id
Well one obvious thing is that you are using generic LayoutParams, not the correct parameters for the layout manager. For example you are not using a TableLayout.LayoutParams for the TextView so you are not actually telling it how to layout the text view within the table structure.
I also suggest using hierarchyviewer to look at what is going on with your view hierarchy.
Is the activity declared in the Manifest.xml?
You must to put
#Override
I had the similar problem
I want to create a relative Layout dynamically through code with 2 Textviews one below the other.How to implement android:layout_below property through code in Android.
can anyone help me in sorting out this issue.
Thanks in Advance,
final TextView upperTxt = (...)
upperTxt.setId(12345);
final TextView lowerTxt = (...);
final RelativeLayout.LayoutParams params = RelativeLayout.LayoutParams(this, null);
params.addRule(RelativeLayout.BELOW, 12345);
lowerTxt.setLayoutParams(params);
Here is my solution for my special Problem.
In case the username wouldn't be found in the db i had to create a RelativeLayout that looks like the xml-generated one.
// text view appears on top of the edit text
enterNameRequest = new TextView(mainActivity.getApplicationContext());
// fill the view with a string from strings.xml
enterNameRequest.setText(mainActivity.getResources().getString(R.string.enterNameRequest));
// edit text appears below text view and above button
enterName = new EditText(mainActivity.getApplicationContext());
enterName.setId(667);
// button appears at the bottom of the relative layout
saveUserName = new Button(mainActivity.getApplicationContext());
saveUserName.setText(mainActivity.getResources().getString(R.string.useUserName));
saveUserName.setId(666);
// generate the relative layout
RelativeLayout layout = new RelativeLayout(mainActivity.getApplicationContext());
layout.setId(668);
// set a background graphic by its id
layout.setBackgroundDrawable(mainActivity.getApplicationContext().getResources().getDrawable(R.drawable.background_head_neutral));
// runtime told me that i MUST use width and height parameters!
LayoutParams params2 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ABOVE, 666);
enterName.setLayoutParams(params2);
LayoutParams params3 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params3.addRule(RelativeLayout.ABOVE, 667);
enterNameRequest.setLayoutParams(params3);
LayoutParams params4 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params4.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 668);
saveUserName.setLayoutParams(params4);
// add views
layout.addView(enterNameRequest);
layout.addView(enterName);
layout.addView(saveUserName);
/* todo: set button action */
mainActivity.setContentView(layout);
What i found out additionally:
It is not so good to manipulate the layout manually from within java!
You should better use a new Activity and set a new layout in it.
This way, the application-code is readable a lot better!
I even tried to set several layouts (not manually, but wit setContentView) in one activity, and it turned out that i didn't know where what was accessing what else... Also, i had a great problem in adding onClickListeners... so you better use -- android:onClick="myButtonMethod" -- in your button tag in the xml and have a method in your according activity, which uses the layout, like this:
public void myButtonMethod(View v){
// do stuff
}
This improves performance because you are not using additional Listeners - but you use the already available Listener that is bound to your activity in every case.
u can try this
LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);``
leftMarginParams.leftMargin = 50;
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams)