android TextView arrays - android

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).

Related

How to assign an OnClickListener for elements created through the run time?

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!

Android: adding multiple Views programmatically

I want to add a LinearLayout wrapped around a TextView and Button programmatically. I want it to take a String array and then using the length of the string array, add that many TextViews each with their own button.
So first:
String [] s = { .... the values ....}
int sL = s.length;
TextView t1 = new TextView (this);
// then somehow create t2, t3... etc. matching the length of the String array.
Is this the best way to do this or is there another way to do this? For some context, it's a quiz app and I've created a list of categories inside resources as values and I'm trying to programmatically get my app to create as many TextViews as there are categories then set each TextView to each category then get each button to take the user to that category of questions.
You are starting it right, just do a for loop and add textviews to your linearlayout.
// You linearlayout in which you want your textview
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mylayout);
linearLayout.setBackgroundColor(Color.TRANSPARENT);
String [] s = { .... the values ....}
int sL = s.length;
TextView textView = null;
// For later use if you'd like
ArrayList<TextView> tViews = new ArrayList<TextView>();
for (int i = 0; i < sL; i++)
{
textView = new TextView(this);
textView.setText(s[i]);
linearLayout.addView(textView);
tViews.add(textView);
}
There is nothing wrong with this way of doing it. If you want to use these textview later on (set text for them or something) store them in an Array of some kind. Edited code
You can do the following:
for(int i=0;i<s.length;i++){
TextView t=new TextView(this);
t.setText(s[i]);
yourLinearLayout.addView(t);
}
But I really think that using a ListView would be better for performance ;)

Dynamically Update TableLayout

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.

TextView & StringArray misfunction

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.

Unable to select children (textview) of tableRow programmatically

I'm trying to print the value of the TextViews which are inside TableRows, using TableLayout#getChildAt(i).getChildAt(j).
When I try to log it using the above, logcat complains, saying that it's a View object and that it doesn't have the method I'm trying to use (getText()).
The only Views in the TableRows are TextViews.
// List<TextView> textViewBoxes...
private void createViews() {
...
tblLayout = new TableLayout(this);
tblRow01 = new TableRow(this);
...
for (int i = 0; i < 99; i++) {
TextView text = new TextView(this);
text.setText("Player " + i);
textViewBoxes.add(text);
}
tblRow01.addView(textViewBoxes.get(0));
...
tblLayout.addView(tblRow01);
...
// Print the contents of the first row's first TextView
Log.d(TAG, ("row1_tv1: " +
tblLayout.getChildAt(0).getChildAt(0).getText().toString));
...
}
Have you tried something like this?
TableRow row = (TableRow)tblLayout.getChildAt(0);
TextView textView = (TextView)row.getChildAt(XXX);
// blah blah textView.getText();
You can also do it in one line, but it sometimes looks ugly:
// wtf?
((TextView)((TableRow)tblLayout.getChildAt(0)).getChildAt(XXX)).getText();
Anyway... what you are doing here is casting the View to the specific type you want. You can do that without problems, since you are completely sure that each TableLayout's child is a TableRow, and you know that TableRow's children on XXX position is a TextView.

Categories

Resources