How to dynamically add fields in table in Android? - 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.

Related

onClickListener on PaneTemplate not allowed?

I have a simple PaneTemplate I am setting up like this:
Row row1 = new Row.Builder().setTitle("Do Thing 1").build();
Row row2 = new Row.Builder().setTitle("Do Thing 2").build();
Row row3 = new Row.Builder().setTitle("Do Thing 3").build();
Row row4 = new Row.Builder().setTitle("Do Thing 4").build();
return new PaneTemplate.Builder(new Pane.Builder().addRow(row1).addRow(row2).addRow(row3).addRow(row4).build()).setTitle("AA Hello!!").build();
and it all works fine and looks like this:
but if I add setOnClickListener to one of the rows:
Row row1 = new Row.Builder().setTitle("Do Thing 1").setOnClickListener(this::onClick).build();
I get an exception:
"a click listener is not allowed on the row"
I get an error:
I have not read about this restriction in any of the AA documentation. I tried making the onClick function anything number of things, including a blank function, and it makes no difference. Any idea what is going on here? How can I get around it? I want the press of this item to do something.
It's restricted on PaneTemplate.
Using ListTemplate for such simple list is better decision.

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.

Android - Views are not aligned correctly

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.

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 get the checkboxes dynamically in android?

In my project I need to display questions and its options. Here the options are at max 20 with multiple answers. The options are not fixed for each question. That means for each question the options may be 2 or 3 or 6 or 18 or 2o. Since the question contains multiple answers I need to create checkboxes to display options dynamically. Based on the number of options for the question we need to display the checkboxes. How can I do that? Please help me regarding this.
Thanks in Advance
You can create an empty LinearLayout and call its addView() function
to add the checkboxes dynamically in your code.
For example,
CheckBox[] cbs = new CheckBox[20]; // Number varies..
for(int i=0; i<20; i++){
cbs[i] = new CheckBox(this);
ll.addView(cb);
cbs.setText("Test");
}
Look at this turorial Android, Part III: Dynamic Layouts
EDIT:
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
CheckBox[] cbs = new CheckBox[20];
for(x=1; x<numberofoptions; x++)
{
cbs[x] = new CheckBox(getContext());
ll.addView(cbs[x]);
}

Categories

Resources