Android - Views are not aligned correctly - android

Here is my code :
rl=(RelativeLayout)findViewById(R.id.ScoreLayout);
rtb=new RatingBar(this);
rl.addView(rtb);
rtb.setNumStars(5);
rtb_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
rtb_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
rtb_params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rtb.setLayoutParams(rtb_params);
txt1=new TextView(this);
rl.addView(txt1);
txt1.setSingleLine();
txt1.setTextSize(TypedValue.COMPLEX_UNIT_PX,15);
txt1.setText("Best Score: ");
txt1_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
txt1_params.addRule(RelativeLayout.ALIGN_TOP, rtb.getId());
txt1_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
txt1.setLayoutParams(txt1_params);
txt2=new TextView(this);
rl.addView(txt2);
txt2.setSingleLine();
txt2.setTextSize(TypedValue.COMPLEX_UNIT_PX,30);
txt2.setText(String.valueOf(DataBase.HighScore));
txt2_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
txt2_params.addRule(RelativeLayout.ALIGN_TOP, txt1.getId());
txt2_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
txt2.setLayoutParams(txt1_params);
txt3=new TextView(this);
rl.addView(txt3);
txt3.setSingleLine();
txt3.setTextSize(TypedValue.COMPLEX_UNIT_PX,15);
txt2.setText("Current Score: ");
txt3_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
txt3_params.addRule(RelativeLayout.ALIGN_TOP, txt2.getId());
txt3_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
txt3.setLayoutParams(txt1_params);
txt4=new TextView(this);
rl.addView(txt4);
txt4.setSingleLine();
txt4.setTextSize(TypedValue.COMPLEX_UNIT_PX,30);
txt4.setText(String.valueOf(DataBase.score));
txt4_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
txt4_params.addRule(RelativeLayout.ALIGN_TOP, txt3.getId());
txt4_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
txt4.setLayoutParams(txt1_params);
btn1=new Button(this);
rl.addView(btn1);
btn1_params=new RelativeLayout.LayoutParams(150,40);
btn1_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
btn1_params.topMargin=DataBase.Layout_Height-80-80;//first 80 for the advertisment Bar and second for the two 40-height-buttons
btn1.setLayoutParams(btn1_params);
btn2=new Button(this);
rl.addView(btn2);
btn2_params=new RelativeLayout.LayoutParams(150,40);
btn2_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
btn2_params.addRule(RelativeLayout.ALIGN_TOP, btn1.getId());
btn2.setLayoutParams(btn2_params);
and while these views should be centered horizontally and tactical they appear like that :
http://postimg.org/image/peqhzw0uh/
I want each view to be under another view and all views should be horizontally in the center ! RatingBar(rtb) should be in the top and under that should be
txt1-->txt2-->txt3-->txt4-->btn1-->btn2
I have spent to much time quering this issue and i cant find the answer why this is happening
thank you for your help :)

You need to setId() some identifiers to your views so that the ALIGN_TOP, view.getId() rules actually do something.
Though ALIGN_TOP only aligns the top of the view, making the views draw on top of each other. Use LAYOUT_BELOW rule or a LinearLayout instead.
For a view id, any integer > 0 will do. Just make sure the id's are distinct so the RelativeLayout can find the correct views you're referring to.
For Android Studio's "Expected resource of type Id" error, use #IdRes annotation to annotate your integers as resource identifiers. For example,
#android.support.annotation.IdRes int id = 1;
view.setId(id); // no error
id++; // next id
view2.setId(id); // and so on
... though in this case a LinearLayout would avoid the need of generating ids in the first place.

Since you are using RelativeLayout use txt1_params.addRule(RelativeLayout.BELOW, rtb.getId()); This should do the trick..
Sample Code for txt1 below rtb
txt1_params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
txt1_params.addRule(RelativeLayout.BELOW, rtb.getId());
txt1_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
txt1.setLayoutParams(txt1_params);
You can use the same code for rest of the views.
Assign id via code (programmatically)
Manually set ids using someView.setId(int);
The int must be positive, but is otherwise arbitrary- it can be whatever you want (keep reading if this is frightful.)
For example, if creating and numbering several views representing items, you could use their item number.

Related

How to refer to a dynamically generated button?

