Edit: as Blumer pointed out, I was not adding the items to the table, so that this question appeared just because I was careless and I didn't see my mistake.
I am trying to create a dynamic TableLayout, as I have to receive results from the server and add rows based on the results, but the table is not updating. (Also, the TableLayout already has 1 initial row, the header row).
This is my code:
Room[] rooms = State.rooms;
TableLayout tblBookDetails = (TableLayout) findViewById(R.id.tblbookdetails);
for(int i = 0; i < rooms.length; i++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
LayoutParams layout_wrapwrap = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout_wrapwrap.rightMargin = 10; //TODO: Convert into DP
Resources res = getResources();
TextView txt1 = new TextView(this);
txt1.setLayoutParams(layout_wrapwrap);
txt1.setTextColor(res.getColor(android.R.color.black));
txt1.setText(rooms[i].name);
TextView txt2 = new TextView(this);
txt2.setLayoutParams(layout_wrapwrap);
txt2.setTextColor(getResources().getColor(android.R.color.black));
txt2.setText(rooms[i].price + " " + rooms[i].currency);
EditText edit1 = new EditText(this);
edit1.setLayoutParams(layout_wrapwrap);
//Must use deprecated method, since support library does not provide for this.
edit1.setBackgroundDrawable(res.getDrawable(android.R.drawable.edit_text));
edit1.setEms(3);
edit1.setInputType(InputType.TYPE_CLASS_NUMBER);
EditText edit2 = new EditText(this);
edit2.setLayoutParams(layout_wrapwrap);
//Must use deprecated method, since support library does not provide for this.
edit2.setBackgroundDrawable(res.getDrawable(android.R.drawable.edit_text));
edit2.setEms(3);
edit2.setInputType(InputType.TYPE_CLASS_NUMBER);
Spinner spinner = new Spinner(this);
layout_wrapwrap.rightMargin = 0;
spinner.setLayoutParams(layout_wrapwrap);
Integer[] numbers = new Integer[rooms[i].count];
for(int j = 0; j < numbers.length; j++) {
numbers[j] = i + 1;
}
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(
BookActivity.this, R.layout.spinner_textview, numbers);
spinner.setAdapter(adapter);
tblBookDetails.addView(tr);
}
//Another exquisite beauty of Java.
Log.d("USR", Integer.valueOf(tblBookDetails.getChildCount()).toString());
tblBookDetails.invalidate();
tblBookDetails.refreshDrawableState();
To prevent any confusion, the Room[] array is just a simple property-holder class.
This code looks enormously convoluted, and the table is not updating. I've searched quite a bit on the Internet, and I could not find any solution for this problem.
Thank you in advance.
I see where you add tr to tblBookDetails, but I don't see anywhere where you put txt1, txt2, edit1, etc. in tr. Try adding those views to the row, and I think that should get you there, because right now you appear to be adding the TableRow, but there's nothing in it.
Related
My android app requires me to create some LinearLayouts according to data i got through the run time, so i don't know it's number and I have to put it into a for loop to create it, and as a result the name assigned to the layouts or the elements inside it will be overridden with each iterate through the for loop, and that's my code:
List<LinearLayout> inner_ver = new ArrayList<LinearLayout>();
for(int i = 0 ; i < size_from_run_time ; i++){
LinearLayout temp_inner_ver = new LinearLayout(this);
temp_inner_ver.setLayoutParams(temp_lay);
temp_inner_ver.setOrientation(LinearLayout.VERTICAL);
temp_inner_ver.setWeightSum(2);
temp_inner_ver.setPadding(7, 7, 7, 7);
inner_ver.add(temp_inner_ver);
}
for(int j = 0 ; j < inner_ver.size() ; j++){
LinearLayout icon1 = new LinearLayout(this);
inner_ver.get(j).addView(icon1);
icon1.setLayoutParams(lp_icon);
icon1.setBackgroundResource(R.drawable.ac_overlay);
icon1.setOrientation(LinearLayout.HORIZONTAL);
icon1.setTag(NORMAL);
// icon1
TextView text1 = new TextView(this);
icon1.addView(text1);
text1.setLayoutParams(text_name);
text1.setText("something");
text1.setTextSize(12);
text1.setTextColor(Color.WHITE);
ImageButton rgp1 = new ImageButton(this);
icon1.addView(rgp1);
rgp1.setLayoutParams(lp_ineer_ver);
rgp1.setImageResource(R.drawable.grp);
rgp1.setBackgroundColor(Color.TRANSPARENT);
Button rgp_value1 = new Button(this);
icon1.addView(rgp_value1);
rgp_value1.setLayoutParams(lp_ineer_ver);
rgp_value1.setText("something");
rgp_value1.setTextSize(12);
rgp_value1.setBackgroundColor(Color.TRANSPARENT);
rgp_value1.setTextColor(Color.WHITE);
ImageButton cool1 = new ImageButton(this);
icon1.addView(cool1);
cool1.setLayoutParams(lp_ineer_ver);
cool1.setImageResource(Color.TRANSPARENT);
cool1.setBackgroundColor(Color.TRANSPARENT);
TextView cool_value1 = new TextView(this);
icon1.addView(cool_value1);
cool_value1.setLayoutParams(text_cool);
cool_value1.setText("something");
cool_value1.setTextSize(12);
ver_rooms.addView(inner_ver.get(j)); // ver_rooms is a LinearLayout defined through the xml
}
So, what if i want to add an OnClickListener for the created items (e.g rgb1, rgb_value1, cool1), as I may have like 10 of inner_ver and all of them for sure contains all of these elements with the same name.
You would probably create an array or ArrayList of 10 inner_ver.Here I have assumed, innerVerList is an Array that holds List of LinearLayout.
for (LinearLayout l: list){
for(int i=0; i<l.getChildCount(); ++i){
l.getChildAt(i).addOnClickListner(/*name of onClick listener here*/ );
}
}
But I still don't get when will you need so many LinearLayouts. Though I hope it helps!
Happy coding!
I am making a word game in which each a user has multiple guesses, each one made up of multiple TextViews. So far my code reads:
TextView[] guess1 = new TextView[numTextViews];
guess1[0] = (TextView) findViewById(R.id.Guess1_1);
guess1[1] = (TextView) findViewById(R.id.Guess1_2);
guess1[2] = (TextView) findViewById(R.id.Guess1_3);
guess1[3] = (TextView) findViewById(R.id.Guess1_4);
guess1[4] = (TextView) findViewById(R.id.Guess1_5);
with the xml looking like:
<TextView
android:id="#+id/Guess1_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:gravity="center"
android:text="#string/guessChar" />...
which repeats with android:id= changing.
I am going to be repeating myself if I type out TextView[] guess2 and all its elements.
What is a better way to go about this?
Would it be better to create all the TextViews programmatically as they are so similar?
This is how you can iterate through your views without the use of ids in repetitive code:
LinearLayout ll = (LinearLayout) findViewById(R.id.layout_containing_textviews);
for (int i = 0; i < ll.getChildCount(); i++) {
if (ll.getChildAt(i).getClass() == TextView.class) {
guess1[i] = (TextView)ll.getChildAt(i);
}
}
Make sure to tweak this in case you have non-TextView views since the i index will not be consecutive in that case. You can use another counter just for the TextViews.
Now if your layout has only TextViews, you don't even need an array. You can use that layout as a container/array the way it's used in the snipped above.
Do you know what is the amount of guesses for each text view?
I would suggest you to use reflection
Class clazz = R.id.class; // get the R class
Field f = clazz.getField("Guess1_" + "1");
int id = f.getInt(null); // pass in null, since field is a static field.
TextView currcell = (TextView) findViewById(id);
in this case it will bring the Guess1_1
for you case:
for (int i =0; i < numTextViews; i++)
{
Class clazz = R.id.class;
Field f = clazz.getField("Guess1_" + Integer.toString(i+1));
int id = f.getInt(null);
guess[i] = (TextView)findViewById(id);
}
but this only bring you the first array of Guess1 you need to convert it to generic code..
so some problems can be occur.. so read it with the xml as you have right now would be the easiest way..
Edit:
If the all textView have the same attributes you can also create it programmatically
LinearLayout view = new LinearLayout(this); // create new linear layout
view.setOrientation(LinearLayout.HORIZONTAL); // optional.. so the
// view will be horizontaly
view.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)); // set the layout
// height and width
for (int i = 0; i < numOf ; i ++)
{
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
guess[i] = new TextView();
guess[i].setLayoutParams(lp);
guess[i].setID(i+1);
}
You could either create the textViews programmatically (and use inflate if you wish to use some xml too), or you could use the getIdentifier method , for example:
private static final String ID_FORMAT="Guess1_%d";
...
for(int i=0;i<10;++i)
{
String id=String.format(FORMAT,i);
TextView tv = (TextView) findViewById(getResources().getIdentifier(id, "id", getPackageName()));
//...
}
same goes if you wish to do a loop within a loop.
If the layout has a lot of views, I would suggest using an adapterView (listView,gridView,...) instead, and avoid creation of so many views (either programmatically or by xml).
Well i made an activity where i am creating some TextViews based on the size of a string array! But despite the fact that my string array has 4 items on it, which i tested it with debugging, the textviews that are created is only 1. If anyone has an idea about it please tell me :)
setContentView(R.layout.program);
String[] daily_lessons = getResources().getStringArray(R.array.firstGradeLessons);
final TextView[] tv = new TextView[daily_lessons.length];
final LinearLayout layout = (LinearLayout) findViewById(R.id.linear1);
fasa = (TextView) findViewById(R.id.textView1);
fasa.setText(String.valueOf(daily_lessons.length));
for (int i=0; i<daily_lessons.length; i++){
tv[i] = new TextView(this);
tv[i].setText(daily_lessons[i]);
tv[i].setTextSize(20);
tv[i].setLayoutParams(new LinearLayout.LayoutParams((int)LayoutParams.FILL_PARENT,(int) LayoutParams.WRAP_CONTENT));
tv[i].setGravity(Gravity.CENTER);
layout.addView(tv[i]);
}
If you still need an answer to this question here is what I would do.
setContentView(R.layout.program);
String[] daily_lessons = getResources().getStringArray(R.array.firstGradeLessons);
LinearLayout layout = (LinearLayout) findViewById(R.id.linear1);
fasa = (TextView) findViewById(R.id.textView1);
fasa.setText(String.valueOf(daily_lessons.length));
TextView tmpView = null;
for (int i=0; i<daily_lessons.length; i++){
tmpView = new TextView(this);
tmpView.setText(daily_lessons[i]);
tmpView.setTextSize(20);
layout.addView(tmpView , new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
}
I use this type of code alot for my dynamically genenerated content (obtain content from prepopulated database).
The TextView seems to be created but might now be visible on the GUI may be stacked over each other etc.
1.Use the layout.setOrientation(ORIENTAIION.VERTICAL) on the parent linear layout's.
2.Use the childCount() on layout to make it sure on the fact that the all 4 text views have been added to the snippet.
3.Also make sure your are not using removeALLView() etc methods for your case study to the problem case.
I'm still new in android programming, what I'm trying to do is, I want to create 5x5 dimension TableLayout. I know this can be done by using GridView BaseAdapter suing Inflate service. But for this one i try to apply using table layout. Below is the code. I create new instance of TableLayout, and new instance of Table row. On each table row, I created instance of 5 TextView. But once I open in emulator or in my phone, there is no TableRow created, it just empty blank Table Layout. Also there is no exception was thrown.
GridView navIcon = (GridView) findViewById(R.id.content);
navIcon.setAdapter(new ImageAdapter(this));
navIcon.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View v, int position,long id) {
// TODO Auto-generated method stub
if (position==0){
try{
TableLayout calgrid = (TableLayout) findViewById(R.id.gridtable);
Context ctxt = v.getContext();
TextView[] tView = new TextView[25];
calgrid = new TableLayout(ctxt);
int dip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,(float) 1, getResources().getDisplayMetrics());
int counter=1;
TableRow[] tr = new TableRow[5];
for(int j=0;j<5;j++){
tr[j] = new TableRow(ctxt);
for(int i=0;i<5;i++){
tView[i] = new TextView(ctxt);
tView[i].setText(String.valueOf(counter));
tView[i].setTextSize(15);
counter+=1;
tView[i].setWidth(50 * dip);
tView[i].setPadding(20*dip, 0, 0, 0);
tView[i].setTextColor(Color.rgb( 100, 200, 200));
Toast.makeText(getApplicationContext(), "tView["+i+"] value " + String.valueOf(tView[i].getText()), Toast.LENGTH_SHORT).show();
tr[j].addView(tView[i], 50, 50);
}
calgrid.addView(tr[j]);
}
}catch(Exception e){
Log.e("MainActivity", "Error in activity", e);
Toast.makeText(getApplicationContext(),e.getClass().getName() + " " + e.getMessage(),Toast.LENGTH_LONG).show();
}
}
}
});
First of all, it is a mistake to do calgrid = (TableLayout) findViewById(R.id.gridtable); and then calgrid = new TableLayout(ctxt);, which basically says find this view now assign this variable to something completely different. Remove the second statement and it will load the table from xml which is what you want.
Second, I think it would be a good idea to simplify things for yourself because there is a lot going on here. Instead of doing all this work inside an onClick listener, do it in the onCreate method itself. Also, you seem to be using the Context from the GridView, which seems odd. Perhaps if you posted your xml layout file it could help explain what you are trying to do?
There is also a problem with indices in the array of TextViews, as tView[i] will only assign items up to 5 but the array contains 25 items. Try using tView[(j*5)+i] instead. I don't think this is causing your problems but just make sure you are assigning your items correctly.
Here is an example of how to do something along the lines of what you want
setContentView(R.layout.grid);
TableLayout tl = (TableLayout) findViewById(R.id.gridtable);
for (int j = 0; j < 5; j++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
for (int i = 0; i < 5; i++) {
TextView tView = new TextView(this);
tView.setText("TEXT" + String.valueOf((j * 5) + i + 1));
tView.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tr.addView(tView);
}
tl.addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
and grid.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridtable"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</TableLayout>
Once you get it working in the activity itself you can try to put it inside a listener attached to a GridView. Hope this helps!
I have multiple dynamic editTextBox. I want to know how can I store all its edit textbox value?
what should I write in all edit box that should be I want a store on button click event.
My code is below:
for(i = 0 ;i < 6; i++) {
TableRow tr = new TableRow(this);
TableRow tr1 = new TableRow(this);
TextView tv1 = new TextView(this);
editText1 = new EditText(this);
editText1.setWidth(300);
tr.addView(tv1);
tbl.addView(tr);
tr1.addView(editText1);
tbl.addView(tr1);
}
Here is the code.
EditText[] editText1 = new EditText[6];
for(i = 0 ;i < 6; i++) {
TableRow tr = new TableRow(this);
TableRow tr1 = new TableRow(this);
TextView tv1 = new TextView(this);
editText1[i] = new EditText(this);
editText1[i].setWidth(300);
tr.addView(tv1);
tbl.addView(tr);
tr1.addView(editText1[i]);
tbl.addView(tr1);
}
public void onClick(View v)
{
for(int i=0;i<6;i++)
{
Log.i("----value of EditText:"+i,"."+editText1[i].getText().toString());
}
}
A direct answer to your question would be:
remember your textviews when you create them (add them to an ArrayList for example)
the onPause() method of your activity is the place to retain any information you want available later (android framework can finish() your activity anytime when it's paused).
in an overrided onPause() method, cycle through your ArrayList<TextView>, retrieve each TextView content and store them for later use. (If you have a fixed number of TextViews, you may consider using SharedPreferences, but take a look at the remainder of this article to see if something better suits your needs.
You can then use onCreate() or onResume() method to repopulate your TextViews before your application shows up.
An indirect, possibly better, answer would be to separate data from UI by using a data management class that would handle saving restoring and modifying your data and a customized Adapter which would be responsible of filling the TextViews. This way you can easily change the later to address different widgets.
I wrote these codes without using editor, check it before using
String sValues="";
for (int i = 0; i < tbl.getChildCount(); i++) {
TableRow row = (TableRow)tbl.getChildAt(i);
for (int j = 0; j < row.getChildCount(); j++) {
if(row.getChildAt(j) instanceof EditText){
EditText editText1 = (EditText)row.getChildAt(j);
sValues += editText1.getText().toString();
}
}
}