I am trying to create a textview and a button programmatically in the existing relative layout. The idea is to put the textview in the left corner of the parentView(relativeLayout) and add then the button to the right of the textView. But in the app it looks like they are on the one place. The button is in front of textView, not on the right. Please, give me some advice.
the code:
TextView textView = new TextView(getActivity().getApplicationContext());
textView.setText("...");
textView.setTextColor(Color.GRAY);
int id = 0;
textView.setId(id);
final RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.setMargins(16, 16, 0, 0);
textView.setLayoutParams(params);
notificationContentLayout.addView(textView, params);
Button customerButton = new Button(getActivity().getApplicationContext());
customerButton.setText("...");
customerButton.setTextColor(Color.parseColor("#00b3ff"));
customerButton.setBackgroundColor(Color.TRANSPARENT);
id = id + 1;
customerButton.setId(id);
final RelativeLayout.LayoutParams paramsForButton =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsForButton.addRule(RelativeLayout.RIGHT_OF, textView.getId());
paramsForButton.addRule(RelativeLayout.ALIGN_PARENT_TOP); // with or without that rule everything is the same
// paramsForButton.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
paramsForButton.setMargins(10,0, 16, 0);
customerButton.setLayoutParams(paramsForButton);
notificationContentLayout.addView(customerButton, paramsForButton);
For RelativeLayout.LayoutParams rules, 0 means false, and only applies to rules that don't refer to sibling Views, such as CENTER_IN_PARENT. Since you've set your TextView's ID to 0, the RIGHT_OF rule you're adding is being ignored, as false doesn't make sense with that.
To remedy this, simply set the TextView's ID to any positive int value; e.g., 1.
Related
I have an onClickListener in which I try to add two views dynamically to an existing ViewGroup. I simply want to add one to the right of the other, but no matter what I do, they're rendered right on top of each other, with their left edges aligned. Other aspects of the layout are obeyed. For example I can specify a width as MATCH_PARENT and the View is rendered as such. Also, I'm mimicking programmatically how I specified a layout for a different ViewGroup in XML, and the XML-specified layout works properly. Here is my code:
Editable nodeName = nodeSelectView.getText();
View insertPoint = findViewById(R.id.insertionPoint);
//the two views to be added dynamically
EditText nodeView = new EditText(ManageDomainsActivity.this);
Button nodeButton = new Button(ManageDomainsActivity.this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
lp.addRule(RelativeLayout.LEFT_OF, nodeButton.getId());
nodeView.setLayoutParams(lp);
nodeView.setGravity(Gravity.LEFT);
nodeView.setText(nodeName.toString());
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
lp.addRule(RelativeLayout.RIGHT_OF, nodeView.getId());
lp.addRule(RelativeLayout.ALIGN_BASELINE, nodeView.getId());
lp.addRule(RelativeLayout.ALIGN_BOTTOM, nodeView.getId());
nodeButton.setLayoutParams(lp);
nodeButton.setText("Kill");
nodeButton.setGravity(Gravity.CENTER);
((ViewGroup) insertPoint).addView(nodeView, 0,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
((ViewGroup) insertPoint).addView(nodeButton, 1,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
You need to set the ID's of the views you're creating programatically since using getId() on a view without an id returns a NO_ID constant which doesn't work in RelativeLayout rules. Programatically created views do not need globally unique IDs (only unique in the viewgroup) so you can just set them as 1, 2, 3, ... etc
The problem was that the LayoutParameters I was passing in addView() were overriding the ones I had set on the respective views. It also failed because of a circular dependency, since the two views were defined to the right and left of each other, respectively. This doesn't seem circular to me, and it works fine in the XML that way, but it threw an exception in the dynamic layout assignment. Here's the code that works:
Editable nodeName = nodeSelectView.getText();
View insertPoint = findViewById(R.id.insertionPoint);
EditText nodeView = new EditText(ManageDomainsActivity.this);
nodeView.setId(1);
Button nodeButton = new Button(ManageDomainsActivity.this);
nodeButton.setId(2);
RelativeLayout.LayoutParams lpView = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lpView.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
nodeView.setLayoutParams(lpView);
nodeView.setGravity(Gravity.LEFT);
nodeView.setText(nodeName.toString());
RelativeLayout.LayoutParams lpButton = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lpButton.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
lpButton.addRule(RelativeLayout.RIGHT_OF, nodeView.getId());
lpButton.addRule(RelativeLayout.ALIGN_BASELINE, nodeView.getId());
lpButton.addRule(RelativeLayout.ALIGN_BOTTOM, nodeView.getId());
nodeButton.setLayoutParams(lpButton);
nodeButton.setText("Kill");
nodeButton.setGravity(Gravity.CENTER);
((ViewGroup) insertPoint).addView(nodeView, lpView);
((ViewGroup) insertPoint).addView(nodeButton, lpButton);
this is my code, but dont know why its returning null? however i can put a null check here, but is there anything wrong?
TextView descriptiontv = (TextView) findViewById(R.id.descriptiontv);
TextView tc = new TextView(c);
final PopupWindow windowPopUp = new PopupWindow(tc,LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT ,false);
tc.setBackgroundResource(R.drawable.bg_training_baloon_hc_2x);
tc.setText("this is a demo test to check how it looks, i m just wanting to test whether it works or not");
tc.setPadding(20, 20, 20, 20);
LinearLayout.LayoutParams params = new android.widget.LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.setMargins(30, 0, 30, 0);
tc.setLayoutParams(params);
Based on my experience, you have to add the view to its parent view first before you can set the layout parameters for it, like so:
TextView calendarYear = new TextView(getActivity());
calendarYear.setText(calendar.getYear() + "");
calendarYear.setTextSize(20);
calendarYear.setTypeface(null, Typeface.BOLD);
calendarYear.setGravity(Gravity.CENTER);
calendarYear.setTextColor(resources.getColor(android.R.color.black));
calendarItemsLinearLayout.addView(calendarYear);
// We have to add the TextView to the layout first before we
// can set the layout margins for it
ViewGroup.LayoutParams layoutParams = calendarYear.getLayoutParams();
((LinearLayout.LayoutParams)layoutParams).setMargins(0, (int)(16 * density), 0, 0);
calendarYear.setLayoutParams(layoutParams);
Here
tc.getLayoutParams()
you haven't given it any params yet so it will return null. Maybe you meant
descriptiontv.getLayoutParams()
Edit
Try changing
params.leftMargin = 30;
params.rightMargin = 30;
to
params.setMargins(30, 0, 30, 0);
And change
LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams)tc.getLayoutParams();
to
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
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...
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).
I need do design programatically one activity with 6 buttons (same size h and w), and all buttons show a fullsize of activity.
I tried do this: RelativeLayout with buttons and modify for tests.
Show one button!!!
`
setContentView(R.layout.main);
ArrayList<Button> buttons = new ArrayList<Button>();
//RelativeLayout bg = (RelativeLayout) findViewById(R.layout.main);
for (int i = 0; i < 10; i++) {
Button newButton = new Button(this);
newButton.setId(100 + i + 1); // ID of zero will not work
newButton.setText("XXXX");
buttons.add(newButton);
// New layout params for each button
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (i > 0) {
// using getId() here in case you change how you assign IDs
int id = buttons.get(i - 1).getId();
lp.addRule(RelativeLayout.RIGHT_OF, id);
}
this.addContentView(newButton, lp);
}`
please look this line if ok: this.addContentView(newButton, lp);
Thanks!!!
mateus
It's a bit not clear from your question whether you want all buttons to distribute evenly across the activity space or each button to take over all activity space?
In first case what you need is a LinearLayout with layout_weight for buttons set to 1.
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.weight = 1;
In the second case I think it's better to use a FrameLayout and just let buttons take over all space by setting
FrameLayout.LayoutParams.FILL_PARENT
to both dimensions.