I am trying to interact with dynamically generated buttons. I want to update text and background color for those player clicked and for those who is near by horizontal or vertical axis at the moment of a click.
What I've tried. I've found an id property of a button in XML which led me to idea that I can make a text key to refer to a programmatically generated button. But when I've tried to assign an id - IDE was expecting a number (Int), not a string. Since buttons form a square array - I decided to encode each button via 4 digit number where first 2 digits stand for a row number and other two stand for a column number. Though when I tried to use findViewById IDE told me that it was expecting a special id data type, not a number.
That's how it looks for now:
for (i in 1..size) {
for (j in 1..size){
val button = Button(this)
button.id = i*100 + j
constraintLayout.addView(button)
}
}
What idea or method could I look at?
If you created it dynamically you can save it in a variable (or an array) for later use.
val myButtons = ArrayList<Button>()
for (i in 1..size) {
for (j in 1..size){
val button = Button(this)
myButtons.add(button)
constraintLayout.addView(button)
}
}
if you have a layout with dynamically created views and you know their order you can get them with getChildAt(index).
Alternatively you can assign ids saved in xml like this.

RelativeLayout.BELOW fails to function

Basically, I've been trying to place a bunch of EditText and TextViews programmatically, all within a RelativeLayout (I have to do it programmatically because the amount of stuff is variable depending on how many "employees" the user has entered). Now, I only need ten pieces of data per "employee", so I decided to keep track of the data using id's in base 10 (ie Employee 1 gets id 0-9, Employee 2 gets id 10-19, etc.). However, every time I use LayoutParams.addRule(int,int) function and manually input my own id, it fails to pick it up. If I use the addRule(int,int) function using "R," it works. The only reason I can come up with that would explain addRule's failure to respond to the manually inputed id values is if my math (for the id-values) is wrong, but if you look at my code, the math is pretty self-explanatory. Please tell me what I'm doing wrong because this is maddening.
Here's what I have so far:
for(int i=0;i<u.getTemp().size();i++){
int index=10*i;
RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
if(i==0)
layoutParams.addRule(RelativeLayout.BELOW,R.id.start_date);
else
layoutParams.addRule(RelativeLayout.BELOW,index-1);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
TextView empName=new TextView(rl.getContext());
empName.setTextSize(26);
empName.setText(u.getTemp().get(i).getName());
empName.setId(index++);
empName.setLayoutParams(layoutParams);
rl.addView(empName);
TextView empNum=new TextView(rl.getContext());
empNum.setText("Employee Number: " + u.getTemp().get(i).getNum());
empNum.setId(index++);
RelativeLayout.LayoutParams empNumLayout=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
empNumLayout.addRule(RelativeLayout.BELOW,empNum.getId()-1);
empNumLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
empNum.setLayoutParams(empNumLayout);
rl.addView(empNum);
EditText regHours=new EditText(rl.getContext());
regHours.setHint("Regular Hours");
regHours.setId(index++);
RelativeLayout.LayoutParams regHoursLayout=new RelativeLayout.LayoutParams(300,RelativeLayout.LayoutParams.WRAP_CONTENT);
regHoursLayout.addRule(RelativeLayout.BELOW,regHours.getId()-1);
regHoursLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
regHours.setLayoutParams(regHoursLayout);
rl.addView(regHours);
}
*Notes: rl is the relativeLayout I placed in the xml file.
I recently lost the reputation to comment :) so I am posting it as an answer. You can try using Linear Layout instead of Relative Layout. If you require any further assistance let me know. I'll help you out. :)
The error was that ids have to be positive. The first TextView had an id of 0 which explains why the addRule didn't respond.

Is a programmatically created View assigned an Integer ID in R.java?

Suppose I create an EditText using the following code and add it to a programmatically created LinearLayout, will it get assigned some ID or do I need to manually assign one using setId()?
I ask this question because there is no chance of Android assigning the same id to two different views whereas if we do it ourselves, something like that might happen.
LayoutParams fparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 5.0f);
LayoutParams tvparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LayoutParams btparams = new LayoutParams(25, 25);
first.setLayoutParams(fparams);
first.setOrientation(LinearLayout.HORIZONTAL);
EditText tv = new EditText(this);
tvparams.weight = 4.97f;
tv.setLayoutParams(tvparams);
tv.setHint("Destination Address / Postcode");
Button bt = new Button(this);
bt.setBackground(getResources().getDrawable(R.drawable.minus));
bt.setTextColor(Color.parseColor("#ffffff"));
bt.setTextSize(12f);
btparams.weight = 0.03f;
bt.setLayoutParams(btparams);
first.addView(bt);
first.addView(tv);
main.addView(first);
There is a constant for views to mark them with no id View.NO_ID.
I'm not sure what you want to achieve, but new views get assigned the id View.NO_ID.
However if you want to generate IDs you can use View.generateViewId().
Edit:
Based on your comment I'm editing my answer. View.generateViewId() does not exists below API level 17, this question "how to avoid ID conflicts?" contains an answer with code to generate ids below API 17.

How to dynamically add fields in table in Android?

I need the user to enter graph coordinates. Problem is, I don't know how many. So I want to have an "Add Point" button which inserts two fields (for x and y coordinates) into a new table row for the user to add more coordinates.
Also, how do I identify these new fields when I want to get data from them? Normally, I already know the ID of the field and call them using findViewById(R.id.ID_here); Now what do I do to identify them?
I'm writing all these coordinates into a file, so if there's a way to write them without identifying each one, please help.
EDIT:
I can't get the edittext fields to have these layout parameter properties:
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="numberDecimal"
Here's my JAVA code for the same:
TableLayout table = (TableLayout) findViewById(R.id.TableLayout1);
TableRow tr = new TableRow(this);
LinearLayout.LayoutParams trparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
tr.setLayoutParams(trparams);
cg[i] = new EditText(this);
weight[i] = new EditText(this);
LinearLayout.LayoutParams fieldparams = new LinearLayout.LayoutParams(100, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
cg[i].setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
weight[i].setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
cg[i].setLayoutParams(fieldparams);
weight[i].setLayoutParams(fieldparams);
tr.addView(cg[i]);
tr.addView(weight[i]);
table.addView(tr);
Please help if you can.
You can create new rows (or any other kind of View) like this:
TableRow tr = new TableRow(myContext); // usually myContext is 'this'
you then add the tr to whatever the parent view is
TableLayout myTable = findViewById(R.id.TableLayout1);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tr.setLayoutParams(lp);
myTable.addView(tr);
You'll need to add layoutParams to the view before you add it since all Views have to, at minimum, specify their layout width and layout height.
If you need to add children to your row (obviously you will, what use is it otherwise) you just repeat the process except now you create an EditText. Once you do, you automatically have a reference to it, since you created it! :)
I'm not clear on what you mean by the last part of your question, where you're writing them to a file. Please elaborate.
Oh, and welcome to Stack... if you find answers useful, don't forget to up-vote them and/or mark them as correct.

Dynamically added rows, setOnClickListener TextView

I have a for loop that each time prints out a row with a TextView within. I want this TextView to be clickable, and when clicked it is supposed to start another activity and send an ID with the Intent. But it's this that I can't manage to work. All links shows up nicely in a table and the textviews are clickable, but all links sends me to the next activity with the same ID, the ID of the last link.
Here is a simplified version of the content of the for loop:
TextView title = new TextView(this);
title.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
title.setText(titleLine);
title.setClickable(true);
title.setId(rows);
rows++;
title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(a.this, b.class);
myIntent.putExtra("id", idLine);
a.this.startActivity(myIntent);
}
});
contRight.addView(title);
I suppose the problem is that all textViews looks the same, so the last setOnClickListener works on all links. However, I have added an ID to each title, with this code: title.setId(rows);, so they are all supposed to be unique.
Anybody who can give some help? :) Thanks!
Shouldn't idLine be v.getId()? It's good for this value to be as "fresh" as possible so that you aren't reading an old value: in this case, the value of the last row which had probably been lurking in idLine. Hence, getting the value from the view directly is the safest method.
Also, the "tag" might be a better place to store information than the id. You can access the tag, and indeed store any number of arguments as tags on any view, without changing the id:
title.setTag(rows);
and then later:
intent.putExtra((Integer) v.getTag());
To store multiple objects (with keys) you can use:
title.setTag("rowid", rows);
and then retrieve it using:
intent.putExtra((Integer) v.getTag("rowid"));
and then you could add additional keys if you requirements changed.
In any case, the intention of the tag is to store information for later retrieval, whereas the id is meant to serve as an identifier for finding views in a hierarchy.

Categories

Resources